3.14. Atenuación de LED con PWM¶
La página Generación de señales analógicas con PWM y un filtro RC usaba un filtro paso bajo RC para extraer una tensión continua de una señal PWM. Para un LED, el filtro no es necesario: el propio ojo humano hace el promediado.
Cuando un LED se enciende y se apaga más rápido que unos 60 Hz, el sistema visual deja de resolver los pulsos individuales y percibe un brillo constante igual a la emisión de luz promedio. Un ciclo de trabajo del 50 % se percibe como aproximadamente medio brillo; el 25 % como un cuarto; el 10 % como tenue.
El cableado es el mismo que para un LED externo estático en Salida GPIO – una resistencia limitadora de corriente en serie con el LED, dimensionada con las reglas de Fundamentos de electrónica. El cambio está solo en el software: el pin funciona como una salida PWM en lugar de un simple Pin.OUT.
3.14.1. Elegir la frecuencia¶
Para la atenuación de LED, la frecuencia de PWM solo tiene que superar el umbral de parpadeo del ojo:
Por debajo de ~60 Hz el ojo ve los pulsos directamente.
Por debajo de ~200 Hz la visión periférica y los movimientos rápidos del ojo todavía pueden revelar parpadeo.
1 kHz queda holgadamente por encima de todo eso y es un valor predeterminado típico.
No hay un límite superior que importe para un LED pequeño en un GPIO; cualquier valor entre 1 kHz y 10 kHz se comporta igual a ojos del observador.
3.14.2. Atenuación progresiva¶
Un bucle de fundido de entrada y fundido de salida barre el ciclo de trabajo desde apagado hasta totalmente encendido y de vuelta, deteniéndose brevemente en cada paso:
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)
A 1 kHz de PWM y pasos de 5 ms, el ojo ve un fundido suave en ambos sentidos, con el brillo aparente siguiendo el valor del ciclo de trabajo.
El brillo percibido no es estrictamente lineal respecto al ciclo de trabajo – la respuesta del ojo sigue aproximadamente una ley cuadrática o cúbica – de modo que un barrido lineal de duty_u16 no parece un barrido lineal del brillo. Para un fundido perceptualmente más suave, varía el ciclo de trabajo siguiendo una curva.
Un truco cómodo que usa solo enteros es incrementar un contador de 8 bits y usar su cuadrado como ciclo de trabajo. 255 × 255 = 65025 está, salvo redondeo, en el fondo de escala completo, de modo que el barrido cubre todo el rango:
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)
El fundido ahora se percibe aproximadamente uniforme en brillo aparente, desde apagado hasta máximo.