In breve: Installa
rbdimmerESP32(per ESP32) oRBDdimmer(per ESP8266) piùPubSubClient. Connettiti al tuo broker MQTT, sottoscrivi un topic di luminosità e chiamarbdimmer_set_level()nel callback. Ripubblica il livello attuale come topic di stato.
Come funziona
ESP32 ──WiFi──► Broker MQTT ◄────── Home Assistant / Node-RED
│ │
│ sottoscrizione: dimmer/level/set
│ pubblicazione: dimmer/level/state
│
└──ISR──► Gate TRIAC ──► Carico (lampada, riscaldatore…)L'ESP32 sottoscrive un topic di comando. Quando HA pubblica un valore (0–100), il callback lo applica al dimmer. L'ESP32 pubblica anche il suo livello attuale per mantenere HA sincronizzato.
Hardware
| Componente | Esempio |
|---|---|
| MCU | ESP32 (dual-core) o ESP8266 |
| Dimmer | Qualsiasi modulo rbdimmer 1CH/2CH/4CH |
| Pin ZC | GPIO 5 (qualsiasi GPIO su ESP32) |
| Pin DIM | GPIO 4 (qualsiasi GPIO su 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
Librerie necessarie
Installa tramite Arduino Library Manager o PlatformIO:
| Libreria | Scopo | Scheda |
|---|---|---|
rbdimmerESP32 |
Controllo ISR del dimmer AC | Solo ESP32 |
RBDdimmer |
Controllo ISR del dimmer AC | Arduino, ESP8266 |
PubSubClient |
Client MQTT | Qualsiasi |
WiFi.h |
WiFi (integrata) | ESP32 |
ESP8266WiFi.h |
WiFi (integrata) | ESP8266 |
PlatformIO (platformio.ini):
lib_deps =
https://github.com/robotdyn-dimmer/rbdimmerESP32
knolleary/PubSubClient @ ^2.8Codice 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();
}Codice completo — ESP8266
Per ESP8266, sostituisci la libreria e l'header WiFi. La logica MQTT è identica.
// Dimmer AC + MQTT su 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();
}Struttura dei topic MQTT
| Topic | Direzione | Valore | Esempio |
|---|---|---|---|
dimmer/level/set |
→ ESP32 | 0–100 |
75 |
dimmer/level/state |
← ESP32 | 0–100 |
75 |
Per più dimmer, usa prefissi di topic unici per dispositivo:
dimmer/kitchen/level/set
dimmer/bedroom/level/setConfigurazione Home Assistant
Aggiungi un light MQTT in 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"— quando accendi la luce da HA, viene inviato il valore di luminosità come payload MQTT (ad es.75) anziché la stringa"ON". Il firmware riceve direttamente un numero e lo applica al dimmer.
Dopo l'aggiunta, riavvia HA. Il dimmer appare come entità luce dimmerabile con uno slider di luminosità 0–100 %.
MQTT multicanale
Per moduli 2CH o 4CH, crea coppie di topic e descrittori di canale aggiuntivi. Ogni canale ottiene la sua coppia sottoscrizione/pubblicazione:
// Canale aggiuntivo
rbdimmer_channel_t ch2;
const char* TOPIC_SET2 = "dimmer/ch2/level/set";
const char* TOPIC_STATE2 = "dimmer/ch2/level/state";
// In onMessage(): verificare il topic, indirizzare al canale corretto
if (strcmp(topic, TOPIC_SET) == 0) {
rbdimmer_set_level(dimmerCh, level);
} else if (strcmp(topic, TOPIC_SET2) == 0) {
rbdimmer_set_level(ch2, level);
}Articoli correlati
- 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
Hai ancora domande?
Ask on forum.rbdimmer.com or open a GitHub Issue.