3.13. Générer un signal analogique avec une PWM et un filtre RC¶
L’ADC lit des tensions sur une broche. L’opération inverse (produire une tension intermédiaire entre 0 V et Vcc sur une broche) est plus difficile, car une sortie GPIO ne sait piloter que ses deux rails. Le substitut classique consiste à commuter la broche entre les rails suffisamment vite pour que la tension moyenne soit celle qui vous intéresse.
3.13.1. Modulation de largeur d’impulsion¶
Un signal à modulation de largeur d’impulsion (PWM) est une onde carrée à fréquence fixe dont le temps à l’état haut (la fraction de chaque cycle passée à Vcc plutôt qu’à la masse) est fixé par logiciel. Cette fraction est le rapport cyclique. La tension moyenne de la forme d’onde est le rapport cyclique multiplié par Vcc :
V_avg = duty × Vcc
Un rapport cyclique de 25 % donne une moyenne de Vcc / 4 ; un rapport cyclique de 50 % donne Vcc / 2 ; un rapport cyclique de 75 % donne 3 × Vcc / 4.
PWM à 25 %, 50 % et 75 % de rapport cyclique. La tension moyenne suit le rapport cyclique.¶
La fréquence est fixée lors de la configuration de la PWM ; le rapport cyclique est ce que le logiciel modifie à la volée. La classe machine.PWM encapsule un canal de minuteur matériel qui génère la forme d’onde sans intervention du processeur : une fois configuré, le signal se poursuit à la fréquence et au rapport cyclique choisis jusqu’à modification.
3.13.2. La classe machine.PWM¶
Construisez une instance de PWM avec la broche ainsi qu’une fréquence et un rapport cyclique initiaux :
from machine import PWM, Pin
pwm = PWM(Pin("P7"), freq=20_000, duty_u16=32768)
Cela démarre une onde carrée à 20 kHz avec un rapport cyclique de 50 % sur P7. Deux méthodes modifient la sortie à la volée :
pwm.duty_u16(16384) # change to 25 % (16384 / 65535)
pwm.freq(5_000) # change to 5 kHz
duty_u16() prend un entier non signé sur 16 bits où 0 correspond à « toujours bas » et 65535 à « toujours haut ». freq() règle la fréquence porteuse en hertz.
Note
Tous les canaux PWM rattachés au même minuteur matériel partagent sa fréquence. Appeler freq() sur un canal modifie tous les autres canaux rattachés à ce minuteur. Utilisez des canaux de minuteurs différents lorsque les sorties doivent fonctionner à des fréquences différentes.
Appelez deinit() pour libérer le canal du minuteur lorsque la sortie n’est plus nécessaire.
3.13.3. Moyennage avec un filtre passe-bas RC¶
Une PWM brute n’est pas une tension lisse ; c’est une onde carrée dont la moyenne est ce que nous voulons. Pour extraire cette moyenne, faites passer la PWM à travers un filtre passe-bas : la même combinaison de résistance et de condensateur utilisée pour l’anti-rebond des interrupteurs dans Anti-rebond.
Une PWM à travers un filtre passe-bas RC : le condensateur moyenne l’onde carrée en une tension continue proportionnelle au rapport cyclique.¶
La fréquence de coupure du filtre (la limite entre les fréquences qu’il laisse passer et celles qu’il bloque) est déterminée par le même produit RC qui donnait la constante de temps du circuit anti-rebond :
f_c = 1 / (2π × R × C)
Pour que le filtre extraie une tension continue propre à partir d’une entrée PWM, la fréquence de coupure doit être bien inférieure à la fréquence de la PWM elle-même. La composante continue (fréquence 0) passe inchangée ; l’harmonique fondamentale de la PWM (à la fréquence de la PWM) est atténuée d’environ f_c / f_PWM. Un rapport de 1 / 200 réduit l’ondulation résiduelle en sortie à environ 0.5 % de l’amplitude d’entrée.
Un point de départ raisonnable pour une consigne à variation lente :
Fréquence PWM
f_PWM = 20 kHz: bien au-dessus de l’audio, et facile à générer proprement par le minuteur.Valeurs du filtre
R = 1.6 kΩ,C = 1 µF: donnantf_c = 1 / (2π × 1.6 kΩ × 1 µF) ≈ 100 Hz.
La suppression de 200× à la porteuse réduit la pleine amplitude de la PWM à environ Vcc / 200 d’ondulation résiduelle à V_out : soit environ 16 mV à 3,3 V.
Deux remarques pratiques :
L’impédance de sortie du filtre vaut environ
R. Toute charge en aval qui tire du courant transformeRet la charge en un diviseur qui tireV_outen dessous de la moyenne idéale, exactement comme le diviseur de la page Lecture de signaux analogiques avec l’ADC. Alimentez une broche d’ADC ou un tampon à haute impédance, pas une charge qui absorbe des milliampères.Le condensateur met environ
5 × R × C ≈ 8 msà se stabiliser lorsque le rapport cyclique change ;V_outaccuse ce retard par rapport au réglage du rapport cyclique. Pour une consigne qui doit se mettre à jour plus vite, augmentez la fréquence de coupure (RouCplus petits) et acceptez davantage d’ondulation.