En bref :
rbdimmerESP32est conçu pour les ESP32 double cœur (original et S3). Les ESP32-S2, C3, C6 et H2 sont simple cœur. La bibliothèque tente d'isoler la tâche du variateur sur un cœur dédié — ce qui est impossible sur les puces simple cœur. L'ISR entre en concurrence avec la pile WiFi, le timing est perturbé, et le résultat est un scintillement, des anomalies aléatoires et une luminosité instable. La solution est DimmerLink (ZC matériel + I2C) ou le passage à une puce double cœur.
Description du problème
Vous avez acheté un ESP32-C3 ou ESP32-S2 — compact, compatible WiFi/BLE, abordable.
Vous connectez un variateur AC directement, utilisez rbdimmerESP32 — et vous observez :
- La charge scintille à tout niveau de luminosité
- Le timing est instable —
setPower(50)donne 30 % un instant, 70 % le suivant - Anomalies avec le WiFi actif — fonctionne mieux sans WiFi, chaos avec
- Le code compile sans erreur, instabilité uniquement à l'exécution
Ou le compilateur avertit à propos de xTaskCreatePinnedToCore avec un cœur inexistant.
Messages typiques sur les forums :
- « ESP32-C3 + variateur — scintillement à tout niveau de puissance »
- « rbdimmerESP32 fonctionne sur ESP32 mais pas sur ESP32-S2 »
- « setPower(50) donne une luminosité aléatoire sur C3 »
- « Fonctionne sans WiFi, tout casse dès que le WiFi se connecte »
Cause profonde
Quels ESP32 sont double cœur et lesquels ne le sont pas
| Puce | Cœurs | Architecture | Variation ISR directe |
|---|---|---|---|
| ESP32 (original) | 2 | Xtensa LX6 | ✅ rbdimmerESP32 |
| ESP32-S3 | 2 | Xtensa LX7 | ✅ rbdimmerESP32 |
| ESP32-S2 | 1 | Xtensa LX7 | ⚠️ DimmerLink uniquement |
| ESP32-C3 | 1 | RISC-V | ⚠️ DimmerLink uniquement |
| ESP32-C6 | 1 | RISC-V | ⚠️ DimmerLink uniquement |
| ESP32-H2 | 1 | RISC-V | ⚠️ DimmerLink uniquement |
⚠️ Remarque sur l'ESP32-C6 : le C6 possède un cœur LP supplémentaire (Low Power), mais il n'est pas adapté à la variation ISR — il fonctionne à une fréquence réduite sans support complet de FreeRTOS. Le cœur principal est unique.
⚠️ Confusion fréquente : l'ESP32-S3 est double cœur (fonctionne). L'ESP32-S2 est simple cœur (ne fonctionne pas avec l'ISR directe). Ce sont des puces différentes.
Pourquoi la variation par découpe de phase nécessite l'isolation des cœurs
Timing de la gâchette TRIAC : du passage par zéro à l'impulsion de gâchette — un délai de 100–9000 µs, précision ±10–20 µs. Tout retard signifie une luminosité incorrecte.
rbdimmerESP32 atteint cette précision sur double cœur ainsi :
- Cœur 0 — tâche du variateur (boucle de timing, traitement ZC, allumage TRIAC)
- Cœur 1 — pile WiFi, TCP/IP, code utilisateur
Ils fonctionnent en parallèle et ne se bloquent pas mutuellement.
Sur simple cœur (C3, S2, H2) — les deux threads partagent un seul cœur. La pile WiFi bloque régulièrement le CPU pendant 1–5 ms pour traiter les paquets. Pendant ce temps, l'ISR du variateur rate sa fenêtre de timing → la lampe scintille.
Les interruptions DMA WiFi ont une priorité matérielle haute fixe dans ESP-IDF —
elles ne sont pas préemptées par les ISR IRAM_ATTR de niveau utilisateur sur simple cœur.
portDISABLE_INTERRUPTS() n'aide pas non plus : le DMA WiFi fonctionne au niveau NMI.
Cela ne peut pas être résolu par logiciel.
Solutions
🟢 Pour tous : DimmerLink — solution matérielle
La seule solution fiable pour un ESP32 simple cœur avec WiFi. DimmerLink détecte le passage par zéro et contrôle le TRIAC lui-même — votre MCU envoie uniquement le niveau de luminosité via I2C.
❌ non supporté has its own controller. Your ESP32-C3 only sets the brightness — no ISR, no timing-critical code on the MCU side.
Câblage pour ESP32-C3 :
- VCC → 3.3V
- GND → GND
- SDA → GPIO 8 (SDA par défaut sur ESP32-C3)
- SCL → GPIO 9 (SCL par défaut sur ESP32-C3)
⚠️ Sur certains modules ESP32-C3, les GPIO 8/9 sont utilisés par la flash externe. Si
Wire.begin()ne fonctionne pas — spécifiez les broches explicitement :Wire.begin(SDA_PIN, SCL_PIN)avec des GPIO libres (ex. 1, 10).
Câblage pour ESP32-S2 :
- SDA → GPIO 3 (vérifiez le brochage de votre carte)
- SCL → GPIO 4
Code (identique pour toutes les plateformes) :
// DimmerLink sur ESP32-C3 / S2 / H2 — pas d'ISR sur le MCU
// Fonctionnement stable avec WiFi actif
#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(); // SDA/SCL par défaut pour votre carte
setLevel(50); // luminosité 50%
}
void loop() {
// Le WiFi peut être utilisé librement — le variateur n'est pas affecté
}Résultat : Fonctionnement stable avec WiFi/BLE sur tout ESP32 simple cœur.
🔵 Vous voulez l'ISR directe — passez à un ESP32 double cœur
Besoin de l'architecture ISR directe ? Utilisez l'ESP32 original ou le S3.
L'ESP32 original et l'ESP32-S3 sont double cœur, rbdimmerESP32 fonctionne normalement :
// ESP32 original / ESP32-S3 — double cœur
// rbdimmerESP32 fonctionne comme prévu
#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() {}Quand changer de puce :
the project
⚠️ Pièges courants
-
« Fonctionne sans WiFi sur C3, scintille avec WiFi » : Symptôme classique d'un conflit ISR simple cœur. Comportement bien documenté. Solution : DimmerLink.
-
«
rbdimmerESP32compile sur C3 — ça devrait marcher » : Ça compile parce que le cœur 0 existe même sur les puces simple cœur.xTaskCreatePinnedToCore(..., 0)créera la tâche, mais sans isolation du WiFi. Le timing est instable — ce n'est pas « fonctionner ». -
« J'utilise ESPHome / Tasmota sur ESP32-C3 — le variateur ne fonctionne pas » : ESPHome et Tasmota sur ESP32 simple cœur ont les mêmes limitations que le code personnalisé. La pile WiFi est en concurrence avec l'ISR du variateur. Utilisez DimmerLink avec ESPHome via I2C (
i2c:+sensor:ou uncustom_component). -
« L'ESP32-S3 a aussi un S — est-il simple cœur aussi ? » : Non. L'ESP32-S3 est double cœur (comme l'ESP32 original, en LX7). On le confond avec l'ESP32-S2. Vérifiez le marquage de la puce sur votre carte.
-
« J'utilise FreeRTOS manuellement et je peux assigner les tâches moi-même » : Sur simple cœur,
xTaskCreatePinnedToCore(..., 0)crée la tâche, mais la pile WiFi est aussi sur le cœur 0. ToutvTaskDelay(1)dans la tâche du variateur cède le CPU au WiFi — le timing est rompu. Et les interruptions DMA WiFi ont une priorité matérielle supérieure aux ISR utilisateur. Cela ne peut pas être résolu par logiciel. DimmerLink est la seule solution fiable. -
"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.
Vérification rapide
Problèmes connexes
- ESP32 + TRIAC : Guru Meditation Error →
troubleshooting/esp32-iram-attr.md - Passage par zéro non détecté →
troubleshooting/zero-cross-detection-errors.md - Zero-cross not detected →
troubleshooting/zero-cross-detection-errors.md
Encore des questions ?
Ask on forum.rbdimmer.com or open a GitHub Issue.