3.13. Analoog genereren met PWM en een RC-filter¶
De ADC leest spanningen op een pin. Het tegenovergestelde – een tussenliggende spanning produceren tussen 0 V en Vcc op een pin – is moeilijker, omdat een GPIO-uitgang alleen weet hoe hij zijn twee rails moet aansturen. De standaard vervanging is om de pin snel genoeg tussen de rails te schakelen zodat de gemiddelde spanning is waar het je om gaat.
3.13.1. Pulsbreedtemodulatie¶
Een pulsbreedtegemoduleerd (PWM) signaal is een blokgolf op een vaste frequentie waarvan de hoogtijd – het deel van elke cyclus dat op Vcc wordt doorgebracht in plaats van aarde – in software wordt ingesteld. Dat deel is de duty cycle. De gemiddelde spanning van de golfvorm is de duty cycle maal Vcc:
V_avg = duty × Vcc
Een duty cycle van 25 % middelt naar Vcc / 4; een duty cycle van 50 % naar Vcc / 2; een duty cycle van 75 % naar 3 × Vcc / 4.
PWM bij 25 %, 50 % en 75 % duty cycle. De gemiddelde spanning volgt de duty cycle.¶
De frequentie wordt ingesteld wanneer de PWM wordt geconfigureerd; de duty cycle is wat software ter plekke verandert. De klasse machine.PWM omhult een hardware timer-kanaal dat de golfvorm genereert zonder hulp van de CPU – eenmaal geconfigureerd gaat het signaal door op de gekozen frequentie en duty cycle totdat het wordt gewijzigd.
3.13.2. De klasse machine.PWM¶
Construeer een PWM-instantie met de pin en een initiële frequentie en duty:
from machine import PWM, Pin
pwm = PWM(Pin("P7"), freq=20_000, duty_u16=32768)
Dat start een blokgolf van 20 kHz bij 50 % duty op P7. Twee methoden veranderen de uitgang ter plekke:
pwm.duty_u16(16384) # change to 25 % (16384 / 65535)
pwm.freq(5_000) # change to 5 kHz
duty_u16() neemt een unsigned 16-bit geheel getal dat 0 afbeeldt op “altijd laag” en 65535 op “altijd hoog”. freq() stelt de draaggolffrequentie in hertz in.
Notitie
Elk PWM-kanaal op dezelfde hardware timer deelt zijn frequentie. Het aanroepen van freq() op één kanaal verandert elk ander kanaal dat aan die timer is gekoppeld. Gebruik kanalen van verschillende timers wanneer uitgangen op verschillende frequenties moeten draaien.
Roep deinit() aan om het timer-kanaal vrij te geven wanneer de uitgang niet langer nodig is.
3.13.3. Middelen met een RC-laagdoorlaatfilter¶
Ruwe PWM is geen vloeiende spanning; het is een blokgolf waarvan het gemiddelde is wat we willen. Om dat gemiddelde te extraheren, stuur je de PWM door een laagdoorlaatfilter – dezelfde weerstand-en-condensator-combinatie die wordt gebruikt voor het ontdenderen van schakelaars in Ontdenderen (debouncing).
PWM door een RC-laagdoorlaatfilter: de condensator middelt de blokgolf tot een gelijkspanning die evenredig is met de duty cycle.¶
De afsnijfrequentie van het filter – de grens tussen frequenties die het doorlaat en die het blokkeert – wordt bepaald door hetzelfde RC-product dat de tijdconstante gaf voor het ontdendercircuit:
f_c = 1 / (2π × R × C)
Om het filter een schone gelijkspanning te laten extraheren uit een PWM-ingang, moet de afsnijfrequentie veel lager zijn dan de PWM-frequentie zelf. De gelijkstroomcomponent (frequentie 0) gaat ongewijzigd door; de grondharmonische van de PWM (op de PWM-frequentie) wordt verzwakt met ongeveer f_c / f_PWM. Een verhouding van 1 / 200 reduceert de resterende rimpel aan de uitgang tot ongeveer 0.5 % van de ingangsuitslag.
Een redelijk startpunt voor een langzaam veranderend instelpunt:
PWM-frequentie
f_PWM = 20 kHz– ruim boven audio, en gemakkelijk voor de timer om schoon te genereren.Filterwaarden
R = 1.6 kΩ,C = 1 µF– watf_c = 1 / (2π × 1.6 kΩ × 1 µF) ≈ 100 Hzgeeft.
De 200×-onderdrukking bij de draaggolf reduceert de volle uitslag van de PWM tot ongeveer Vcc / 200 resterende rimpel op V_out – ongeveer 16 mV bij 3,3 V.
Twee praktische opmerkingen:
De uitgangsimpedantie van het filter is ruwweg
R. Elke stroomafwaartse belasting die stroom trekt, maakt vanRen de belasting een deler dieV_outonder het ideale gemiddelde trekt, precies zoals de deler op de Analoog lezen met de ADC-pagina. Voed een ADC-pin of een hoogohmige buffer, geen belasting die milliampères afvoert.De condensator heeft ongeveer
5 × R × C ≈ 8 msnodig om te stabiliseren wanneer de duty cycle verandert;V_outloopt zoveel achter op de duty-instelling. Voor een instelpunt dat sneller moet updaten, verhoog de afsnijfrequentie (kleinereRofC) en accepteer meer rimpel.