Kurzfassung:
rbdimmerESP32ist für Dual-Core ESP32 konzipiert (Original und S3). ESP32-S2, C3, C6 und H2 sind Single-Core. Die Bibliothek versucht, die Dimmer-Aufgabe auf einem dedizierten Kern zu isolieren — was auf Single-Core-Chips unmöglich ist. Die ISR konkurriert mit dem WiFi-Stack, das Timing wird gestört, und das Ergebnis ist Flackern, zufällige Störungen und instabile Helligkeit. Die Lösung ist DimmerLink (Hardware-ZC + I2C) oder der Wechsel zu einem Dual-Core-Chip.
Problembeschreibung
Sie haben einen ESP32-C3 oder ESP32-S2 gekauft — kompakt, WiFi/BLE-fähig, günstig.
Sie schließen einen AC-Dimmer direkt an, verwenden rbdimmerESP32 — und sehen:
- Die Last flackert bei jeder Helligkeitsstufe
- Das Timing ist instabil —
setPower(50)ergibt mal 30%, mal 70% - Störungen bei aktivem WiFi — ohne WiFi besser, mit WiFi chaotisch
- Code kompiliert fehlerfrei, Instabilität nur zur Laufzeit
Oder der Compiler warnt über xTaskCreatePinnedToCore mit einem nicht existierenden Kern.
Typische Forenbeiträge:
- „ESP32-C3 + Dimmer — Flackern bei jeder Leistungsstufe"
- „rbdimmerESP32 funktioniert auf ESP32, aber nicht auf ESP32-S2"
- „setPower(50) ergibt zufällige Helligkeit auf C3"
- „Funktioniert ohne WiFi einwandfrei, bricht zusammen, sobald WiFi verbindet"
Grundursache
Welche ESP32-Chips sind Dual-Core und welche nicht
| Chip | Kerne | Architektur | Direktes ISR-Dimming |
|---|---|---|---|
| ESP32 (Original) | 2 | Xtensa LX6 | ✅ rbdimmerESP32 |
| ESP32-S3 | 2 | Xtensa LX7 | ✅ rbdimmerESP32 |
| ESP32-S2 | 1 | Xtensa LX7 | ⚠️ Nur DimmerLink |
| ESP32-C3 | 1 | RISC-V | ⚠️ Nur DimmerLink |
| ESP32-C6 | 1 | RISC-V | ⚠️ Nur DimmerLink |
| ESP32-H2 | 1 | RISC-V | ⚠️ Nur DimmerLink |
⚠️ Hinweis zu ESP32-C6: C6 hat einen zusätzlichen LP-Kern (Low Power), aber er eignet sich nicht für ISR-Dimming — er läuft mit reduzierter Taktfrequenz ohne volle FreeRTOS-Unterstützung. Der Hauptkern ist Single-Core.
⚠️ Häufige Verwechslung: ESP32-S3 ist Dual-Core (funktioniert). ESP32-S2 ist Single-Core (funktioniert nicht mit direkter ISR). Das sind verschiedene Chips.
Warum Phasenanschnitt-Dimmung Kernisolierung erfordert
TRIAC-Gate-Timing: vom Nulldurchgang bis zum Gate-Impuls — eine Verzögerung von 100–9000 µs, Genauigkeit ±10–20 µs. Jede Abweichung bedeutet falsche Helligkeit.
rbdimmerESP32 erreicht diese Präzision auf Dual-Core folgendermaßen:
- Core 0 — Dimmer-Aufgabe (Timing-Schleife, ZC-Verarbeitung, TRIAC-Zündung)
- Core 1 — WiFi-Stack, TCP/IP, Benutzercode
Sie laufen parallel und blockieren sich nicht gegenseitig.
Auf Single-Core (C3, S2, H2) — beide Threads teilen sich einen Kern. Der WiFi-Stack blockiert die CPU regelmäßig für 1–5 ms zur Paketverarbeitung. Währenddessen verpasst die Dimmer-ISR ihr Zeitfenster → die Lampe flackert.
WiFi-DMA-Interrupts haben eine feste hohe Hardware-Priorität in ESP-IDF —
sie werden nicht durch IRAM_ATTR-ISR auf Benutzerebene auf Single-Core verdrängt.
portDISABLE_INTERRUPTS() hilft ebenfalls nicht: WiFi-DMA läuft auf NMI-Ebene.
Das lässt sich softwareseitig nicht lösen.
Lösungen
🟢 Für alle: DimmerLink — Hardwarelösung
Die einzige zuverlässige Lösung für Single-Core ESP32 mit WiFi. DimmerLink erkennt den Nulldurchgang und steuert den TRIAC selbst — Ihr MCU sendet nur die Helligkeitsstufe über I2C.
Jeder ESP32 has its own controller. Your ESP32-C3 only sets the brightness — no ISR, no timing-critical code on the MCU side.
Verdrahtung für ESP32-C3:
- VCC → 3.3V
- GND → GND
- SDA → GPIO 8 (Standard-SDA auf ESP32-C3)
- SCL → GPIO 9 (Standard-SCL auf ESP32-C3)
⚠️ Bei einigen ESP32-C3-Modulen werden GPIO 8/9 vom externen Flash genutzt. Wenn
Wire.begin()nicht funktioniert — geben Sie Pins explizit an:Wire.begin(SDA_PIN, SCL_PIN)mit freien GPIOs (z.B. 1, 10).
Verdrahtung für ESP32-S2:
- SDA → GPIO 3 (prüfen Sie die Pinbelegung Ihres Boards)
- SCL → GPIO 4
Code (identisch für alle Plattformen):
// DimmerLink auf ESP32-C3 / S2 / H2 — keine ISR auf dem MCU
// Stabiler Betrieb bei aktivem WiFi
#include <Wire.h>
#define DIMMER_ADDR 0x50
#define REG_LEVEL 0x10
void setLevel(uint8_t level) { // level: 0–100%
Wire.beginTransmission(DIMMER_ADDR);
Wire.write(REG_LEVEL);
Wire.write(level);
Wire.endTransmission();
}
void setup() {
Wire.begin(); // Standard-SDA/SCL für Ihr Board
setLevel(50); // 50% Helligkeit
}
void loop() {
// WiFi kann frei genutzt werden — der Dimmer wird nicht beeinflusst
}Ergebnis: Stabiler Betrieb mit WiFi/BLE auf jedem Single-Core ESP32.
🔵 Direkte ISR gewünscht — Wechsel zu einem Dual-Core ESP32
Benötigen Sie die direkte ISR-Architektur? Verwenden Sie den Original-ESP32 oder S3.
Der Original-ESP32 und ESP32-S3 sind Dual-Core, rbdimmerESP32 funktioniert normal:
// ESP32 Original / ESP32-S3 — Dual-Core
// rbdimmerESP32 funktioniert wie vorgesehen
#include "rbdimmerESP32.h"
#define ZC_PIN 18
#define DIM_PIN 19
rbdimmer dimmer;
void setup() {
Serial.begin(115200);
dimmer.begin(ZC_PIN, DIM_PIN, 50); // ZC_PIN, DIM_PIN, 50 Hz
dimmer.setPower(50);
}
void loop() {}Wann ein Chipwechsel sinnvoll ist:
the project
⚠️ Häufige Fallstricke
-
„Funktioniert ohne WiFi auf C3, flackert mit WiFi": Klassisches Symptom eines Single-Core-ISR-Konflikts. Gut dokumentiertes Verhalten. Lösung: DimmerLink.
-
„
rbdimmerESP32kompiliert auf C3 — sollte funktionieren": Es kompiliert, weil Core 0 auch auf Single-Core-Chips existiert.xTaskCreatePinnedToCore(..., 0)erstellt die Aufgabe, aber ohne Isolierung vom WiFi. Das Timing ist instabil — das ist kein „Funktionieren". -
„Verwende ESPHome / Tasmota auf ESP32-C3 — Dimmer funktioniert nicht": ESPHome und Tasmota auf Single-Core ESP32 haben dieselben Einschränkungen wie eigener Code. Der WiFi-Stack konkurriert mit der Dimmer-ISR. Verwenden Sie DimmerLink mit ESPHome über I2C (
i2c:+sensor:oder eincustom_component). -
„ESP32-S3 hat auch ein S — ist er auch Single-Core?": Nein. ESP32-S3 ist Dual-Core (wie der Original-ESP32, nur LX7). Er wird mit ESP32-S2 verwechselt. Prüfen Sie die Chipbeschriftung auf Ihrem Board.
-
„Ich verwende FreeRTOS manuell und kann Aufgaben selbst pinnen": Auf Single-Core erstellt
xTaskCreatePinnedToCore(..., 0)die Aufgabe, aber der WiFi-Stack ist ebenfalls auf Core 0. JedervTaskDelay(1)in der Dimmer-Aufgabe übergibt die CPU an WiFi — das Timing bricht zusammen. Und WiFi-DMA-Interrupts haben eine Hardware-Priorität über Benutzer-ISR. Das lässt sich softwareseitig nicht lösen. DimmerLink ist die einzige zuverlässige Lösung. -
"I'm using FreeRTOS manually and can pin tasks myself": On single-core
xTaskCreatePinnedToCore(..., 0)creates the task, but the WiFi stack is also on Core 0. AnyvTaskDelay(1)in the dimmer task yields the CPU to WiFi — timing breaks. And WiFi DMA interrupts have a hardware priority above user ISR. This can't be solved in software. DimmerLink is the only reliable solution.
Schnell-Check
Verwandte Probleme
- ESP32 + TRIAC: Guru Meditation Error →
troubleshooting/esp32-iram-attr.md - Nulldurchgang nicht erkannt →
troubleshooting/zero-cross-detection-errors.md - Zero-cross not detected →
troubleshooting/zero-cross-detection-errors.md
Noch Fragen?
Ask on forum.rbdimmer.com or open a GitHub Issue.