Difference: ADCAndDAC (1 vs. 10)

Revision 102021-07-05 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"

Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Introduction

Line: 87 to 87
 
META FILEATTACHMENT attachment="fit.png" attr="" comment="" date="1596180450" name="fit.png" path="fit.png" size="32457" user="UliRaich" version="1"
META FILEATTACHMENT attachment="corrected.png" attr="" comment="" date="1596181140" name="corrected.png" path="corrected.png" size="38453" user="UliRaich" version="1"
META FILEATTACHMENT attachment="openhantek.png" attr="" comment="" date="1596206560" name="openhantek.png" path="openhantek.png" size="95945" user="UliRaich" version="1"
Changed:
<
<
META FILEATTACHMENT attachment="expected.png" attr="" comment="" date="1596808397" name="expected.png" path="expected.png" size="34510" user="UliRaich" version="1"
>
>
META FILEATTACHMENT attachment="expected.png" attr="" comment="" date="1625507965" name="expected.png" path="expected.png" size="37915" user="UliRaich" version="2"
 
META FILEATTACHMENT attachment="polynomialv2.png" attr="" comment="" date="1596810306" name="polynomialv2.png" path="polynomialv2.png" size="2360" user="UliRaich" version="1"
META FILEATTACHMENT attachment="linearity.png" attr="" comment="" date="1596811295" name="linearity.png" path="linearity.png" size="35217" user="UliRaich" version="1"

Revision 92021-07-04 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"

Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Introduction

Revision 82020-08-07 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"
Changed:
<
<

Exercise 9: Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

>
>

Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

 

Introduction

The ESP32 has two 12 bit SAR (Successive Approximation Register) Analogue to Digital Converters (ADCs) and two 8 bit Digital to Analogue Converters on chip. Checking for drivers in the MicroPython manual I only find a description of the ADC. Checking the MicroPython source code however, I see that also the driver for the DACs is available.

Revision 72020-08-07 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"

Exercise 9: Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Introduction

Line: 18 to 18
 

Checking linearity

If we connect the DAC output to the input of an ADC channel and we slowly ramp up the DAC value from 0 to its maximum and we read back the signal level with the ADC, then we expect a perfectly linear curve. This is true under the condition that both, the DAC and the ADC are perfectly linear.

Changed:
<
<
linearity full range linearity restricted range
linearity.png restrictedLinearity.png
>
>
Linearity curve expected Linearity curve measured
expected.png linearity.png
 As we can see, the curve becomes very non-linear for values above 200 (3.3V * 200 / 256 ~ 2.6 V). Unfortunately we do not know if the ADC or the DAC is responsible for this non-linearity. We need an external ADC to check. We also see that the line does not pass though 0,0 as it should.

Verifying linearity with an external ADS1115

Line: 45 to 45
  Here is a graph when fitting a polynomial of grade 5
Changed:
<
<
polynomial.png
>
>
polynomialv2.png
  fit.png
Line: 81 to 81
 
<--/commentPlugin-->
Deleted:
<
<
META FILEATTACHMENT attachment="linearity.png" attr="" comment="" date="1596111249" name="linearity.png" path="linearity.png" size="32384" user="UliRaich" version="1"
 
META FILEATTACHMENT attachment="restrictedLinearity.png" attr="" comment="" date="1596111254" name="restrictedLinearity.png" path="restrictedLinearity.png" size="29920" user="UliRaich" version="1"
META FILEATTACHMENT attachment="linADS1115.png" attr="" comment="" date="1596115847" name="linADS1115.png" path="linADS1115.png" size="30931" user="UliRaich" version="1"
Changed:
<
<
META FILEATTACHMENT attachment="polynomial.png" attr="" comment="" date="1596180154" name="polynomial.png" path="polynomial.png" size="3560" user="UliRaich" version="1"
>
>
META FILEATTACHMENT attachment="polynomial.png" attr="" comment="" date="1596810201" name="polynomial.png" path="polynomial.png" size="2360" user="UliRaich" version="2"
 
META FILEATTACHMENT attachment="fit.png" attr="" comment="" date="1596180450" name="fit.png" path="fit.png" size="32457" user="UliRaich" version="1"
META FILEATTACHMENT attachment="corrected.png" attr="" comment="" date="1596181140" name="corrected.png" path="corrected.png" size="38453" user="UliRaich" version="1"
META FILEATTACHMENT attachment="openhantek.png" attr="" comment="" date="1596206560" name="openhantek.png" path="openhantek.png" size="95945" user="UliRaich" version="1"
Added:
>
>
META FILEATTACHMENT attachment="expected.png" attr="" comment="" date="1596808397" name="expected.png" path="expected.png" size="34510" user="UliRaich" version="1"
META FILEATTACHMENT attachment="polynomialv2.png" attr="" comment="" date="1596810306" name="polynomialv2.png" path="polynomialv2.png" size="2360" user="UliRaich" version="1"
META FILEATTACHMENT attachment="linearity.png" attr="" comment="" date="1596811295" name="linearity.png" path="linearity.png" size="35217" user="UliRaich" version="1"

Revision 62020-08-01 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"

Exercise 9: Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Introduction

Line: 10 to 10
 

The DAC

The DACs are accessible on pins 25 and 26. Since there is no description in the manual, here is the way how to access the DAC:

Added:
>
>


 
Changed:
<
<
  from machine import Pin,DAC
from time import sleep_ms

dac = DAC(Pin(26))
print("Running a triangular wave form with a frequency of ~ 1 Hz on pin 26")
while True:
    for i in range(256):
        dac.write(i)
        sleep_ms(2)
    for i in range(256):
        dac.write(256-i-1)
        sleep_ms(2)
   
>
>
from machine import Pin,DAC
from time import sleep_ms

dac = DAC(Pin(26))
print("Running a triangular wave form with a frequency of ~ 1 Hz on pin 26")
while True:
    for i in range(256):
        dac.write(i)
        sleep_ms(2)
    for i in range(256):
        dac.write(256-i-1)
        sleep_ms(2)
   
  This will generate a slow triangular wave form that can be observed on a multi-meter.

Checking linearity

Line: 48 to 49
  fit.png
Changed:
<
<
The fit gives up the coefficients (a..e) of the polynomial and we can use this to correct for linearity. Instead of returning the raw ADC value we enter it into the polynomial and return the calculated value multiplied by 16 to get 0..4096 instead of 0..256.
>
>
The fit returns the coefficients (a..e) of the polynomial and we can use this to correct for linearity. Instead of returning the raw ADC value we enter it into the polynomial and return the calculated value multiplied by 16 to get 0..4096 instead of 0..256.
  Here is the DAC versus ADC measurement on the ESP32 ADC after correction:

Revision 52020-07-31 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"

Exercise 9: Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Introduction

Line: 52 to 53
 Here is the DAC versus ADC measurement on the ESP32 ADC after correction:

corrected.png

Added:
>
>

A pulse generator on the DAC

In order to bring up the pulse generator on the DAC we will need an oscilloscope to observe the signals. In out toolbox we have a small number of Hantek6022 scopes for which driver software is available. I tried to bring up the scope staring from the source at https://github.com/OpenHantek/OpenHantek6022.

Making the Hantek6022 oscilloscope work

In order to build OpenHantek from source you will needed to install a few additional packages:

  • qttool5-dev for Qt5Linguist
  • libusb-1.0.0-dev
  • libfftw3-dev
Once you clone the software from the repository create the build directory:cd OpenHantek

mkdir build cd build cmake ..

This will create the Makefile for you. All that is left is making the project.

Finally you must allow user USB access to the Oscilloscope by copying 60-hantek.rules which you find in the utils/udev_rules directory to /etc/udev/rules.d. Unplug and re-plug your Hantek scope (Use the black USB connector).

After compilation you will find the OpenHantek binary in build/openhantek.

openhantek.png

  -- Uli Raich - 2020-07-26
Line: 65 to 85
 
META FILEATTACHMENT attachment="polynomial.png" attr="" comment="" date="1596180154" name="polynomial.png" path="polynomial.png" size="3560" user="UliRaich" version="1"
META FILEATTACHMENT attachment="fit.png" attr="" comment="" date="1596180450" name="fit.png" path="fit.png" size="32457" user="UliRaich" version="1"
META FILEATTACHMENT attachment="corrected.png" attr="" comment="" date="1596181140" name="corrected.png" path="corrected.png" size="38453" user="UliRaich" version="1"
Added:
>
>
META FILEATTACHMENT attachment="openhantek.png" attr="" comment="" date="1596206560" name="openhantek.png" path="openhantek.png" size="95945" user="UliRaich" version="1"

Revision 42020-07-31 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"

Exercise 9: Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Introduction

Line: 16 to 16
 

Checking linearity

If we connect the DAC output to the input of an ADC channel and we slowly ramp up the DAC value from 0 to its maximum and we read back the signal level with the ADC, then we expect a perfectly linear curve. This is true under the condition that both, the DAC and the ADC are perfectly linear.

Changed:
<
<
linearity full range linearity restricted range
>
>
linearity full range linearity restricted range
 
linearity.png restrictedLinearity.png
As we can see, the curve becomes very non-linear for values above 200 (3.3V * 200 / 256 ~ 2.6 V). Unfortunately we do not know if the ADC or the DAC is responsible for this non-linearity. We need an external ADC to check. We also see that the line does not pass though 0,0 as it should.

Verifying linearity with an external ADS1115

Line: 28 to 28
 
SCL D1: GPIO 22 D1: GPIO 5
SDA D2: GPIO 21 D2: GPIO 4
A0 DAC 2: GPIO 26  
Changed:
<
<
A driver MicroPython driver for the ADS1115 is available making it very easy to use: https://github.com/robert-hh/ads1x15

I modified the above program checking linearity, replacing ADC readout by access to the ADS1115 instead of the ESP32 internal ADC. This is the result:

>
>
A driver MicroPython driver for the ADS1115 is available making it very easy to perform the check: https://github.com/robert-hh/ads1x15. I copied the driver to /lib on the ESP32 using ampy and modified my ADC vs DAC program to use the ADS1115 instead of the ESP32 ADC. This is the result:
  linADS1115.png
Added:
>
>
Note the change in scale on the y axis. The ADS1115 is a 16 bit ADC while the ESP32 has only 12 bits. The maximum value on the y axis depends on the input voltage range selected.
 This clearly shows that the ESP32 ADC is the culprit!
Added:
>
>

Correcting the non-linearity

Now that we know that the DAC is nicely linear and it is the ADC introducing the non-linearity we can try to correct for it using our first DAC vs ADC measurement as calibration curve. If we can calculate the DAC value from the ADC output we can also calculate the corrected ADC value.

For this to work we must invert (replace x by y and vice versa) the function adc = y = f(x) where x is the DAC value. This is the function of the first plot. Then we fit a polynomial to the inverted curve and finally we use this polynomial to correct the values read from the ADC.

Here is a graph when fitting a polynomial of grade 5

polynomial.png

fit.png

The fit gives up the coefficients (a..e) of the polynomial and we can use this to correct for linearity. Instead of returning the raw ADC value we enter it into the polynomial and return the calculated value multiplied by 16 to get 0..4096 instead of 0..256.

Here is the DAC versus ADC measurement on the ESP32 ADC after correction:

corrected.png

  -- Uli Raich - 2020-07-26
Line: 45 to 62
 
META FILEATTACHMENT attachment="linearity.png" attr="" comment="" date="1596111249" name="linearity.png" path="linearity.png" size="32384" user="UliRaich" version="1"
META FILEATTACHMENT attachment="restrictedLinearity.png" attr="" comment="" date="1596111254" name="restrictedLinearity.png" path="restrictedLinearity.png" size="29920" user="UliRaich" version="1"
META FILEATTACHMENT attachment="linADS1115.png" attr="" comment="" date="1596115847" name="linADS1115.png" path="linADS1115.png" size="30931" user="UliRaich" version="1"
Added:
>
>
META FILEATTACHMENT attachment="polynomial.png" attr="" comment="" date="1596180154" name="polynomial.png" path="polynomial.png" size="3560" user="UliRaich" version="1"
META FILEATTACHMENT attachment="fit.png" attr="" comment="" date="1596180450" name="fit.png" path="fit.png" size="32457" user="UliRaich" version="1"
META FILEATTACHMENT attachment="corrected.png" attr="" comment="" date="1596181140" name="corrected.png" path="corrected.png" size="38453" user="UliRaich" version="1"

Revision 32020-07-30 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"

Exercise 9: Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Introduction

Line: 15 to 15
 This will generate a slow triangular wave form that can be observed on a multi-meter.

Checking linearity

Changed:
<
<
If we connect the DAC output to the input of an ADC channel and we slowly ramp up the DAC value from 0 to its maximum and we read back the signal level with an ADC, then we expect a perfectly linear curve. This is true under the condition that both, the DAC and the ADC are perfectly linear.
>
>
If we connect the DAC output to the input of an ADC channel and we slowly ramp up the DAC value from 0 to its maximum and we read back the signal level with the ADC, then we expect a perfectly linear curve. This is true under the condition that both, the DAC and the ADC are perfectly linear.
 
linearity full range linearity restricted range
linearity.png restrictedLinearity.png
As we can see, the curve becomes very non-linear for values above 200 (3.3V * 200 / 256 ~ 2.6 V). Unfortunately we do not know if the ADC or the DAC is responsible for this non-linearity. We need an external ADC to check. We also see that the line does not pass though 0,0 as it should.
Added:
>
>

Verifying linearity with an external ADS1115

The ADS1115 is a high precision 16 bit Sigma/Delta ADC with an I2C interface. It can easily be connected to the WeMos D1 bus as follows:

ADS 1115 WeMos D1 bus and ESP32 WeMos D1 bus and ESP8266
Vdd 3.3V 3.3V
Gnd Gnd Gnd
SCL D1: GPIO 22 D1: GPIO 5
SDA D2: GPIO 21 D2: GPIO 4
A0 DAC 2: GPIO 26  
A driver MicroPython driver for the ADS1115 is available making it very easy to use: https://github.com/robert-hh/ads1x15

I modified the above program checking linearity, replacing ADC readout by access to the ADS1115 instead of the ESP32 internal ADC. This is the result:

linADS1115.png

This clearly shows that the ESP32 ADC is the culprit!

  -- Uli Raich - 2020-07-26
Line: 28 to 44
 
META FILEATTACHMENT attachment="linearity.png" attr="" comment="" date="1596111249" name="linearity.png" path="linearity.png" size="32384" user="UliRaich" version="1"
META FILEATTACHMENT attachment="restrictedLinearity.png" attr="" comment="" date="1596111254" name="restrictedLinearity.png" path="restrictedLinearity.png" size="29920" user="UliRaich" version="1"
Added:
>
>
META FILEATTACHMENT attachment="linADS1115.png" attr="" comment="" date="1596115847" name="linADS1115.png" path="linADS1115.png" size="30931" user="UliRaich" version="1"

Revision 22020-07-30 - UliRaich

Line: 1 to 1
 
META TOPICPARENT name="Exercises"

Exercise 9: Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Added:
>
>

Introduction

 
Changed:
<
<
Article text.
>
>
The ESP32 has two 12 bit SAR (Successive Approximation Register) Analogue to Digital Converters (ADCs) and two 8 bit Digital to Analogue Converters on chip. Checking for drivers in the MicroPython manual I only find a description of the ADC. Checking the MicroPython source code however, I see that also the driver for the DACs is available.

The ADC

ADC 2 is used for WiFi and therefore not accessible to us. ADC 1 however has multiplexed input and 8 ADC channels are available for use (on Pins 32-39). The ADC has a range 0..1V but attenuators are available. If we set the attenuation to 11 DB we get a voltage range of approximately 0 .. 3.6 V. Pin 36 and pin 26 are available on the WeMos D1 bus but pins on the ESP32 CPU card can also be used (e.g. pin 33, 34, 35).

The DAC

The DACs are accessible on pins 25 and 26. Since there is no description in the manual, here is the way how to access the DAC:   from machine import Pin,DAC
from time import sleep_ms

dac = DAC(Pin(26))
print("Running a triangular wave form with a frequency of ~ 1 Hz on pin 26")
while True:
    for i in range(256):
        dac.write(i)
        sleep_ms(2)
    for i in range(256):
        dac.write(256-i-1)
        sleep_ms(2)
   

This will generate a slow triangular wave form that can be observed on a multi-meter.

Checking linearity

If we connect the DAC output to the input of an ADC channel and we slowly ramp up the DAC value from 0 to its maximum and we read back the signal level with an ADC, then we expect a perfectly linear curve. This is true under the condition that both, the DAC and the ADC are perfectly linear.

linearity full range linearity restricted range
linearity.png restrictedLinearity.png
As we can see, the curve becomes very non-linear for values above 200 (3.3V * 200 / 256 ~ 2.6 V). Unfortunately we do not know if the ADC or the DAC is responsible for this non-linearity. We need an external ADC to check. We also see that the line does not pass though 0,0 as it should.
  -- Uli Raich - 2020-07-26

Comments

<--/commentPlugin-->
\ No newline at end of file
Added:
>
>
META FILEATTACHMENT attachment="linearity.png" attr="" comment="" date="1596111249" name="linearity.png" path="linearity.png" size="32384" user="UliRaich" version="1"
META FILEATTACHMENT attachment="restrictedLinearity.png" attr="" comment="" date="1596111254" name="restrictedLinearity.png" path="restrictedLinearity.png" size="29920" user="UliRaich" version="1"

Revision 12020-07-26 - UliRaich

Line: 1 to 1
Added:
>
>
META TOPICPARENT name="Exercises"

Exercise 9: Analogue to Digital (ADC) and Digital to Analogue (DAC) conversion

Article text.

-- Uli Raich - 2020-07-26

Comments

<--/commentPlugin-->
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback