3.14. Ściemnianie diody LED za pomocą PWM

Strona Generowanie sygnału analogowego za pomocą PWM i filtru RC używała filtru dolnoprzepustowego RC do uzyskania napięcia stałego z sygnału PWM. W przypadku diody LED filtr nie jest potrzebny – samo ludzkie oko dokonuje uśredniania.

Gdy dioda LED jest załączana i wyłączana szybciej niż około 60 Hz, układ wzrokowy przestaje rozróżniać pojedyncze impulsy i postrzega stałą jasność równą średniej emisji światła. Współczynnik wypełnienia 50 % odczytywany jest jako mniej więcej połowa jasności; 25 % jako ćwierć; 10 % jako przyciemnienie.

Okablowanie jest takie samo jak dla statycznej zewnętrznej diody LED na stronie Wyjście GPIO – rezystor ograniczający prąd połączony szeregowo z diodą LED, dobrany zgodnie z zasadami z Podstawy elektroniki. Zmiana dotyczy tylko oprogramowania: pin pracuje jako wyjście PWM zamiast zwykłego Pin.OUT.

3.14.1. Dobór częstotliwości

Do ściemniania diody LED częstotliwość PWM musi jedynie przekroczyć próg migotania dla oka:

  • Poniżej ~60 Hz oko widzi impulsy bezpośrednio.

  • Poniżej ~200 Hz widzenie peryferyjne i szybkie ruchy oka mogą nadal ujawniać migotanie.

  • 1 kHz jest wygodnie powyżej tego wszystkiego i stanowi typową wartość domyślną.

Nie istnieje istotna górna granica dla małej diody LED na pinie GPIO; wszystko od 1 kHz do 10 kHz zachowuje się dla oka tak samo.

3.14.2. Wygaszanie

Pętla rozjaśniania / wygaszania przesuwa współczynnik wypełnienia od wyłączenia do pełnego załączenia i z powrotem, zatrzymując się na chwilę przy każdym kroku:

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)

Przy PWM 1 kHz i krokach 5 ms oko widzi płynne przejście w obu kierunkach, a postrzegana jasność podąża za wartością wypełnienia.

Postrzegana jasność nie jest ściśle liniowa względem współczynnika wypełnienia – reakcja oka podąża z grubsza za prawem kwadratowym lub sześciennym – więc liniowa zmiana duty_u16 nie wygląda jak liniowa zmiana jasności. Dla percepcyjnie płynniejszego przejścia zmieniaj wypełnienie według krzywej.

Wygodną sztuczką operującą wyłącznie na liczbach całkowitych jest zwiększanie 8-bitowego licznika i użycie jego kwadratu jako współczynnika wypełnienia. 255 × 255 = 65025 mieści się w granicach zaokrąglenia pełnej skali, więc przebieg obejmuje cały zakres:

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)

Przejście wydaje się teraz z grubsza równomierne w postrzeganej jasności od wyłączenia do pełnej mocy.