I searched but couldn’t find an answer for this specific case:
ESP32-S2 with rbdimmer 1CH module — dimmer completely unresponsive. No errors during compile or upload, but the lamp does not respond to any commands.
Environment:
- Board: ESP32-S2 (Wemos S2 Mini)
- Library: rbdimmerESP32 v1.2
- IDE: Arduino IDE 2.3.3
- Module: rbdimmer 1CH 4A
- Load: 40W incandescent bulb
- ZC pin: GPIO3, PSM pin: GPIO5
What I tried:
- Basic example sketch from library — compiles, uploads, no dimming
- Serial.println confirms setPower() values are sent — but no visible change on lamp
- Tested same module with standard ESP32 DevKit — works fine
- Swapped cables, tested different GPIOs — same result on S2
- No crash, no Guru Meditation, no errors in Serial Monitor
#include <rbdimmerESP32.h>
rbdimmer dimmer(5, 3);
void setup() {
Serial.begin(115200);
dimmer.begin(NORMAL_MODE, ON);
Serial.println("Dimmer initialized");
}
void loop() {
for (int i = 0; i <= 100; i += 10) {
dimmer.setPower(i);
Serial.println(i);
delay(1000);
}
}
Serial output shows values 0, 10, 20… correctly. Lamp stays off the entire time. Same code and module work on regular ESP32.
Any ideas?
Root cause: ESP32-S2 is a single-core chip.
The rbdimmerESP32 library pins its ISR handler and timing task to Core 0 via xTaskCreatePinnedToCore(), and expects your application loop to run on Core 1. On dual-core ESP32 (Xtensa LX6/LX7) this works because the two cores operate independently.
ESP32-S2 has only one core. The FreeRTOS scheduler cannot pin tasks to separate cores, so the library’s interrupt architecture silently fails — no crash, no error, just no TRIAC firing.
Affected chips (all single-core):
- ESP32-S2 (Xtensa LX7, single-core)
- ESP32-C3 (RISC-V, single-core)
- ESP32-H2 (RISC-V, single-core)
Supported chips:
- ESP32 (Xtensa LX6, dual-core)
- ESP32-S3 (Xtensa LX7, dual-core)
This explains why the same code works on your regular ESP32 DevKit but not on the S2. The library compiles for both targets because the FreeRTOS API is the same — it just doesn’t function correctly on single-core silicon.
If you must use ESP32-S2, look into the DimmerLink module — it offloads all phase-cut timing to a dedicated MCU and communicates via I2C. Your S2 only sends brightness commands over the bus.
Update after two weeks — DimmerLink module arrived today. Thank you Kai and rbdimmer team for the recommendation.
Tested with ESP32-S2 over I2C.
Result: works perfectly. Smooth dimming from 0% to 100%, no issues.
The I2C setup was straightforward — just Wire.begin() and the DimmerLink library handles everything else. Much simpler than the direct TRIAC approach actually.
One note for anyone finding this thread later: the DimmerLink default I2C address is 0x27. If you have other I2C devices on the same bus, check for address conflicts with Wire.beginTransmission() / Wire.endTransmission() scanner sketch.
[SOLVED] Root cause: ESP32-S2 is single-core — rbdimmerESP32 library requires dual-core ESP32.
Fix: use DimmerLink module (I2C) instead of direct TRIAC control.
Supported for rbdimmerESP32 library: ESP32 (dual-core), ESP32-S3 (dual-core).
Not supported: ESP32-S2, ESP32-C3, ESP32-H2 (all single-core).