Ignorer et passer au contenu

Livraison offerte à partir de 50€ d'achats, livrée sous 48h !

Livraison à partir de seulement 2.50€ !

Contents Menu Expand Light mode Dark mode Auto light/dark mode

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 :

\[V_{volt} = \frac{3.3V}{4095} \times V_{bits}\]

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 :

Schéma de câblage esp32 adc potentiomètre avec LED

Circuit électrique à réaliser

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)