ADCDAC

Page Actions

Conversion Analogique - Num\xE9rique et Num\xE9rique - Analogique

Introduction

L'ESP32 poss\xE8de deux convertisseurs analogique - num\xE9rique (Analog to Digital converter, ADC) 16 bits du type SAR (Successive Approximation Register) et deux convertisseurs num\xE9rique - analogique (Digital to Analog Converter, DAC) de 8 bits. Cherchant des pilotes dans le manuel Micropython je trouve seulement la description de l'ADC. Dans le code source de MicroPython par contre je vois qu\x92aussi le pilote pour le DAC est disponible.

L'ADC

ADC2 est utilis\xE9 pour le WiFi et pour cette raison n'est pas accessible \xE0 nous. L'ADC 1 par contre poss\xE8de une entr\xE9e multiplex\xE9e et huit canaux sont utilisables (sur les pins 32-39). L'ADC travaille dans un intervalle de 0..1V mais ils existent des att\xE9nuateurs pour \xE9tendre cette gamme. Une att\xE9nuation de 11 dB r\xE9sulte dans une gamme approximative 0..3.6V.

Le DAC

Les DAC sont accessibles sur les pins 25 et 26. Puisqu\x92il n'y a pas de descriptions dans le manuel MicroPython, voila un exemple d'acc\xE8s au DAC :

rom 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)

Ceci produira une onde triangulaire lente, qu'on peut observer avec un multim\xE8tre.

V\xE9rification de la lin\xE9arit\xE9

Si on connecte le DAC avec l'entr\xE9e d'un ADC et on monte la valeur envoy\xE9e au DAC lin\xE9airement de z\xE9ro au maximum de 255 on s'attend \xE0 une courbe de valeurs lus de l'ADC parfaitement lin\xE9aire. Ceci est vrai si aussi bien le DAC que L'ADC sont lin\xE9aire.
Courbe de lin\xE9arit\xE9 attendu Courbe de lin\xE9arit\xE9 mesur\xE9
expected.png linearity.png
Comme on voit, la courve devient tr\xE8s non-lin\xE9aire pour des valeurs d\xE9passant les valeurs DAC de 255 (3.3V * 200 / 256: ~ 2.6 V). Malheureusement nous de savont pas si l'ADC ou le DAC est responsable pour cette non-lin\xE9arit\xE9. On voit aussi que la courbe ne passe pas par 0,0 comme on pourrait s'attendre.

V\xE9rification de lin\xE9arit\xE9 avec un ADC ADS1115 externe

L'ADS1115 est un ADC haute pr\xE9cision de 16 bit du type Signa/Delta avec une interface I2C. On peut facilement le connect\xE9 sur les pins I2C SCL et SDA de la carte CPU. Les connexions pour la CPU WeMos D1 mini sont sp\xE9cifie dans le tableau ci-dessous:

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  
Un pilote existe pour l'ADS1115 facilitant le teste : https://github.com/robert-hh/ads1x15.

J'ai copi\xE9 le pilote dans /lib de l'ESP32 avec ampy et j'ai modifi\xE9 mon programme ADC vs DAC en utilisant l'ADS1115 au lieu de l'ADC de l'ESP32. Voil\xE0 le r\xE9sultat :

linADS1115.png

Notez le changement d'\xE9chelle sur l'axe y. L'ADS1115 est un ADC 16 bit tandis que l'ADC de l'ESP32 utilise 12 bits seulement. Le maximum sur l'axe y d\xE9pend de la gamme de tension d'entr\xE9e s\xE9lectionn\xE9e. Ceci d\xE9montre clairement que c'est ADC de l'ESP32 est le coupable.

Correction de la non-lin\xE9arit\xE9 par software

Puisque nous savons maintenant que le DAC est bien lin\xE9aire et que c'est l'ADC qui introduit la non-lin\xE9arit\xE9 nous pouvons utiliser notre premi\xE8re mesure DAC vs ADC comme courbe de calibration. Si nous pouvons calculer la valeur DAC \xE0 partir d'une valeur ADC nous pouvons aussi corriger la non-lin\xE9arit\xE9.

Pour accomplir ceci nous devons d'abord invertir (replacer les valeurs x par les valeurs y et vice vers) la fonction adc = y = f(x) ou x est la valeur du DAC. Ceci est la fonction du premier graphe (noir, partiellement couvert par le graphe rouge). En suite, nous pouvons calculer une approximation polynomiale \xE0 la fonction invertie (graphe rouge).

Le polyn\xF4me du grade 5 est d\xE9fini comme suit :

polynomialv2.png

fit.png

La fonction polyfit du module Python numpy est utilis\xE9 pour calculer cette approximation et elle retourne les coefficients a..f du polyn\xF4me. Le polyn\xF4me ainsi obtenu est utilis\xE9 pour calculer la valeur d'entr\xE9e corrig\xE9e. Au lieu de retourner la valeur lu de 'ADC nous entrons cette valeur dans le polyn\xF4me et nous retournons la valeur calcul\xE9e, multiplier par 16 pour adapter la gamme 0..225 a la gamme de l'ADC: 0..4095.

Voil\xE0 le graphe ADC vs DAC corrig\xE9 avec le polyn\xF4me de calibration.

corrected.png

-- %USERSIG{UliRaich - 2021-07-04}%

Comments

 
I Attachment Action Size Date Who Comment
corrected.pngpng corrected.png manage 37 K 05 Jul 2021 - 10:08 UnknownUser  
expected.pngpng expected.png manage 37 K 05 Jul 2021 - 17:58 UnknownUser  
fit.pngpng fit.png manage 31 K 05 Jul 2021 - 10:08 UnknownUser  
linADS1115.pngpng linADS1115.png manage 30 K 05 Jul 2021 - 10:11 UnknownUser  
linearity.pngpng linearity.png manage 34 K 05 Jul 2021 - 09:51 UnknownUser  
polynomialv2.pngpng polynomialv2.png manage 2 K 05 Jul 2021 - 10:28 UnknownUser  
Topic revision: r4 - 27 Nov 2021, UliRaich