Mesurer une tension analogique avec l’ADC de l’ESP32 en MicroPython
(Mis à jour le 16/11/2022)
Sur l’ESP32 certaines broches sont reliées à l’ADC intégré du microcontrôleur. Un ADC est un convertisseur analogique vers numérique : il revoit une valeur numérique proportionnelle à la tension mesurée.
Note
En français, un ADC est généralement nommé un CAN . Cependant, il existe aussi un protocole de communication largement utilisé en automobile qui s’appelle aussi CAN ( le bus CAN ). Pour éviter la confusion lors de vos recherches, je vous conseille donc de toujours utiliser les acronymes en anglais.
Caractéristiques
Sur l’ESP32, les pins 36, 39, 34 et 35 peuvent être utilisés comme entrée analogique avec MicroPython. La résolution des mesures est sur 12 bits, donc les mesures sont situées entre 0 et 4095.
Avertissement
Contrairement à l’Arduino, les entrées analogiques sur l’ESP32 ne doivent pas dépasser une tension de 3.3V. Cela pourrait abimer voire détruire les entrées de l’ADC. Il faut donc bien vérifier de ne pas utiliser une tension d’alimentation de 5V pour mesurer la valeur d’un capteur. Il existe des solutions pour limiter la tension en entrée de l’ADC.
Lire une entrée analogique de l’ESP32 avec MicroPython
On mesure la tension d’une entrée analogique à l’aide du sous-module ADC
du module machine
. Comme pour le PWM, on associe une broche physique à l’objet ADC
.
from machine import Pin, ADC
# Pin definitions
adc_pin = Pin(36, mode=Pin.IN)
adc = ADC(adc_pin)
adc.atten(ADC.ATTN_11DB)
Il ne faut pas oublier n’importer le sous-module ADC. Vous noterez qu’il faut en plus pour l’ESP32, spécifier une atténuation de 11 dB (avec ADC.ATTN_11DB
) pour lire une tension sur toute la plage de 0 à 3.3V.
On peut aussi créer un objet ADC
en spécifiant le numéro du canal analogique que l’on veut utiliser.
from machine import ADC
adc = ADC(0) # Select the ADC_0 ()
Avertissement
Sur l’ESP32, les canaux analogiques sont attribués un peu dans le désordre aux broches. C’est donc mieux d’utilisation la définition par le numéro de broche.
Une fois que l’on a configuré une entrée analogique en MicroPython, il suffit pour lire la valeur analogique d’utiliser la fonction read()
.
from machine import Pin, ADC
adc = ADC(Pin(36, mode=Pin.IN))
print(adc.read())
Il faudra faire un produit en croix pour avoir la valeur mesurée en volt :
Mini-Projet : Contrôler l’intensité d’une LED via un potentiomètre sur l’ESP32
Nous allons utiliser à la fois le PWM et l’ADC avec MicroPython pour contrôler l’intensité d’une LED externe.
Schéma électrique :

Note
Pensez à mettre une résistance en série avec la LED pour éviter qu’elle claque. (330 Ω par exemple)
Pour la lecture de la position du potar seule :
from machine import Pin, ADC
import time
# Create an ADC object linked to pin 36
adc = ADC(Pin(36, mode=Pin.IN))
while True:
# Read ADC and convert to voltage
val = adc.read()
val = val * (3.3 / 4095)
print(round(val, 2), "V") # Keep only 2 digits
# Wait a bit before taking another reading
time.sleep_ms(100)
Pour la lecture de la position du potar et la variation de la luminosité :
from machine import Pin, ADC, PWM
import time
def map(x, in_min, in_max, out_min, out_max):
""" return linear interpolation like map() fonction in Arduino"""
return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min
if __name__ == "__main__":
# Create a PWM object linked to pin 23
pwm_led = PWM(Pin(23,mode=Pin.OUT))
pwm_led.freq(1_000)
# Create an ADC object linked to pin 36
adc = ADC(Pin(36, mode=Pin.IN))
adc.atten(ADC.ATTN_11DB)
while True:
val = adc.read()
pwm_value = map(x=val, in_min=0, in_max=4095, out_min=0,out_max=1023)
pwm_led.duty(pwm_value)
time.sleep_ms(10)