Mesurer une tension analogique avec l’ADC en MicroPython

Sur l’ESP32 et la Raspberry Pi Pico 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 la Raspberry Pi Pico, les broches 26,27 et 28 peuvent être utilisées comme une entrée analogique. La résolution des valeurs mesurées est sur 16 bits, les valeurs sont donc comprises entre 0 et 65535.

Note

Sur la carte uPesy RP2040 DevKit, il existe une entrée analogique supplémentaire sur la broche 29.

Indication

Il existe une entrée analogique « cachée » dans le microcontrôleur RP2040 qui permet de mesurer directement la température de la puce. C’est un peu équivalent aux mesures de températures des CPU des ordinateurs. Il ne faut pas l’utiliser pour connaitre la température de la pièce. Cette entrée correspond au canal ADC_4 .

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 la Pico et 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 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(26, mode=Pin.IN)
adc = ADC(adc_pin)

Il ne faut pas oublier n’importer le sous-module ADC.

Pour l’ESP32, il faut en plus spécifier une atténuation de 11 dB (avec ADC.ATTN_11DB ) pour lire une tension sur toute la plage de 0 à 3.3V.

from machine import Pin, ADC

# Pin definitions
adc_pin = Pin(26, mode=Pin.IN)
adc = ADC(adc_pin)
adc.atten(ADC.ATTN_11DB)

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_u16() sur la Raspberry Pi Pico et read() sur ESP32.

from machine import Pin, ADC
adc = ADC(Pin(26, mode=Pin.IN))
print(adc.read_u16())

Il faudra faire un produit en croix pour avoir la valeur mesurée en volt :

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

Mesurer la température interne de la Raspberry Pi Pico :

La Raspberry Pi Pico possède un capteur de température interne pour mesurer la température de la puce RP2040. Bien que pas très fiable, il permet d’avoir un aperçu de la température du CPU (comme sur les ordinateurs). Ce capteur est directement relié à l’entrée ADC_4 de l’ADC.

capteur interne température pi pico via le can

Le capteur interne de température est positioné sur la dernière broche de l’ADC

Pour mesurer la température, il faut :
  • Récupérer la valeur analogique brute du capteur de température disponible sur le canal 4 de l’ADC

  • Convertir cette valeur en tension

  • Utiliser une formule donnée dans la documentation du RP240 pour convertir cette tension en température (en °C)

from machine import ADC
import time

temp_sensor = ADC(4)

while True:
    adc_voltage = temp_sensor.read_u16() * 3.3 / 65535
    cpu_temp = 27 - (adc_voltage - 0.706)/0.001721 # Formula given in RP2040 Datasheet
    print(cpu_temp)
    time.sleep_ms(1_000)

Note

Vous pouvez constater le changement de température en mettant votre doigt sur la puce RP2040.

Sortie de la console REPL:

32.19402
32.19402
32.66216
31.72584
33.13027
33.59842
34.06656
34.06656
34.53474
34.06656

Mini-Projet : Contrôler l’intensité d’une LED via un potentiomètre :

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 a 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 :

from machine import Pin, ADC
import time


# Create an ADC object linked to pin 26
adc = ADC(Pin(26, mode=Pin.IN))

while True:

    # Read ADC and convert to voltage
    val = adc.read_u16()
    val = val * (3.3 / 65535)
    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

# Create a PWM object linked to pin 15
pwm_led = PWM(Pin(15,mode=Pin.OUT))
pwm_led.freq(1_000)

# Create an ADC object linked to pin 26
adc = ADC(Pin(26, mode=Pin.IN))

while True:

    val = adc.read_u16()
    pwm_led.duty_u16(val)
    time.sleep_ms(10)