3.14. LED dimmen met PWM¶
De pagina Analoog genereren met PWM en een RC-filter gebruikte een RC-laagdoorlaatfilter om een DC-spanning uit een PWM-signaal te halen. Voor een LED is het filter niet nodig – het menselijk oog doet het middelen zelf.
Wanneer een LED sneller dan ongeveer 60 Hz aan en uit wordt geschakeld, stopt het visuele systeem met het onderscheiden van individuele pulsen en neemt het een constante helderheid waar die gelijk is aan de gemiddelde lichtopbrengst. Een duty cycle van 50 % leest als ongeveer halve helderheid; 25 % als een kwart; 10 % als gedimd.
De bedrading is dezelfde als voor een statische externe LED op GPIO-uitgang – een stroombegrenzende weerstand in serie met de LED, gedimensioneerd met de regels uit Basiselektronica. De wijziging zit alleen in de software: de pin draait als een PWM-output in plaats van een gewone Pin.OUT.
3.14.1. De frequentie kiezen¶
Voor het dimmen van een LED hoeft de PWM-frequentie alleen de flikkerdrempel van het oog te overschrijden:
Onder ~60 Hz ziet het oog de pulsen ronduit.
Onder ~200 Hz kunnen perifeer zicht en snelle oogbewegingen nog steeds flikkering onthullen.
1 kHz ligt comfortabel boven dat alles en is een typische standaard.
Er is geen bovengrens die ertoe doet voor een kleine LED op een GPIO; alles van 1 kHz tot 10 kHz gedraagt zich hetzelfde voor het oog.
3.14.2. Faden¶
Een fade-in / fade-out-lus sweept de duty cycle van uit naar volledig aan en weer terug, en blijft bij elke stap kort hangen:
import time
from machine import PWM, Pin
led = PWM(Pin("P7"), freq=1000, duty_u16=0)
while True:
for d in range(0, 65535, 256):
led.duty_u16(d)
time.sleep_ms(5)
for d in range(65535, 0, -256):
led.duty_u16(d)
time.sleep_ms(5)
Bij 1 kHz PWM en stappen van 5 ms ziet het oog een soepele fade in beide richtingen, waarbij de waargenomen helderheid de duty-waarde volgt.
Waargenomen helderheid is niet strikt lineair in de duty cycle – de respons van het oog volgt ruwweg een kwadraat- of derdemachtswet – dus een lineaire sweep van duty_u16 ziet er niet uit als een lineaire sweep van helderheid. Voor een perceptueel soepelere fade stap je de duty op een curve.
Een handige truc met alleen gehele getallen is het ophogen van een 8-bits teller en het gebruiken van zijn kwadraat als de duty cycle. 255 × 255 = 65025 ligt binnen de afronding van de volledige schaal, dus de sweep beslaat het hele bereik:
import time
from machine import PWM, Pin
led = PWM(Pin("P7"), freq=1000, duty_u16=0)
while True:
for step in range(256):
led.duty_u16(step * step) # 0..65025, roughly quadratic
time.sleep_ms(5)
for step in range(255, -1, -1):
led.duty_u16(step * step)
time.sleep_ms(5)
De fade voelt nu ruwweg gelijkmatig in waargenomen helderheid van uit naar vol.