Respuesta corta: El parpadeo LED con un dimmer AC tiene tres causas distintas. Los Tipos 1 y 2 están causados por incompatibilidad arquitectónica de los dimmers AC TRIAC con las bombillas LED — la solución hardware es un dimmer AC MOSFET (trailing edge, diseñado para LED). Si usa un dimmer TRIAC, cambie a una lámpara Philips/Osram/Ikea y mantenga el brillo por encima del 20 %. El Tipo 3 es una perturbación del timing ESP32 por WiFi/BLE — se corrige con la biblioteca rbdimmerESP32 o DimmerLink (aplica a cualquier tipo de dimmer).
El problema
Configuró su dimmer, el código funciona, la detección de cruce por cero es correcta — pero la bombilla LED sigue parpadeando. Es más notable por debajo del 40–50 % de brillo. Sospecha que hay un problema con interrupciones o timing, pero los cambios de código no ayudan.
La clave: el parpadeo tiene múltiples causas que requieren soluciones distintas. Los cambios de código solo ayudan con el Tipo 3 (timing ESP32). Para los Tipos 1 y 2, hay que cambiar el tipo de dimmer (a MOSFET) o la lámpara — no el código.
Síntomas por tipo de parpadeo:
Tipo 1 (driver LED / arquitectura TRIAC):
- «Las LED regulables baratas usan directamente la red atenuada para el PWM del LED, lo que da parpadeo perceptible» (Arduino Forum, 2019)
- Parpadeo visible por debajo del 40–50 % de brillo; lámpara bien al 100 %
- Los cambios de código no hacen diferencia — mismo efecto con cualquier configuración
- Incluso al 50 %, las lámparas baratas parpadean visiblemente
Tipo 2 (corriente de mantenimiento TRIAC):
- Destellos aleatorios a bajo brillo o con carga ligera
- Zumbido por debajo del 20 % de brillo
- Una sola bombilla LED de 5–7 W sin carga adicional
Tipo 3 (timing ESP32):
- Parpadeo irregular, impredecible — no sincronizado con la red
- Desaparece al desconectar WiFi (
WiFi.disconnect()) - Aparece bajo carga activa MQTT/HTTP en ESP32
- Las lámparas de calidad también parpadean — cambia al modificar el código
TRIAC vs MOSFET: por qué el tipo de dimmer importa más que el código
Los Tipos 1 y 2 no son defectos de la lámpara ni del código. Son el resultado de que los dimmers AC TRIAC fueron diseñados para bombillas incandescentes — no para bombillas LED.
| Parámetro | Dimmer AC TRIAC | Dimmer AC MOSFET |
|---|---|---|
| Método de conmutación | Leading edge (pico brusco al inicio del semiciclo) | Trailing edge (corte suave al final) |
| Diseñado para | Incandescencia, halógeno, calentadores resistivos | Bombillas LED, transformadores de baja tensión |
| Corriente de mantenimiento | Sí — corriente mínima para seguir conductivo | No — funciona con cualquier carga |
| Parpadeo LED | Tipos 1 y 2 con lámparas baratas | Ninguno — trailing edge es compatible con LED |
| Rango de atenuación LED | 20–95 % (inestable por debajo) | 5–95 % |
El dimmer AC MOSFET elimina los Tipos 1 y 2 a nivel hardware:
- Trailing edge abre la carga al inicio de cada semiciclo: el driver LED recibe inmediatamente la tensión completa y carga sus condensadores tampón — la pulsación de 100/120 Hz desaparece.
- Sin corriente de mantenimiento: operación estable con cargas tan pequeñas como 5 W.
El Tipo 3 (timing ESP32) aplica igualmente a ambos tipos de dimmers — no está relacionado con el método de conmutación, sino solo con la precisión de las interrupciones del MCU.
Causas fundamentales
Detailed theory of zero-cross detection and TRIAC operation: AC Dimmer: Zero-Cross and TRIAC — How It Works.
Tipo 1: parpadeo del driver LED (específico de TRIAC)
El TRIAC corta la onda sinusoidal AC desde el leading edge: en cada semiciclo, la primera parte se corta y la corriente fluye solo en la segunda parte. A bajo brillo — solo un breve pulso de corriente al final de cada semiciclo.
Un driver LED de calidad suaviza estos pulsos mediante condensadores y ejecuta su propio PWM de alta frecuencia (1–4 kHz). Resultado: luz estable y uniforme.
Un driver LED barato rectifica la corriente sin buffer. El LED recibe corriente continua pulsante a 100 Hz (red de 50 Hz) o 120 Hz (red de 60 Hz). Esta frecuencia es visible al ojo humano — el parpadeo es obvio.
Un dimmer AC MOSFET (trailing edge) abre la carga al inicio de cada semiciclo: el driver LED recibe inmediatamente la tensión completa y carga sus condensadores. La pulsación de 100 Hz desaparece — incluso con una lámpara barata.
Tipo 2: corriente de mantenimiento TRIAC (específico de TRIAC)
Cada TRIAC tiene un parámetro de corriente de mantenimiento — la corriente mínima necesaria para permanecer conductivo. Si la corriente de carga cae por debajo de este valor, el TRIAC se apaga aleatoriamente — antes del cruce por cero. Resultado: semiciclos perdidos, destellos aleatorios y zumbido a bajo brillo.
El MOSFET no tiene corriente de mantenimiento — es un transistor, no un tiristor. Operación estable incluso con cargas tan pequeñas como 5 W.
Tipo 3: perturbación del timing ESP32 (independiente del dimmer)
El control TRIAC requiere precisión de ±50 µs: el MCU debe disparar el TRIAC exactamente en el retardo calculado después del cruce por cero. La pila WiFi de ESP32 y las tareas RTOS pueden retrasar la ejecución del ISR 200–500 µs — el parpadeo aparece bajo WiFi activo.
Fuentes de retraso:
- La pila WiFi / BLE bloquea temporalmente las interrupciones mientras procesa paquetes
- Acceso a memoria Flash (OTA, SPIFFS, Serial) — congelación de 10–100 ms
- ISR no en IRAM: ESP32 la lee desde Flash en cada llamada — añade retraso
loop()y WiFi en el mismo núcleo (Core 1) compiten por CPU
Diferencia clave con Tipos 1 y 2: el parpadeo es irregular, desaparece
con WiFi.disconnect(), y cambia al modificar el código — no al cambiar
la lámpara.
Detailed breakdown: How to Fix ESP32 AC Dimmer Flickering.
Soluciones
🔑 Mejor solución: dimmer AC MOSFET
Elimina los Tipos 1 y 2 a nivel hardware — sin cambio de lámpara, sin ajuste de código.
El dimmer AC MOSFET (trailing edge) está diseñado específicamente para bombillas LED. La conmutación trailing edge da al driver LED un inicio limpio en cada semiciclo — la pulsación de 100/120 Hz desaparece. Sin corriente de mantenimiento — operación estable con una sola lámpara de 5–7 W.
Cuándo elegir el dimmer AC MOSFET:
El Tipo 3 (timing ESP32) aplica también a dimmers MOSFET — la precisión del ISR es igualmente importante. Use rbdimmerESP32 o DimmerLink para resolverlo.
🟢 Principiante: TRIAC + lámpara de calidad o DimmerLink
¿Usa un dimmer TRIAC? Dos opciones: reemplazar la lámpara o usar DimmerLink.
Opción 1: Reemplace la lámpara por un modelo con driver LED de calidad:
- Philips WarmGlow, SceneSwitch, Master LED
- Osram CLASSIC A, SUPERSTAR
- Ikea TRÅDFRI (gama regulable)
Busque en el embalaje: «TRIAC dimmable», «phase-cut compatible», «leading edge compatible».
Opción 2: Carga mínima.
Al menos 15–20 W. Para cargas más ligeras, conecte una resistencia de lastre en paralelo: 100–150 Ω / 20 W.
Opción 3: Control I2C sin ISR — DimmerLink.
If you use Raspberry Pi, ESP32-S2/C3/H2, or simply don't want to deal with interrupts — Cualquier ESP32 controls TRIAC via I2C without writing any ISR code.
Cuándo elegir DimmerLink:
// DimmerLink vía I2C — sin ISR, sin cruce por cero en su código
// Funciona con: Arduino, ESP32, Raspberry Pi
// Documentación: https://www.rbdimmer.com/docs/dimmerlink-I2CCommunication
#include <Wire.h>
#define DIMMER_ADDR 0x50
#define REG_LEVEL 0x10
// Establecer brillo (20–95 % para bombillas LED con TRIAC)
void setLevel(uint8_t level) {
Wire.beginTransmission(DIMMER_ADDR);
Wire.write(REG_LEVEL);
Wire.write(level);
Wire.endTransmission();
}
void setup() {
Wire.begin();
setLevel(50); // 50 % de brillo
}
void loop() {}Resultado: brillo estable sin parpadeo, siempre que use una lámpara de calidad.
🔵 Avanzado: corregir el timing ESP32 (Tipo 3)
El Tipo 3 aplica a cualquier dimmer AC — TRIAC o MOSFET.
Identifique primero el tipo de parpadeo — de lo contrario la corrección no ayudará:
| Síntoma | Tipo | Solución |
|---|---|---|
| Mismo parpadeo con cualquier código | Tipo 1 — driver LED | Dimmer AC MOSFET o reemplazar lámpara |
| Destellos aleatorios, zumbido < 20 % | Tipo 2 — corriente de mantenimiento TRIAC | Dimmer AC MOSFET o mín. 20 % |
| Cambia con WiFi encendido/apagado | Tipo 3 — timing ESP32 | IRAM_ATTR / rbdimmerESP32 |
Corregir el timing ESP32 (Tipo 3)
Si el parpadeo desaparece con WiFi.disconnect() — el problema es el timing
del ISR.
// Problema: ISR no en IRAM — ESP32 la lee desde Flash en cada llamada
// Solución: IRAM_ATTR coloca el ISR en RAM de forma permanente
// ❌ Incorrecto (sin IRAM_ATTR — parpadeo bajo carga WiFi):
void zeroCrossISR() {
triggerTriac();
}
// ✅ Correcto (IRAM_ATTR — ISR siempre en RAM, sin retrasos Flash):
void IRAM_ATTR zeroCrossISR() {
triggerTriac();
}For ESP32 doble núcleo, IRAM_ATTR is applied automatically inside the library.
La separación de núcleos mejora aún más la estabilidad:
// rbdimmerESP32: ISR se ejecuta en Core 0 (núcleo del sistema)
// loop() y WiFi se ejecutan en Core 1 — sin competencia de CPU
#include "rbdimmerESP32.h"
// ... resto del código sin cambiosRegla clave para bombillas LED: nunca establezca el brillo por debajo del 20 %. La mayoría de las bombillas LED se comportan de forma inestable en el rango 0–15 %.
Opción A: ESP32 con rbdimmerESP32 ✅ Recomendado
When: dual-core ESP32 only (not S2/C3/H2) Library: rbdimmerESP32 — docs · GitHub
// Plataforma: ESP32 de doble núcleo
// Biblioteca: rbdimmerESP32
// Rango: 20–95 % para atenuación LED estable con TRIAC
#include "rbdimmerESP32.h"
#define ZC_PIN 18 // entrada de cruce por cero
#define DIM_PIN 19 // control de puerta TRIAC
rbdimmer dimmer;
// Limitar rango de brillo para bombillas LED
void setLedLevel(uint8_t percent) {
// Convierte 0–100 % → 20–95 % para estabilidad LED con TRIAC
uint8_t mapped = 20 + (percent * 75) / 100;
if (mapped > 95) mapped = 95;
dimmer.setPower(mapped);
}
void setup() {
dimmer.begin(ZC_PIN, DIM_PIN, 50); // red de 50 Hz
setLedLevel(50);
}
void loop() {}Errores comunes:
- Usar
rbdimmerESP32en ESP32 de un solo núcleo (S2/C3/H2) — no soportado - Establecer brillo = 0 en vez de llamar off: el TRIAC es inestable con
ángulos de disparo muy pequeños. Use
setPower(0)solo para apagar completamente.
Opción B: Arduino AVR (Uno, Mega, Nano)
When: AVR boards only — do not use on ESP32! Library: Arduino Uno/Mega (legacy)
// Plataforma: Arduino Uno / Mega / Nano (solo AVR)
// ADVERTENCIA: para ESP32, use rbdimmerESP32
// Cruce por cero: solo pines 2 o 3 en Uno/Nano
#include <RBDdimmer.h>
#define ZC_PIN 2 // cruce por cero — solo pines 2 o 3
#define DIM_PIN 11 // pin con PWM
dimmerLamp dimmer(DIM_PIN, ZC_PIN);
void setup() {
dimmer.begin(NORMAL_MODE, ON);
dimmer.setPower(20); // mínimo 20 % para bombillas LED
}
void loop() {}⚠️ Errores comunes de los foros
Errores reales de 3 hilos de foros (2019–2025).
-
«Probé diferentes códigos — el parpadeo no desaparece»: El código no es el problema para los Tipos 1 y 2. Hay que cambiar el dimmer (dimmer AC MOSFET) o la lámpara (Philips/Osram).
-
«Por debajo del 30 % de brillo, destellos brillantes aleatorios»: Corriente de mantenimiento TRIAC (Tipo 2). Solución: dimmer AC MOSFET, o mantener brillo por encima del 20 %, o añadir más carga.
-
«Al 100 % funciona bien, parpadea solo al atenuar»: Señal clásica de driver LED barato (Tipo 1). A plena potencia la onda sinusoidal no se corta. Dimmer AC MOSFET o cambio de lámpara lo soluciona.
-
«Agregué delay() en loop() — mejoró un poco»: Ilusión. Sincronización accidental con la frecuencia de red. Con otros ajustes de brillo volverá a parpadear.
-
«ESP32 solo parpadea con WiFi activo»: Tipo 3 — perturbación del timing ISR. Solución:
rbdimmerESP32(IRAM_ATTR aplicado automáticamente) o DimmerLink (aislamiento hardware del control del dimmer).
Checklist rápido
Antes de publicar en el foro, verifique:
→ Tipo 3 — use IRAM_ATTR o rbdimmerESP32
Tabla de compatibilidad
| Lámpara | TRIAC (leading edge) | MOSFET (trailing edge) | Notas |
|---|---|---|---|
| Philips WarmGlow / Master LED | ✅ 10–95 % | ✅ 5–95 % | Recomendado |
| Osram SUPERSTAR | ✅ 15–95 % | ✅ 5–95 % | Recomendado |
| Ikea TRÅDFRI dimmable | ✅ 10–95 % | ✅ 5–95 % | Recomendado |
| «Dimmable» genérica barata | ⚠️ Parpadea < 40 % | ✅ 5–95 % | MOSFET lo corrige |
| Bombilla incandescente | ✅ 10–95 % | ✅ 5–95 % | Carga resistiva ideal |
| Cualquier LED «non-dimmable» | ❌ Parpadeo constante | ❌ Posible | Reemplazar la lámpara |
Temas relacionados
- LED Lamps with AC Dimmer: TRIAC vs MOSFET — Compatibility Guide
- Trailing Edge vs Leading Edge: Which Dimmer Method to Choose
¿Todavía tiene preguntas?
Post on rbdimmer.com forum or open a GitHub Issue.