3.14. Dimerização de LED com PWM

A página Gerando sinais analógicos com PWM e um filtro RC usou um filtro passa-baixa RC para extrair uma tensão DC de um sinal PWM. Para um LED, o filtro não é necessário – o próprio olho humano faz a média.

Quando um LED é ligado e desligado mais rápido do que cerca de 60 Hz, o sistema visual deixa de resolver os pulsos individuais e percebe um brilho constante igual à saída luminosa média. Um ciclo de trabalho de 50 % é percebido como aproximadamente metade do brilho; 25 % como um quarto; 10 % como fraco.

A fiação é a mesma de um LED externo estático em Saída GPIO – um resistor limitador de corrente em série com o LED, dimensionado usando as regras de Fundamentos de eletrônica. A mudança está apenas no software: o pino funciona como uma saída PWM em vez de um simples Pin.OUT.

3.14.1. Escolhendo a frequência

Para dimerização de LED, a frequência de PWM só precisa superar o limiar de cintilação do olho:

  • Abaixo de ~60 Hz o olho enxerga os pulsos diretamente.

  • Abaixo de ~200 Hz a visão periférica e o movimento rápido dos olhos ainda podem revelar a cintilação.

  • 1 kHz está confortavelmente acima de tudo isso e é um padrão típico.

Não há limite superior que importe para um pequeno LED em um GPIO; qualquer valor de 1 kHz a 10 kHz se comporta da mesma forma para o olho.

3.14.2. Esmaecimento

Um laço de esmaecimento de entrada / esmaecimento de saída varre o ciclo de trabalho de desligado até totalmente ligado e de volta, permanecendo brevemente em cada passo:

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)

Com PWM de 1 kHz e passos de 5 ms, o olho vê um esmaecimento suave em ambos os sentidos, com o brilho aparente acompanhando o valor do ciclo de trabalho.

O brilho percebido não é estritamente linear em relação ao ciclo de trabalho – a resposta do olho segue aproximadamente uma lei quadrática ou cúbica – de modo que uma varredura linear de duty_u16 não parece uma varredura linear de brilho. Para um esmaecimento perceptualmente mais suave, varie o ciclo de trabalho em uma curva.

Um truque conveniente que usa apenas inteiros é incrementar um contador de 8 bits e usar seu quadrado como ciclo de trabalho. 255 × 255 = 65025 está dentro do arredondamento da escala total, então a varredura cobre toda a faixa:

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)

O esmaecimento agora parece aproximadamente uniforme em brilho aparente, de desligado até o máximo.