Passa al contenuto

How to Fix ESP32 AC Dimmer Flickering. Guide

ESP32 TRIAC dimmer flickers? Learn why it happens and 2 proven solutions: software (rbdimmerESP32.h) vs hardware (DimmerLink module).

If you are building an AC dimmer with a TRIAC, you have probably noticed flickering, unstable brightness, or random jumps in light intensity.

Most DIY developers think the problem is caused by:

  • low-quality dimmer hardware
  • bad TRIAC or optocoupler
  • PCB layout issues

But in most real-world projects, the dimmer hardware is not the problem.

The real issue is timing accuracy in firmware, especially on ESP8266 and ESP32.

This guide explains:

  • why TRIAC dimmers flicker
  • why ESP32 makes it harder
  • how to fix flicker using software
  • why dedicated hardware control is the most reliable solution


How an AC TRIAC Dimmer Works

A TRIAC dimmer does not reduce voltage smoothly.

It controls when the TRIAC turns on during each AC half-cycle.

Process:

  1. AC waveform crosses zero (zero-cross event)

2. MCU waits for a precise delay (phase angle)

3. MCU sends a short gate pulse to the TRIAC

4. TRIAC conducts until the next zero-cross

Brightness depends entirely on microsecond-level timing accuracy.

For a deep technical explanation, read:  https://www.rbdimmer.com/blog/diy-insights-1/ac-dimmer-based-on-zero-cross-detector-and-triac-operating-principles-and-applications-5


Why Timing Matters (By The Numbers)

AC dimming is real-time control. Here are the hard numbers:

  • AC frequency: 50 Hz(60Hz) → zero-cross every 10 ms
  • TRIAC firing accuracy required: ±50 µs for stable brightness
  • ESP32 Wi-Fi interrupt blocking: 200–500 µs
  • Result: visible flicker even under moderate CPU load

💡 This means Wi-Fi can break TRIAC timing by 10× the acceptable error margin.


Why Flickering Happens in ESP8266 / ESP32 Projects

ESP chips are powerful but not real-time by default.

They run:

  • Wi-Fi / BLE stacks
  • Flash memory access (often blocking)
  • RTOS scheduling (ESP32)
  • Background system tasks

If dimmer timing code competes with these tasks:

  • zero-cross interrupts get delayed
  • TRIAC gate pulses shift
  • brightness becomes unstable

This becomes worse when:

  • MQTT / OTA / Web UI is active
  • logging is enabled
  • multiple dimmer channels are used

Common Beginner Mistakes

Popular Arduino / ESPHome / Tasmota examples often:

  • use delay() after zero-cross
  • run timing logic in non-deterministic callbacks
  • call blocking functions inside ISR
  • access Flash memory during timing-critical code

They work in demos, but fail in real products.


Solution 1 — Software-Based: rbdimmerESP32.h

For ESP32 dual-core chips, flicker can be solved in software if done correctly.

What rbdimmerESP32.h Does

rbdimmerESP32.h is designed for deterministic TRIAC control:

  • hardware timers (not software delays)
  • ISR code stored in IRAM (no flash stalls)
  • core separation: real-time vs Wi-Fi
  • FreeRTOS-safe architecture

Repo: 👉 https://github.com/robotdyn-dimmer/rbdimmerESP32


Key Technical Details IRAM (Instruction RAM)

ESP32 normally executes code from Flash.

Flash access can stall the CPU for hundreds of microseconds.

Solution:

Place timing-critical code in IRAM using:

IRAM_ATTR void zeroCrossISR() {
  // ultra-fast ISR code
}

Hardware Timers

Never use delay() or millis() for TRIAC timing.

Use ESP32 hardware timers for microsecond precision.


Dual-Core Strategy

  • Core 0: dimmer timing (real-time)
  • Core 1: Wi-Fi, MQTT, UI, logging

This isolation prevents flicker.


When Software Solution Makes Sense

✅ ESP32 only

✅ You understand interrupts and RTOS

✅ You need full firmware control

⚠️ Requires careful architecture


DO ✅

  • Use ESP32 hardware timers for TRIAC control
  • Keep ISR code under 10 µs
  • Run dimming on Core 0, Wi-Fi on Core 1
  • Store timing-critical code in IRAM


DON'T ❌

  • Never call Serial.print() from ISR
  • Don’t access Flash in timing-critical code
  • Avoid delay() near zero-cross logic
  • Don’t mix dimming and networking tasks

Solution 2 — Hardware-Based: DimmerLink (Recommended)

The most reliable way to eliminate flicker is to remove TRIAC timing from the main MCU.

What Is DimmerLink

DimmerLink is a dedicated dimmer controller module:

  • detects zero-cross
  • generates TRIAC pulses internally
  • guarantees stable timing
  • communicates via UART / I²C

Docs: 👉 https://github.com/robotdyn-dimmer/DimmerLink


Why DimmerLink Eliminates Flicker

  • Wi-Fi cannot delay TRIAC firing
  • MCU timing bugs cannot affect dimming
  • Flash stalls are irrelevant
  • Scaling to multiple channels is trivial

Your MCU just sends Serial (UART) commands like:

Example: 02 53 00 32  → Set dimmer 0 to 50%
Response: 00          → OK
LEVELBrightness
0x00 (0)0% — off
0x32 (50)50%
0x64 (100)100% — full brightness

Software vs Hardware Comparison

CriteriarbdimmerESP32.hDimmerLink
Cost (BOM)$0$1.5
Power consumptionSame as MCU+10 mA
PCB space0 (software)~1×2 cm
Certification (CE/UL)DIY onlyDIY only
ESP8266 support✔️
ESP32 support✔️✔️

RaspberryPI/OrangePI..

✔️

Multiple dimmers⚠️ complex✔️ easy
Beginner-friendly✔️
Production ready⚠️✔️

Decision Tree: Which Solution Is Right for Me?


Are you using ESP8266?

  • Use DimmerLink

Are you using ESP32 and want full control?

  • Use rbdimmerESP32

Do you need multiple dimmers and rock-solid stability?

  • Use DimmerLink

Are you building a commercial product?

  • Use DimmerLink

Are you experimenting and learning real-time programming?

  • Use rbdimmerESP32
 


Final Thoughts

TRIAC dimming is not about voltage — it is about microsecond timing.

Wi-Fi is not real-time.

Delays are dangerous.

Flash is unpredictable.

If you want stable light and zero flicker, isolate timing or move it to dedicated hardware - DimmerLink.




Condividi articolo
Accedi per lasciare un commento