3.13. Generarea semnalelor analogice cu PWM și un filtru RC

ADC-ul citește tensiunile de pe un pin. Operațiunea opusă – producerea unei tensiuni intermediare între 0 V și Vcc pe un pin – este mai dificilă, deoarece o ieșire GPIO știe doar cum să comande cele două șine ale sale. Substitutul standard este să comuți pinul între șine suficient de rapid încât tensiunea medie să fie cea care contează.

3.13.1. Modulația în lățime de impuls

Un semnal modulat în lățime de impuls (PWM) este o undă dreptunghiulară la o frecvență fixă, al cărei timp în starea înaltă – fracțiunea din fiecare ciclu petrecută la Vcc în loc de masă – este stabilit prin software. Acea fracțiune este factorul de umplere. Tensiunea medie a formei de undă este factorul de umplere înmulțit cu Vcc:

V_avg = duty × Vcc

Un factor de umplere de 25 % are media Vcc / 4; un factor de umplere de 50 % are media Vcc / 2; un factor de umplere de 75 % are media 3 × Vcc / 4.

Trei trasee de undă dreptunghiulară stivuite vertical, fiecare la aceeași frecvență. Unda de sus este înaltă timp de 25 % din fiecare perioadă și joasă timp de 75 %. Unda din mijloc este înaltă și joasă fiecare câte jumătate din perioadă. Unda de jos este înaltă timp de 75 % și joasă timp de 25 %.

PWM cu factor de umplere de 25 %, 50 % și 75 %. Tensiunea medie urmărește factorul de umplere.

Frecvența este stabilită la configurarea PWM-ului; factorul de umplere este ceea ce software-ul modifică din mers. Clasa machine.PWM încapsulează un canal de temporizator hardware care generează forma de undă fără ajutorul CPU-ului – odată configurat, semnalul continuă la frecvența și factorul de umplere alese până la modificare.

3.13.2. Clasa machine.PWM

Construiți o instanță PWM cu pinul și o frecvență și un factor de umplere inițiale:

from machine import PWM, Pin

pwm = PWM(Pin("P7"), freq=20_000, duty_u16=32768)

Aceasta pornește o undă dreptunghiulară de 20 kHz cu factor de umplere de 50 % pe P7. Două metode modifică ieșirea din mers:

pwm.duty_u16(16384)   # change to 25 % (16384 / 65535)
pwm.freq(5_000)       # change to 5 kHz

duty_u16() primește un întreg fără semn pe 16 biți, mapând 0 la „mereu jos” și 65535 la „mereu sus”. freq() setează frecvența purtătoare în hertzi.

Notă

Fiecare canal PWM de pe același temporizator hardware împarte aceeași frecvență. Apelarea freq() pe un canal modifică toate celelalte canale atașate acelui temporizator. Folosiți canale ale unor temporizatoare diferite atunci când ieșirile trebuie să funcționeze la frecvențe diferite.

Apelați deinit() pentru a elibera canalul de temporizator atunci când ieșirea nu mai este necesară.

3.13.3. Medierea cu un filtru RC trece-jos

PWM-ul brut nu este o tensiune lină; este o undă dreptunghiulară a cărei medie este ceea ce dorim. Pentru a extrage acea medie, treceți PWM-ul printr-un filtru trece-jos – aceeași combinație de rezistor și condensator folosită pentru eliminarea zgomotului de contact al comutatoarelor în Eliminarea oscilațiilor de contact (debouncing).

Un pin PWM se conectează printr-un rezistor în serie R la un nod de ieșire. Un condensator C de la acel nod la masă completează filtrul trece-jos; tensiunea netezită apare la V_out.

PWM printr-un filtru RC trece-jos: condensatorul mediază unda dreptunghiulară într-o tensiune continuă proporțională cu factorul de umplere.

Frecvența de tăiere a filtrului – granița dintre frecvențele pe care le lasă să treacă și cele pe care le blochează – este stabilită de același produs RC care a dat constanta de timp pentru circuitul de eliminare a zgomotului de contact:

f_c = 1 / (2π × R × C)

Pentru ca filtrul să extragă o tensiune continuă curată dintr-o intrare PWM, frecvența de tăiere trebuie să fie mult mai mică decât frecvența PWM însăși. Componenta continuă (frecvența 0) trece neschimbată; armonica fundamentală a PWM-ului (la frecvența PWM) este atenuată cu aproximativ f_c / f_PWM. Un raport de 1 / 200 reduce ondulația reziduală de la ieșire la aproximativ 0.5 % din amplitudinea intrării.

Un punct de pornire rezonabil pentru o valoare de referință cu variație lentă:

  • Frecvența PWM f_PWM = 20 kHz – mult peste domeniul audio și ușor de generat curat de către temporizator.

  • Valorile filtrului R = 1.6 , C = 1 µF – dând f_c = 1 / (2π × 1.6 × 1 µF) 100 Hz.

Suprimarea de 200× la purtătoare reduce amplitudinea completă a PWM-ului la aproximativ Vcc / 200 ondulație reziduală la V_out – aproximativ 16 mV la 3,3 V.

Două note practice:

  • Impedanța de ieșire a filtrului este aproximativ R. Orice sarcină din aval care absoarbe curent transformă R și sarcina într-un divizor care trage V_out sub media ideală, exact ca divizorul de pe pagina Citirea semnalelor analogice cu ADC-ul. Alimentați un pin ADC sau un tampon (buffer) cu impedanță mare, nu o sarcină care absoarbe miliamperi.

  • Condensatorului îi ia aproximativ 5 × R × C 8 ms să se stabilizeze atunci când factorul de umplere se modifică; V_out rămâne în urma setării factorului de umplere cu atât. Pentru o valoare de referință care trebuie să se actualizeze mai rapid, ridicați frecvența de tăiere (R sau C mai mici) și acceptați mai multă ondulație.