Skip to Content

Trailing Edge vs Leading Edge: Which Dimmer Method to Choose

Phase-cut dimming explained: why TRIAC (leading edge) causes LED flicker at low brightness, and when MOSFET (trailing edge) is the right hardware choice.
February 26, 2026 by
Trailing Edge vs Leading Edge: Which Dimmer Method to Choose
Administrator
| No comments yet

Short answer: Leading edge is the standard TRIAC dimmer — it opens the load in the second half of each AC half-cycle (best for incandescent bulbs and heaters). Trailing edge is a MOSFET dimmer — it opens the load from the start of each half-cycle (better for LED lamps, less flicker). Most low-cost dimmer modules use leading edge.



The Problem

Your TRIAC dimmer works perfectly with an incandescent bulb or heater — but swap in an LED lamp and problems appear: flickering, instability, erratic behavior at low brightness.

This is the classic mismatch between control method and load type. TRIAC dimmers implement leading edge — a method optimized for resistive loads that creates problems with electronic LED drivers. Trailing edge (MOSFET) solves these problems.

Typical mismatch symptoms from the forums:

  • «TRIAC leading edge dimmers don't produce good results with dimmable LED bulbs» (Arduino Forum, 2024)
  • «I use triac boards to drive incandescent lights and they dim/rise very well. But if I use LED lights they don't behave» (Arduino Forum, 2024)
  • LED flickering below 30–50% brightness that no code change can fix
  • Lamp works fine at 100%, but unstable when dimmed



Root Cause

Both methods use phase-cut control (phase angle control): a TRIAC or transistor opens at a specific point in the AC half-cycle and passes part of the sine wave to the load. The difference is which part of the half-cycle reaches the load.


Leading Edge (forward phase-cut)

text
Sine wave:   ╭─────╮        ╭─────╮
             │     │        │     │
─────────────╯     ╰────────╯     ╰────
Leading edge (50% power):
             ──╭───╮        ──╭───╮
               │   │          │   │
───────────────╯   ╰──────────╯   ╰────
               ↑ TRIAC fires here
  • TRIAC fires midway through the half-cycle
  • Load receives the second half of each half-cycle
  • Characteristic sharp voltage spike when the TRIAC fires
  • The industry standard for residential dimmers for the past 50 years

Problem with LED: The LED driver sees the voltage jump abruptly from zero to ~200–300 V. Many LED drivers react to this as an electrical spike or interference, trigger protection circuits, and behave erratically.


Trailing Edge (reverse phase-cut)

text
Sine wave:   ╭─────╮        ╭─────╮
             │     │        │     │
─────────────╯     ╰────────╯     ╰────
Trailing edge (50% power):
             ╭───╮          ╭───╮
             │   │          │   │
─────────────╯   ╰──────────╯   ╰──────
                 ↑ transistor switches off here
  • MOSFET (transistor) opens at the start of the half-cycle, closes midway
  • Load receives the first half of each half-cycle
  • Voltage rises smoothly from zero following the sine wave — no sharp spike
  • More complex and expensive circuit, requires more sophisticated control

Advantage with LED: The LED driver sees voltage that rises gradually from zero — identical to the start of a normal half-cycle, just shortened. Most LED drivers handle this waveform correctly.


The Control Math

c
// Leading edge: longer delay = less power
delay_us = firing_angle;     // larger delay = less power
// Trailing edge: longer delay = more power
// (we close the transistor sooner)
delay_us = half_period - firing_angle;  // larger delay = more power
// half_period:
// 50 Hz → 10,000 µs
// 60 Hz →  8,333 µs



Solutions



🟢 Beginner: Choosing the Right Module

Don't want to deal with phase angle math — pick the right module and use DimmerLink.

Most available TRIAC modules (including RBDimmer) use leading edge. This is the standard — it works well with resistive loads: incandescent bulbs, halogen, heaters, soldering irons, rheostats.

If you need trailing edge for LED — you need a MOSFET dimmer, not a TRIAC module.

Practical rule:

  • Incandescent / halogen / heater → any TRIAC dimmer (leading edge)
  • Quality LED labeled «TRIAC dimmable» → TRIAC (leading edge) works
  • LED with instability / flickering → trailing edge (MOSFET module)

Control via DimmerLink:

DimmerLink works with standard RBDimmer TRIAC modules (leading edge) over I2C or UART. When trailing edge is needed, DimmerLink also controls MOSFET modules.

When to choose DimmerLink:

  • ☐ Raspberry Pi (no realtime OS for ISR)
  • ☐ ESP32-S2/C3/H2 (single-core — software libraries not supported)
  • ☐ Want to control the dimmer from any platform without writing ISR code
  • cpp
    // DimmerLink via I2C — works with any connected module
    // (TRIAC leading edge or MOSFET trailing edge — no code changes needed)
    // Docs: https://www.rbdimmer.com/docs/dimmerlink-I2CCommunication
    #include <Wire.h>
    #define DIMMER_ADDR 0x50
    #define REG_LEVEL   0x10
    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% brightness
    }
    void loop() {}


    🔵 Advanced: Implementing in Code

    Want to control phase angle yourself — here's how it works.

    Both implementations use a zero-cross interrupt. The only difference is the delay formula before firing.


    Option A: Leading Edge on ESP32 with rbdimmerESP32 ✅ Recommended

    When: dual-core ESP32 + resistive loads or quality TRIAC-compatible LED lamps.

    The rbdimmerESP32 library implements leading edge by default.

    cpp
    // Platform: dual-core ESP32
    // Library: rbdimmerESP32 — leading edge, automatic
    // Source: github.com/robotdyn-dimmer/rbdimmerESP32
    #include "rbdimmerESP32.h"
    #define ZC_PIN  18
    #define DIM_PIN 19
    rbdimmer dimmer;
    void setup() {
        dimmer.begin(ZC_PIN, DIM_PIN, 50);  // 50 Hz mains
        dimmer.setPower(50);                // 50% power
    }
    void loop() {
        // Smooth ramp
        for (int p = 10; p <= 95; p++) {
            dimmer.setPower(p);
            delay(30);
        }
        for (int p = 95; p >= 10; p--) {
            dimmer.setPower(p);
            delay(30);
        }
    }


    Option B: Trailing Edge — Manual Implementation on Arduino AVR

    When: leading edge is causing LED problems and you need to switch to trailing edge without changing the module (some MOSFET modules allow this in hardware).

    cpp
    // Platform: Arduino Uno / Mega (AVR only)
    // Implementation: trailing edge via manual zero-cross ISR control
    // WARNING: only works with MOSFET modules — NOT with TRIAC!
    // For ESP32 use rbdimmerESP32 (leading edge)
    #define ZC_PIN  2   // zero-cross — pins 2 or 3 only on Uno
    #define DIM_PIN 11  // MOSFET gate control pin
    volatile int brightness = 50;  // 0–100%
    // Zero-cross interrupt
    void zeroCrossISR() {
        // Trailing edge: open at start, close after (brightness/100) * half_period
        // 50 Hz: half_period = 10,000 µs
        // 60 Hz: half_period = 8,333 µs
        int on_time = (brightness * 10000L) / 100;  // 50 Hz
        digitalWrite(DIM_PIN, HIGH);    // open MOSFET immediately
        delayMicroseconds(on_time);     // hold open
        digitalWrite(DIM_PIN, LOW);     // close MOSFET
    }
    void setup() {
        pinMode(DIM_PIN, OUTPUT);
        attachInterrupt(digitalPinToInterrupt(ZC_PIN),
                        zeroCrossISR, RISING);
    }
    void loop() {
        brightness = 50;  // 50%
    }

    Note: delayMicroseconds() inside an ISR blocks other interrupts. For production use, replace the delay with a hardware timer. This example demonstrates the principle only.



    ⚠️ Common Mistakes from the Forums

    Real errors from 3 forum threads (2019–2025).

    • «Switched to trailing edge in code — still flickering»: If you have a TRIAC module (not MOSFET), trailing edge in software does nothing. A TRIAC physically cannot do trailing edge — you need a MOSFET module.

    • «Switched to trailing edge — lamp looks dimmer at the same value»: This is expected. Trailing edge works with inverted logic compared to leading edge. At 50% trailing edge you get a different half-cycle portion than at 50% leading edge. Recalibrate your range.

    • «Found a library that does trailing edge on the same module»: If you have a standard TRIAC module (BTA16, BT139, BTA08) — no library can switch it to trailing edge. The hardware physics don't allow it.

    • «Forum users report: switching from leading-edge RBDimmer code to manual trailing-edge zero-crossing code FIXED LED flicker without changing hardware» — this only works if they had a MOSFET module, not a TRIAC.




    Quick Checklist

    Before posting to the forum, verify:

  • ☐ What is your module — TRIAC or MOSFET? (check the chip markings)
  • ☐ TRIAC (BTA08, BTA16, BT139) — leading edge only
  • ☐ MOSFET (IRLZ44N, IRF540) — supports trailing edge
  • ☐ Is your load resistive (incandescent) or LED with electronic driver?
  • ☐ For LED with problems: try swapping to a Philips/Osram lamp first —
  • this solves 80% of cases without changing the module



    Compatibility Table

    Method Module Load Works? Notes
    Leading edge TRIAC RBDimmer Incandescent bulb ✅ Excellent
    Leading edge TRIAC RBDimmer Halogen 230V ✅ Excellent
    Leading edge TRIAC RBDimmer Heater ✅ Excellent
    Leading edge TRIAC RBDimmer Philips/Osram LED ✅ Quality lamp
    Leading edge TRIAC RBDimmer Cheap no-name LED ⚠️ Flicker < 40%
    Trailing edge MOSFET Any dimmable LED ✅ Best result
    Trailing edge TRIAC Any ❌ Impossible in hardware



    Related Topics



    Still Have Questions?

    Post on rbdimmer.com forum or open a GitHub Issue.

    Share this post
    Sign in to leave a comment