Resumen: Instala
rbdimmerESP32(para ESP32) oRBDdimmer(para ESP8266) másPubSubClient. Conéctate a tu broker MQTT, suscríbete a un topic de brillo y llama arbdimmer_set_level()en el callback. Publica de vuelta el nivel actual como topic de estado.
Cómo funciona
ESP32 ──WiFi──► Broker MQTT ◄────── Home Assistant / Node-RED
│ │
│ suscripción: dimmer/level/set
│ publicación: dimmer/level/state
│
└──ISR──► Gate TRIAC ──► Carga (lámpara, calefactor…)El ESP32 se suscribe a un topic de comando. Cuando HA publica un valor (0–100), el callback lo aplica al dimmer. El ESP32 también publica su nivel actual para que HA se mantenga sincronizado.
Hardware
| Componente | Ejemplo |
|---|---|
| MCU | ESP32 (doble núcleo) o ESP8266 |
| Dimmer | Cualquier módulo rbdimmer 1CH/2CH/4CH |
| Pin ZC | GPIO 5 (cualquier GPIO en ESP32) |
| Pin DIM | GPIO 4 (cualquier GPIO en ESP32) |
| VCC | 3,3V |
⚠️ Use
rbdimmerESP32on dual-core ESP32. The olderRBDdimmerlibrary has noIRAM_ATTRon its ISR — it crashes when WiFi is active.rbdimmerESP32pins the ISR to Core 0; WiFi runs on Core 1. See: Wrong Library: RBDdimmer vs rbdimmerESP32
Bibliotecas necesarias
Instala mediante Arduino Library Manager o PlatformIO:
| Biblioteca | Propósito | Placa |
|---|---|---|
rbdimmerESP32 |
Control ISR del dimmer AC | Solo ESP32 |
RBDdimmer |
Control ISR del dimmer AC | Arduino, ESP8266 |
PubSubClient |
Cliente MQTT | Cualquiera |
WiFi.h |
WiFi (integrada) | ❌ no |
ESP8266WiFi.h |
WiFi (integrada) | ESP8266 |
PlatformIO (platformio.ini):
lib_deps =
https://github.com/robotdyn-dimmer/rbdimmerESP32
knolleary/PubSubClient @ ^2.8Código completo — ESP32
// AC Dimmer + MQTT on ESP32 (dual-core)
// Library: rbdimmerESP32 + PubSubClient
// IMPORTANT: use rbdimmerESP32, NOT RBDdimmer, on ESP32
#include <WiFi.h>
#include <PubSubClient.h>
#include "rbdimmerESP32.h"
// ── Configuration ─────────────────────────────────────────────
const char* WIFI_SSID = "YourSSID";
const char* WIFI_PASS = "YourPassword";
const char* MQTT_SERVER = "192.168.1.100"; // broker IP
const int MQTT_PORT = 1883;
const char* DEVICE_ID = "dimmer_esp32_01"; // unique per device
// MQTT topics
const char* TOPIC_SET = "dimmer/level/set"; // receive command
const char* TOPIC_STATE = "dimmer/level/state"; // publish state
// Dimmer pins
#define ZC_PIN 5
#define DIM_PIN 4
// ── Globals ───────────────────────────────────────────────────
WiFiClient wifiClient;
PubSubClient mqtt(wifiClient);
rbdimmer_channel_t dimmerCh;
int currentLevel = 0;
// ── MQTT callback ─────────────────────────────────────────────
void onMessage(char* topic, byte* payload, unsigned int length) {
char buf[8];
int len = min((int)length, 7);
memcpy(buf, payload, len);
buf[len] = '\0';
int level = atoi(buf);
level = constrain(level, 0, 100);
rbdimmer_set_level(dimmerCh, level);
currentLevel = level;
// Publish confirmed state
char stateStr[8];
itoa(level, stateStr, 10);
mqtt.publish(TOPIC_STATE, stateStr, true); // retained
}
// ── MQTT reconnect ────────────────────────────────────────────
void mqttReconnect() {
while (!mqtt.connected()) {
Serial.print("Connecting to MQTT…");
if (mqtt.connect(DEVICE_ID)) {
Serial.println(" connected.");
mqtt.subscribe(TOPIC_SET);
// Republish retained state on reconnect
char stateStr[8];
itoa(currentLevel, stateStr, 10);
mqtt.publish(TOPIC_STATE, stateStr, true);
} else {
Serial.print(" failed, rc=");
Serial.println(mqtt.state());
delay(5000);
}
}
}
// ── Setup ─────────────────────────────────────────────────────
void setup() {
Serial.begin(115200);
// Connect WiFi
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print(".");
}
Serial.println("\nWiFi connected: " + WiFi.localIP().toString());
// Init dimmer
rbdimmer_init();
rbdimmer_register_zero_cross(ZC_PIN, RBDIMMER_PHASE_DEFAULT);
rbdimmer_config_t cfg = {
.gpio_pin = DIM_PIN,
.phase = RBDIMMER_PHASE_DEFAULT,
.initial_level = 0,
.curve_type = RBDIMMER_CURVE_RMS
};
rbdimmer_create_channel(&cfg, &dimmerCh);
// Setup MQTT
mqtt.setServer(MQTT_SERVER, MQTT_PORT);
mqtt.setCallback(onMessage);
}
// ── Loop ──────────────────────────────────────────────────────
void loop() {
if (!mqtt.connected()) mqttReconnect();
mqtt.loop();
}Código completo — ESP8266
Para ESP8266, cambia la biblioteca y el encabezado WiFi. La lógica MQTT es idéntica.
// Dimmer AC + MQTT en ESP8266 — sketch completo
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <RBDdimmer.h>
const char* WIFI_SSID = "YourSSID";
const char* WIFI_PASS = "YourPassword";
const char* MQTT_SERVER = "192.168.1.100";
const int MQTT_PORT = 1883;
const char* DEVICE_ID = "dimmer_esp8266_01";
const char* TOPIC_SET = "dimmer/level/set";
const char* TOPIC_STATE = "dimmer/level/state";
#define ZC_PIN 5 // D1 (NodeMCU)
#define DIM_PIN 4 // D2
WiFiClient wifiClient;
PubSubClient mqtt(wifiClient);
dimmerLamp dimmer(DIM_PIN, ZC_PIN);
int currentLevel = 0;
void onMessage(char* topic, byte* payload, unsigned int length) {
char buf[8];
int len = min((int)length, 7);
memcpy(buf, payload, len);
buf[len] = '\0';
int level = constrain(atoi(buf), 0, 100);
dimmer.setPower(level);
currentLevel = level;
char stateStr[8];
itoa(level, stateStr, 10);
mqtt.publish(TOPIC_STATE, stateStr, true);
}
void mqttReconnect() {
while (!mqtt.connected()) {
if (mqtt.connect(DEVICE_ID)) {
mqtt.subscribe(TOPIC_SET);
} else {
delay(5000);
}
}
}
void setup() {
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
dimmer.begin(NORMAL_MODE, ON);
dimmer.setPower(0);
mqtt.setServer(MQTT_SERVER, MQTT_PORT);
mqtt.setCallback(onMessage);
}
void loop() {
if (!mqtt.connected()) mqttReconnect();
mqtt.loop();
}Estructura de topics MQTT
| Topic | Dirección | Valor | Ejemplo |
|---|---|---|---|
dimmer/level/set |
→ ESP32 | 0–100 |
75 |
dimmer/level/state |
← ESP32 | 0–100 |
75 |
Para múltiples dimmers, usa prefijos de topics únicos por dispositivo:
dimmer/kitchen/level/set
dimmer/bedroom/level/setConfiguración de Home Assistant
Añade un light MQTT en configuration.yaml (o usa MQTT Discovery):
mqtt:
light:
- name: "Living Room Dimmer"
unique_id: "dimmer_esp32_01"
command_topic: "dimmer/level/set"
state_topic: "dimmer/level/state"
brightness_command_topic: "dimmer/level/set"
brightness_state_topic: "dimmer/level/state"
brightness_scale: 100
on_command_type: "brightness"
retain: true
optimistic: false
on_command_type: "brightness"— cuando enciendes la luz desde HA, se envía el valor de brillo como payload MQTT (por ejemplo,75) en lugar de la cadena"ON". El firmware recibe un número directamente y lo aplica al dimmer.
Después de añadir, reinicia HA. El dimmer aparece como una entidad de luz regulable con un deslizador de brillo de 0–100 %.
MQTT multicanal
Para módulos 2CH o 4CH, crea pares de topics y descriptores de canal adicionales. Cada canal obtiene su propio par de suscripción/publicación:
// Canal adicional
rbdimmer_channel_t ch2;
const char* TOPIC_SET2 = "dimmer/ch2/level/set";
const char* TOPIC_STATE2 = "dimmer/ch2/level/state";
// En onMessage(): verificar topic, dirigir al canal correcto
if (strcmp(topic, TOPIC_SET) == 0) {
rbdimmer_set_level(dimmerCh, level);
} else if (strcmp(topic, TOPIC_SET2) == 0) {
rbdimmer_set_level(ch2, level);
}Artículos relacionados
- Wrong library on ESP32 → RBDdimmer vs rbdimmerESP32
- ESP32 crashes with WiFi → IRAM_ATTR Causes and Fix
- Single-core ESP32 → ESP32-S2/C3/H2 Doesn't Work
- ESPHome instead of MQTT → ESPHome YAML for AC Dimmer
- Which dimmer module → Complete Buyer's Guide
¿Todavía tienes preguntas?
Ask on forum.rbdimmer.com or open a GitHub Issue.