Ir al contenido

ESPHome YAML for AC TRIAC Dimmer: Standard and DimmerLink

Ready-to-use ESPHome YAML configurations for AC TRIAC dimmers — from a 10-line minimal setup to a full DimmerLink integration with sensors, curve selection, and lambda functions.

TL;DR: Two ESPHome integration methods exist. The standard ac_dimmer platform works out-of-the-box but has ISR/WiFi conflicts on ESP32. The DimmerLink external component uses a hardware controller for reliable, flicker-free dimming on any board.



Method Comparison

Feature Standard ac_dimmer DimmerLink component
ESP8266 ✅ Stable ✅ Stable
ESP32 (dual-core) ⚠️ May flicker ✅ Stable
ESP32-S2/C3/H2/C6 ❌ Not supported ✅ Supported
Raspberry Pi ❌ Not supported ✅ Supported
Additional hardware None DimmerLink module
YAML lines (minimal) ~10 ~30
Built-in sensors No Frequency, brightness
Dimming curve select No LINEAR / RMS / LOG



Method 1: Standard ESPHome ac_dimmer Platform

This is the built-in ESPHome platform. No external components needed.


Minimal config (ESP8266)

yaml
esphome:
  name: dimmer-esp8266
  platform: ESP8266
  board: nodemcuv2
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
api:
  encryption:
    key: !secret api_key
ota:
  password: !secret ota_password
output:
  - platform: ac_dimmer
    id: dimmer_out
    gate_pin: GPIO4          # DIM pin
    zero_cross_pin:
      number: GPIO5          # ZC pin
      mode: INPUT
      inverted: yes
    method: leading_pulse    # TRIAC default
light:
  - platform: monochromatic
    output: dimmer_out
    name: "Dimmer"


Full config — with gamma and min power

yaml
output:
  - platform: ac_dimmer
    id: dimmer_out
    gate_pin: GPIO4
    zero_cross_pin:
      number: GPIO5
      mode: INPUT
      inverted: yes
    method: leading_pulse
    min_power: 0.01          # minimum duty (1%) — avoids flicker at 0
light:
  - platform: monochromatic
    output: dimmer_out
    name: "Dimmer"
    gamma_correct: 0         # 0 = linear; 2.8 = human perception curve
    default_transition_length: 500ms


Dimming method options

yaml
method: leading_pulse   # Brief gate pulse — standard TRIAC (default)
method: leading         # Gate held until ZC — alternative TRIAC
method: trailing        # Gate pulled low at end — MOSFET only


ESP32 warning

⚠️ The standard ac_dimmer platform has two distinct problems on ESP32 hardware:

  • ESP32, ESP32-S3 — may flicker; ISR timing disrupted by WiFi
  • ESP32-S2, ESP32-C3, ESP32-H2, ESP32-C6 — not supported at all

Fix: Use Method 2 (DimmerLink) for any ESP32-based setup.

See: ESP32 + AC Dimmer: IRAM_ATTR Causes and Fix




Method 2: DimmerLink External Component

DimmerLink offloads zero-cross detection and TRIAC timing to a dedicated Cortex-M0+ controller. ESPHome sends brightness via I2C (register 0x10). No ISR runs on the MCU.

Docs: rbdimmer.com/docs/dimmerlink-esphome

Component source: github.com/robotdyn-dimmer/DimmerLink/tree/main/components


Wiring

text
DimmerLink   →   ESP32 (or any MCU)
──────────────────────────────────
VCC          →   3.3V
GND          →   GND
SDA          →   GPIO21
SCL          →   GPIO22


Minimal config (~30 lines)

yaml
esphome:
  name: dimmerlink
  platform: ESP32
  board: esp32dev
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
api:
  encryption:
    key: !secret api_key
ota:
  password: !secret ota_password
external_components:
  - source:
      type: git
      url: https://github.com/robotdyn-dimmer/DimmerLink
      ref: main
    components: [dimmerlink]
i2c:
  sda: GPIO21
  scl: GPIO22
  frequency: 100kHz
light:
  - platform: dimmerlink
    name: "Dimmer"
    address: 0x50


Standard config — with sensors and curve selector

yaml
# (external_components + i2c block as above)
light:
  - platform: dimmerlink
    name: "Dimmer"
    address: 0x50
sensor:
  - platform: dimmerlink
    address: 0x50
    frequency:
      name: "AC Frequency"
      unit_of_measurement: "Hz"
    brightness:
      name: "Dimmer Level"
      unit_of_measurement: "%"
select:
  - platform: dimmerlink
    address: 0x50
    dimming_curve:
      name: "Dimming Curve"
      # Options shown in HA dropdown: LINEAR, RMS, LOGARITHMIC
binary_sensor:
  - platform: dimmerlink
    address: 0x50
    status:
      name: "Dimmer Online"
button:
  - platform: dimmerlink
    address: 0x50
    reset:
      name: "Dimmer Reset"
    recalibrate:
      name: "Dimmer Recalibrate"


Extended config — all entities

yaml
# Full DimmerLink integration with diagnostics
sensor:
  - platform: dimmerlink
    address: 0x50
    frequency:
      name: "AC Frequency"
    brightness:
      name: "Dimmer Level"
text_sensor:
  - platform: dimmerlink
    address: 0x50
    firmware_version:
      name: "DimmerLink Firmware"
number:
  - platform: dimmerlink
    address: 0x50
    min_brightness:
      name: "Min Brightness"
      min_value: 0
      max_value: 20
select:
  - platform: dimmerlink
    address: 0x50
    dimming_curve:
      name: "Dimming Curve"
binary_sensor:
  - platform: dimmerlink
    address: 0x50
    status:
      name: "Dimmer OK"
    calibration_mode:
      name: "Calibration Active"
button:
  - platform: dimmerlink
    address: 0x50
    reset:
      name: "Reset"
    recalibrate:
      name: "Recalibrate"


Multi-device config

Multiple DimmerLink modules on one I2C bus (different addresses):

yaml
light:
  - platform: dimmerlink
    name: "Kitchen"
    address: 0x50
  - platform: dimmerlink
    name: "Bedroom"
    address: 0x51



Lambda Integration (Advanced)

For custom logic — for example, setting brightness from a physical button or a sensor reading — use ESPHome lambda functions with direct I2C register access.

Docs: rbdimmer.com/docs/dimmerlink-esphome/lambda-integration


DimmerLink I2C register map (key registers)

Register Address Description
STATUS 0x00 Status flags (read-only)
DIM0_LEVEL 0x10 Channel 0 brightness, 0–100
DIM0_CURVE 0x11 Curve: 0=LINEAR, 1=RMS, 2=LOG
AC_FREQ 0x20 Measured AC frequency (Hz)


Lambda example — set brightness directly

yaml
# Template output using lambda for custom brightness control
output:
  - platform: template
    id: dimmer_out
    type: float
    write_action:
      - lambda: |-
          uint8_t level = (uint8_t)(state * 100.0f);
          // requires i2c: block in your ESPHome config
          Wire.beginTransmission(0x50);
          Wire.write(0x10);   // DIM0_LEVEL register
          Wire.write(level);
          Wire.endTransmission();
light:
  - platform: monochromatic
    output: dimmer_out
    name: "Dimmer (lambda)"


Lambda example — button triggers preset

yaml
binary_sensor:
  - platform: gpio
    pin: GPIO0
    name: "Dim Button"
    on_press:
      - lambda: |-
          // Toggle between 30% and 80%
          static bool high = false;
          uint8_t level = high ? 30 : 80;
          high = !high;
          Wire.beginTransmission(0x50);
          Wire.write(0x10);
          Wire.write(level);
          Wire.endTransmission();



Dimming Curves

Curve Register value ESPHome dimming_curve Best for
Linear 0 LINEAR Heaters, resistive
RMS 1 RMS Incandescent, halogen
Logarithmic 2 LOGARITHMIC Dimmable LED bulbs

RMS and logarithmic curves compensate for the non-linear relationship between phase angle and perceived brightness.




Common Issues

Symptom Cause Fix
Flickering with ESP32 ISR/WiFi conflict Use DimmerLink method
Dimmer offline after OTA ISR preempted during flash Use DimmerLink
Brightness stuck at 0% min_power too low or ZC wiring Check ZC pin
HA light entity missing ESPHome not adopted in HA Re-adopt device
Component not found Wrong ref: in external_components Use ref: main



Related Articles



Still have questions?

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

Compartir esta publicación
Iniciar sesión para dejar un comentario