Ignorer et passer au contenu

Livraison offerte à partir de 50€

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

Générer des tensions variables grâce au PWM de la Pi Pico en MicroPython

Le PWM, une astuce pour générer des tensions variables sur des broches numériques

Le PWM est une technique qui permet de générer une tension comprise entre 0 et 3.3V en utilisant uniquement des sorties numériques . PWM est l’acronyme de Pulse With Modulation , en français c’est appelé MLI pour Modulation de Largeur d’Impulsion . En effet, cette astuce repose sur la proportion temporelle d’un signal logique à son état haut (3.3V) et à son état bas (0V) : le PWM consiste à faire varier la largeur d’une impulsion électrique.

Note

Le PWM permet de générer des tensions constantes dont on peut faire varier la valeur. Il ne génère pas des tensions alternatives comme pourrait le faire un DAC.

fonctionnement pwm micropython

Principe du PWM

La succession d’impulsion avec une largeur donnée est vue en moyenne comme une tension constante comprise entre 0V et 3.3V dont sa valeur est déterminée par :

\[V_{sortie} = V_{entree} \times \alpha\]

avec α la largeur d’impulsion ( duty cycle en anglais)

Un signal PWM se configure via la largeur d’impulsion et la fréquence de l’impulsion. On pourra modifier ces 2 paramètres en MicroPython.

En pratique, le PWM est utilisé pour :

  • Contrôler la vitesse d’un moteur

  • Contrôler la luminosité de LED

  • Générer des signaux carrés (avec α=0.5)

  • Générer des notes de musiques (son similaire à celui des consoles rétro)

Performance du PWM sur la Raspberry Pi Pico

Les signaux PWM sont non pas générés en permanence par le microprocesseur mais par des blocs matériels dédiés. Il suffit ainsi de configurer une seule fois les blocs PWM dans le script pour que le signal soit généré en permanence en tâche de fond. On associe une sortie d’un bloc PWM à une broche de notre carte. Les ressources du processeur seront alors libres pour exécuter d’autres tâches.

Chaque bloc PWM peut avoir une fréquence indépendante.

Caractéristiques du PWM de la

Pi Pico

Plage de fréquence du signal PWM

7 Hz à 125 Mhz

Fréquence PWM indépendante

8

Sortie PWM

16

Résolution de la largeur d’impulsion

16 bits

Note

En pratique, dans la majorité des cas, une fréquence PWM autour de 1000 Hz sera suffisante.

Le PWM sur MicroPython avec la Pico

L’utilisation du PWM avec MicroPython est très simple. MicroPython se charge de sélectionner automatiquement un bloc PWM disponible : il n’est pas nécessaire d’indiquer celui que l’on compte utiliser. La partie hardware décrite au-dessus est complètement masquée.

La configuration consiste à associer un objet PWM à un objet Pin et de choisir la fréquence PWM.

from machine import Pin, PWM

pin = Pin(25, mode=Pin.OUT)
pin_with_pwm = PWM(pin) # Attach PWM object on a pin

Note

Puisque l’objet PWM est aussi dans le module machine, on peut réunir les 2 imports sur une seule ligne :

from machine import Pin
from machine import PWM

est équivalent à

from machine import Pin, PWM

Une fois que la broche de la carte est liée à notre objet PWM, toutes les fonctions se font directement sur l’objet PWM (Contrairement au code Arduino ou l’on doit préciser le numéro de pin avec la fonction analogWrite(pin_number) .

Note

En python, on peut insérer des underscores _ pour rendre les nombres plus faciles à lire (et ainsi éviter de compter les zéros sur des grands nombres). Par exemple, pour écrire 1 MHz , au lieu d’avoir 1000000 on peut mettre 1_000_000 .

On utilise la fonction .duty_u16() pour choisir la largeur d’impulsion avec une valeur comprise entre 0 et \(2^{16}-1\) (0-65535). La tension est imposée directement en sortie du pin sélectionné précédemment.

Avertissement

Pour ceux qui ont déjà fait du MicroPython sur l’ESP32, vous remarquerez que u_16 à été rajouté au nom de la fonction. Il précise que la fonction attend en entrée une valeur jusqu’à 16 bits (et non pas jusqu’à 10 bits sur l’ESP32 avec la fonction .duty() ).

Pour se rendre compte de la variation de la tension, on peut utiliser la LED intégrée de votre carte avec le script suivant :

from machine import Pin, PWM

LED_BUITLTIN = 25 # For Raspberry Pi Pico

pwm_led = PWM(Pin(LED_BUITLTIN, mode=Pin.OUT)) # Attach PWM object on the LED pin

# Settings
pwm_led.freq(1_000)

while True:
    for duty in range(0,65_536):
        pwm_led.duty_u16(duty) # For Pi Pico

Avertissement

La fonction range(0, 65_536) compte entre 0 et 65 535 : le dernier élément est exclu.

Pour que ce soit plus parlant, on peut simplement préciser juste le pourcentage du duty cycle puis appliquer une formule.

from machine import Pin, PWM

LED_BUITLTIN = 25 # For Raspberry Pi Pico

pwm_led = PWM(Pin(LED_BUITLTIN, mode=Pin.OUT)) # Attach PWM object on the LED pin
pwm_led.freq(1_000)

duty_cycle = 50 # Between 0 - 100 %
pwm_led.duty_u16(int((duty_cycle/100)*65_535))

On peut faire varier la luminosité de la LED en faisant varier entre 0 et 100% la largeur d’impulsion.

from machine import Pin, PWM
import time

LED_BUITLTIN = 25 # For Raspberry Pi Pico

pwm_led = PWM(Pin(LED_BUITLTIN, mode=Pin.OUT)) # Attach PWM object on the LED pin
pwm_led.freq(1_000)

while True:
    for duty in range(101): # Duty from 0 to 100 %
        pwm_led.duty_u16(int((duty/100)*65_535))
        time.sleep_ms(10)

Mini-Projet : Faire dimmer la LED intégrée de sa Raspberry Pi Pico

Avec tout ce que l’on a vu, le script est très facile à faire :

from machine import Pin, PWM

LED_BUITLTIN = 25 # For Raspberry Pi Pico

pwm_led = PWM(Pin(LED_BUITLTIN, mode=Pin.OUT)) # Attach PWM object on the LED pin

# Settings
pwm_led.freq(1_000)

while True:
    for duty in range(0,65_536, 5):
        pwm_led.duty_u16(duty)
    for duty in range(65_536,0, -5):
        pwm_led.duty_u16(duty)

Note

Afin que la tension varie plus vite, on fait varier le duty de 5 en 5 avec range(0, 65_536, 5) . Pour décrémenter une valeur, on met un pas de -5 : range(65_536, 0, -5) .

Nous utilisons des cookies pour que votre visite sur la boutique soit la plus agréable possible. Politique de confidentialité