3.14. Atenuarea LED-urilor cu PWM

Pagina Generarea semnalelor analogice cu PWM și un filtru RC a folosit un filtru trece-jos RC pentru a extrage o tensiune continuă dintr-un semnal PWM. Pentru un LED, filtrul nu este necesar – ochiul uman însuși realizează medierea.

Când un LED este aprins și stins mai repede de aproximativ 60 Hz, sistemul vizual nu mai distinge impulsurile individuale și percepe o luminozitate constantă egală cu emisia luminoasă medie. Un factor de umplere de 50 % este perceput ca aproximativ jumătate din luminozitate; 25 % ca un sfert; 10 % ca slabă.

Cablarea este aceeași ca pentru un LED extern static de pe Ieșire GPIO – un rezistor de limitare a curentului în serie cu LED-ul, dimensionat folosind regulile din Noțiuni de bază de electronică. Schimbarea este doar în software: pinul funcționează ca o ieșire PWM în loc de un simplu Pin.OUT.

3.14.1. Alegerea frecvenței

Pentru atenuarea LED-urilor, frecvența PWM trebuie doar să depășească pragul de pâlpâire al ochiului:

  • Sub ~60 Hz ochiul vede impulsurile direct.

  • Sub ~200 Hz vederea periferică și mișcările rapide ale ochiului pot încă scoate la iveală pâlpâirea.

  • 1 kHz este confortabil peste toate acestea și este o valoare implicită tipică.

Nu există o limită superioară care să conteze pentru un LED mic pe un GPIO; orice valoare de la 1 kHz la 10 kHz se comportă identic pentru ochi.

3.14.2. Estompare

O buclă de estompare progresivă / atenuare progresivă variază factorul de umplere de la oprit la complet aprins și înapoi, zăbovind scurt la fiecare pas:

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)

La PWM de 1 kHz și pași de 5 ms, ochiul vede o estompare lină în ambele direcții, luminozitatea aparentă urmărind valoarea factorului de umplere.

Luminozitatea percepută nu este strict liniară în raport cu factorul de umplere – răspunsul ochiului urmează aproximativ o lege pătratică sau cubică – așa că o variație liniară a duty_u16 nu arată ca o variație liniară a luminozității. Pentru o estompare perceptiv mai lină, variază factorul de umplere pe o curbă.

Un truc convenabil, doar cu numere întregi, este să incrementezi un contor pe 8 biți și să folosești pătratul lui ca factor de umplere. 255 × 255 = 65025 se află, în limitele rotunjirii, la valoarea de scală completă, astfel încât variația acoperă întregul interval:

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)

Estomparea pare acum aproximativ uniformă ca luminozitate aparentă, de la oprit la complet.