3.14. Stmívání LED pomocí PWM

Stránka Generování analogového signálu pomocí PWM a RC filtru používala RC dolní propust k získání stejnosměrného napětí z PWM signálu. U LED tento filtr není potřeba – průměrování zajišťuje samo lidské oko.

Když se LED zapíná a vypíná rychleji než asi 60 Hz, zrakový systém přestane rozlišovat jednotlivé pulzy a vnímá ustálený jas rovný průměrnému světelnému výkonu. Střída 50 % se jeví zhruba jako poloviční jas; 25 % jako čtvrtinový; 10 % jako tlumený.

Zapojení je stejné jako u statické externí LED na stránce GPIO výstup – proud omezující rezistor v sérii s LED, dimenzovaný podle pravidel ze stránky Základy elektroniky. Mění se pouze software: pin běží jako výstup PWM namísto prostého Pin.OUT.

3.14.1. Volba frekvence

Pro stmívání LED musí frekvence PWM překonat pouze práh blikání oka:

  • Pod ~60 Hz vidí oko pulzy přímo.

  • Pod ~200 Hz může periferní vidění a rychlý pohyb očí stále odhalit blikání.

  • 1 kHz je pohodlně nad všemi těmito hodnotami a je typickou výchozí volbou.

Pro malou LED na GPIO neexistuje žádná horní hranice, na které by záleželo; cokoli od 1 kHz do 10 kHz se oku jeví stejně.

3.14.2. Prolínání

Smyčka pro postupné rozsvícení / zhasnutí přejíždí střídu od vypnutí po plné rozsvícení a zpět, přičemž se na každém kroku krátce zdrží:

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)

Při PWM 1 kHz a krocích po 5 ms vidí oko plynulé prolínání oběma směry, kdy zdánlivý jas sleduje hodnotu střídy.

Vnímaný jas není ve střídě striktně lineární – odezva oka se řídí zhruba kvadratickým nebo kubickým zákonem –, takže lineární nárůst hodnoty duty_u16 nevypadá jako lineární nárůst jasu. Pro percepčně plynulejší prolínání měňte střídu po křivce.

Pohodlným trikem využívajícím pouze celá čísla je zvyšovat 8bitový čítač a jeho druhou mocninu použít jako střídu. 255 × 255 = 65025 je po zaokrouhlení na hranici plného rozsahu, takže přejezd pokryje celý rozsah:

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)

Prolínání nyní působí zhruba rovnoměrně ve zdánlivém jasu od vypnutí po plný výkon.