Se rendre au contenu

Guide de dépannage rbdimmerESP32

Mise à jour pour v2.0.0 -- inclut des corrections pour quatre problèmes de scintillement découverts lors de la validation du matériel 4 canaux.

Liste de vérification diagnostique rapide

Avant de plonger dans le dépannage détaillé, examinez cette liste de vérification rapide :

Vérification système de base

  • Carte ESP32 sélectionnée correctement dans l'IDE
  • ESP-IDF 5.3 ou ultérieur (si vous utilisez le framework ESP-IDF)
  • Bibliothèque correctement installée et incluse
  • Toutes les connexions de câblage sécurisées
  • Alimentation électrique adéquate (3,3V, >500mA)
  • Module de variation de lumière alimenté et opérationnel
  • Charge CA compatible avec la gradation
  • Procédures de sécurité respectées
  • Code de test rapide

    Exécutez ce test minimal pour vérifier les fonctionnalités de base :

    cpp
    #include 
    void setup() {
        Serial.begin(115200);
        delay(2000);
        Serial.println("=== RBDimmer Quick Diagnostic ===");
        // Test 1: Library initialization
        rbdimmer_err_t err = rbdimmer_init();
        Serial.printf("1. Library Init: %s (%d)\n",
                      (err == RBDIMMER_OK) ? "OK" : "FAILED", err);
        // Test 2: Zero-cross registration
        err = rbdimmer_register_zero_cross(2, 0, 50);
        Serial.printf("2. Zero-Cross Registration: %s (%d)\n",
                      (err == RBDIMMER_OK) ? "OK" : "FAILED", err);
        // Test 3: Channel creation
        rbdimmer_channel_t* channel;
        rbdimmer_config_t config = {4, 0, 0, RBDIMMER_CURVE_LINEAR};
        err = rbdimmer_create_channel(&config, &channel);
        Serial.printf("3. Channel Creation: %s (%d)\n",
                      (err == RBDIMMER_OK) ? "OK" : "FAILED", err);
        if (err == RBDIMMER_OK) {
            Serial.println("Basic functionality working");
            Serial.println("Check hardware connections for full operation");
        } else {
            Serial.println("Basic functionality failed");
            Serial.println("Check installation and wiring");
        }
    }
    void loop() {
        delay(1000);
    }

    Problèmes de compilation

    Problème : Bibliothèque introuvable

    Messages d'erreur :

    plaintext
    fatal error: rbdimmerESP32.h: No such file or directory

    Solutions :

    Arduino IDE

    1. Vérifier l'installation : - Vérifiez Fichier -> Exemples -> rbdimmerESP32 - Si non visible, la bibliothèque n'est pas correctement installée

    2. Réinstaller la bibliothèque : Sketch -> Include Library -> Manage Libraries Search "rbdimmerESP32" -> Install

    3. Vérification manuelle de l'installation : - La bibliothèque doit être dans : ~/Documents/Arduino/libraries/rbdimmerESP32/ - Assurez-vous que rbdimmerESP32.h est dans le dossier src/

    Problème : Erreurs de compilation

    Messages d'erreur :

    plaintext
    error: 'micros' was not declared in this scope
    error: 'digitalRead' was not declared in this scope

    Solutions :

    1. Vérifier la sélection de la carte : - Doit être du type de carte ESP32 - Arduino IDE : Outils -> Carte -> ESP32

    2. Update ESP32 Core: - Arduino IDE: Tools -> Board -> Boards Manager - Search "ESP32" -> Update to latest version - ESP-IDF users: v5.3 or later required

    3. Vérifier le framework :

    Messages d'erreur :

    plaintext
    error: conflicting declaration of C function

    Solutions :

    1. Vérifier les inclusions multiples : - Incluez rbdimmerESP32.h une seule fois par fichier - Vérifiez les conflits avec d'autres bibliothèques de variation de lumière

    2. Reconstruction propre : - Supprimez le dossier de compilation et recompiler

    Problème : Erreurs de l'éditeur de liens

    Messages d'erreur :

    plaintext
    undefined reference to `rbdimmer_init'

    Solutions :

    1. Configuration du composant ESP-IDF : cmake # In main/CMakeLists.txt idf_component_register( SRCS "main.c" INCLUDE_DIRS "." REQUIRES rbdimmerESP32 )

    La bibliothèque utilise une architecture modulaire avec son propre fichier Kconfig. ESP-IDF récupérera automatiquement les options Kconfig lorsque le composant est enregistré correctement.

    Problème : L'initialisation de la bibliothèque échoue

    Symptoms: - rbdimmer_init() returns non-zero error code - System doesn't respond to commands

    Code de diagnostic :

    cpp
    void diagnose_init() {
        Serial.println("Diagnosing initialization...");
        rbdimmer_err_t err = rbdimmer_init();
        switch(err) {
            case RBDIMMER_OK:
                Serial.println("Initialization successful");
                break;
            case RBDIMMER_ERR_NO_MEMORY:
                Serial.println("Memory allocation failed");
                Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
                break;
            default:
                Serial.printf("Unknown error: %d\n", err);
        }
    }

    Solutions :

    1. Problèmes de mémoire : - Vérifiez la mémoire de tas disponible - Réduisez l'utilisation de mémoire par ailleurs - Augmentez la taille du tas si possible

    2. Initialisations multiples : - Appelez rbdimmer_init() une seule fois - Vérifiez les appels en double

    Problème : L'enregistrement de la détection de passage par zéro échoue

    Codes d'erreur et solutions :

    RBDIMMER_ERR_INVALID_ARG

    cpp
    // Check pin number validity
    void check_pin_validity() {
        uint8_t test_pin = 2;
        if (test_pin >= GPIO_NUM_MAX) {
            Serial.printf("Invalid pin number: %d\n", test_pin);
        }
        // Check if pin is available
        if (test_pin == 0 || test_pin == 1 || test_pin == 3) {
            Serial.println("Warning: Using boot/serial pin");
        }
    }

    Solutions : - Utilisez les broches GPIO 2, 4, 5, 12-15, 25-27 - Évitez les broches 0, 1, 3 (démarrage/série) - Évitez les broches 6-11 (mémoire flash)

    RBDIMMER_ERR_ALREADY_EXIST

    cpp
    // Check for duplicate phase registration
    for(int phase = 0; phase < 4; phase++) {
        rbdimmer_err_t err = rbdimmer_register_zero_cross(2+phase, phase, 0);
        if (err == RBDIMMER_ERR_ALREADY_EXIST) {
            Serial.printf("Phase %d already registered\n", phase);
        }
    }

    Solutions : - Vérifiez les appels en double rbdimmer_register_zero_cross() - Utilisez rbdimmer_deinit() pour réinitialiser si nécessaire

    Problème : La création du canal échoue

    Code de diagnostic :

    cpp
    void diagnose_channel_creation() {
        rbdimmer_config_t config = {4, 0, 0, RBDIMMER_CURVE_LINEAR};
        rbdimmer_channel_t* channel;
        rbdimmer_err_t err = rbdimmer_create_channel(&config, &channel);
        switch(err) {
            case RBDIMMER_OK:
                Serial.println("Channel created successfully");
                break;
            case RBDIMMER_ERR_NOT_FOUND:
                Serial.printf("Phase %d not registered\n", config.phase);
                break;
            case RBDIMMER_ERR_NO_MEMORY:
                Serial.println("No memory or max channels reached");
                Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
                break;
            case RBDIMMER_ERR_GPIO_FAILED:
                Serial.printf("GPIO %d configuration failed\n", config.gpio_pin);
                break;
            case RBDIMMER_ERR_TIMER_FAILED:
                Serial.println("Timer allocation failed");
                break;
            default:
                Serial.printf("Unknown error: %d\n", err);
        }
    }

    Solutions :

    1. Phase non enregistrée : - Enregistrez d'abord le détecteur de passage par zéro - Vérifiez que le numéro de phase correspond

    2. Problèmes de mémoire : - Maximum 8 canaux supportés - Chaque canal utilise ~200 octets de RAM - Libérez de la mémoire si nécessaire

    3. Problèmes GPIO : - Essayez une broche GPIO différente - Vérifiez les conflits de broche avec d'autres codes

    Problèmes de connexion matérielle

    Problème : Aucune détection de passage par zéro

    Symptômes : - rbdimmer_get_frequency() retourne 0 - Aucune réaction de gradation

    Code de diagnostic :

    cpp
    void diagnose_zero_cross() {
        Serial.println("Zero-cross diagnostic starting...");
        // Test 1: Pin state monitoring
        pinMode(2, INPUT);
        Serial.println("Monitoring zero-cross pin for 10 seconds...");
        int high_count = 0, low_count = 0;
        unsigned long start_time = millis();
        while(millis() - start_time < 10000) {
            if(digitalRead(2)) {
                high_count++;
            } else {
                low_count++;
            }
            delayMicroseconds(100);
        }
        Serial.printf("High readings: %d, Low readings: %d\n", high_count, low_count);
        if(high_count == 0) {
            Serial.println("Pin always LOW - check connections");
        } else if(low_count == 0) {
            Serial.println("Pin always HIGH - check connections");
        } else {
            Serial.println("Pin changing states - wiring OK");
        }
        // Test 2: Frequency measurement
        rbdimmer_init();
        rbdimmer_register_zero_cross(2, 0, 0);
        Serial.println("Measuring frequency for 30 seconds...");
        for(int i = 0; i < 30; i++) {
            delay(1000);
            uint16_t freq = rbdimmer_get_frequency(0);
            Serial.printf("Frequency: %d Hz\n", freq);
            if(freq > 0) {
                Serial.println("Frequency detected successfully");
                break;
            }
        }
    }

    Solutions :

    1. Vérifier les connexions physiques : - Vérifiez la connexion de la broche de sortie de passage par zéro - Vérifiez la connexion de masse entre l'ESP32 et le module de variation de lumière - Assurez-vous que le module de variation de lumière est alimenté

    2. Test du module de variation de lumière : - Utilisez un multimètre pour vérifier la sortie de passage par zéro (tension CC) - Devrait afficher ~3,3V impulsions à la fréquence du réseau - Si aucun signal, le module de variation de lumière peut être défectueux

    3. Essayer une broche différente : cpp // Test different GPIO pins uint8_t test_pins[] = {2, 4, 5, 12, 13, 14, 15}; for(int i = 0; i < sizeof(test_pins); i++) { Serial.printf("Testing pin %d\n", test_pins[i]); // Test each pin... }

    Problème : Le TRIAC ne bascule pas

    Symptoms: - Load doesn't respond to dimming commands - Always full on or full off

    Code de diagnostic :

    cpp
    void diagnose_triac_control() {
        Serial.println("TRIAC control diagnostic...");
        // Test 1: GPIO output test
        pinMode(4, OUTPUT);
        Serial.println("Manual GPIO test - watch for LED/scope");
        for(int i = 0; i < 10; i++) {
            digitalWrite(4, HIGH);
            Serial.println("GPIO HIGH");
            delay(500);
            digitalWrite(4, LOW);
            Serial.println("GPIO LOW");
            delay(500);
        }
        // Test 2: Library control test
        rbdimmer_init();
        rbdimmer_register_zero_cross(2, 0, 50); // Fixed frequency for test
        rbdimmer_config_t config = {4, 0, 0, RBDIMMER_CURVE_LINEAR};
        rbdimmer_channel_t* channel;
        rbdimmer_create_channel(&config, &channel);
        Serial.println("Testing dimmer levels...");
        for(int level = 0; level <= 100; level += 25) {
            rbdimmer_set_level(channel, level);
            Serial.printf("Level: %d%%, Delay: %d us\n",
                          level, rbdimmer_get_delay(channel));
            delay(2000);
        }
    }

    Solutions :

    1. Vérifier la connexion de commande de porte : - Vérifiez la broche GPIO vers l'entrée de porte du variateur - Assurez-vous de la polarité correcte - Vérifiez les connexions desserrées

    2. Test avec indicateur LED : cpp // Add LED to gate control pin pinMode(4, OUTPUT); // LED should pulse with dimming

    3. Problèmes du module de variation de lumière : - Vérifiez l'alimentation du module - Vérifiez que le module est conçu pour la logique 3,3V - Testez avec un module de variation de lumière différent

    Problème : Comportement de gradation erratique

    Symptômes : - Niveaux de luminosité incohérents - Scintillement ou saut - Basculement aléatoire marche/arrêt

    Code de diagnostic :

    cpp
    void diagnose_stability() {
        Serial.println("Stability diagnostic...");
        rbdimmer_init();
        rbdimmer_register_zero_cross(2, 0, 0);
        rbdimmer_config_t config = {4, 0, 50, RBDIMMER_CURVE_RMS};
        rbdimmer_channel_t* channel;
        rbdimmer_create_channel(&config, &channel);
        // Monitor frequency stability
        Serial.println("Monitoring frequency stability...");
        uint16_t freq_readings[60];
        for(int i = 0; i < 60; i++) {
            delay(1000);
            freq_readings[i] = rbdimmer_get_frequency(0);
            Serial.printf("Freq[%d]: %d Hz\n", i, freq_readings[i]);
        }
        // Analyze stability
        uint16_t min_freq = 1000, max_freq = 0;
        for(int i = 0; i < 60; i++) {
            if(freq_readings[i] > 0) {
                if(freq_readings[i] < min_freq) min_freq = freq_readings[i];
                if(freq_readings[i] > max_freq) max_freq = freq_readings[i];
            }
        }
        Serial.printf("Frequency range: %d - %d Hz\n", min_freq, max_freq);
        if(max_freq - min_freq > 2) {
            Serial.println("Frequency unstable - check power quality");
        } else {
            Serial.println("Frequency stable");
        }
    }

    Solutions :

    1. Problèmes d'alimentation : - Vérifiez la stabilité de l'alimentation ESP32 - Utilisez un adaptateur secteur de qualité (>500mA) - Ajoutez des condensateurs de filtrage à l'alimentation

    2. Interférences électriques : - Séparez le câblage basse tension et CA - Ajoutez des noyaux de ferrite sur les câbles - Utilisez des câbles blindés si nécessaire

    3. Problèmes de charge : - Testez avec un type de charge différent - Vérifiez la compatibilité de la charge - Vérifiez que le courant de charge est dans les limites du variateur

    4. Bruit de passage par zéro (v2.0.0) : - Voir la section Problèmes de gradation et de scintillement ci-dessous pour le réglage du filtre anti-rebond ZC

    Problèmes de performance

    Problème : Imprécision de la synchronisation

    Symptoms: - Dimming levels don't match expected brightness - Timing measurements show variations

    Code de diagnostic :

    cpp
    void diagnose_timing() {
        Serial.println("Timing accuracy diagnostic...");
        rbdimmer_init();
        rbdimmer_register_zero_cross(2, 0, 50);
        rbdimmer_config_t config = {4, 0, 0, RBDIMMER_CURVE_LINEAR};
        rbdimmer_channel_t* channel;
        rbdimmer_create_channel(&config, &channel);
        // Test timing at different levels
        for(int level = 10; level <= 90; level += 10) {
            rbdimmer_set_level(channel, level);
            uint32_t delay_us = rbdimmer_get_delay(channel);
            uint16_t freq = rbdimmer_get_frequency(0);
            uint32_t half_cycle_us = 1000000 / (2 * freq);
            Serial.printf("Level: %d%%, Delay: %d us, Half-cycle: %d us, Ratio: %.1f%%\n",
                          level, delay_us, half_cycle_us,
                          (float)delay_us / half_cycle_us * 100.0);
            delay(1000);
        }
    }

    Solutions :

    1. Vérifier la charge système : ```cpp void check_system_load() { unsigned long start = millis(); // Run normal operations for 10 seconds while(millis() - start < 10000) { // Your normal loop code here delay(10); }

      unsigned long actual_time = millis() - start; Serial.printf("Expected: 10000ms, Actual: %dms\n", actual_time); if(actual_time > 10100) { Serial.println("System overloaded - optimize code"); } } ```

    2. Optimiser la gestion des interruptions : - Maintenez le code ISR au minimum - Évitez Serial.print() dans les rappels - Utilisez les files d'attente FreeRTOS pour le transfert de données

    3. Vérifier l'horloge CPU : cpp void check_cpu_clock() { Serial.printf("CPU Frequency: %d MHz\n", ESP.getCpuFreqMHz()); if(ESP.getCpuFreqMHz() < 240) { Serial.println("Consider increasing CPU frequency"); } }

    Problème : Problèmes de mémoire

    Symptômes : - Le système plante ou se réinitialise - La création du canal échoue - Comportement erratique

    Code de diagnostic :

    cpp
    void diagnose_memory() {
        Serial.println("Memory diagnostic...");
        Serial.printf("Free heap at start: %d bytes\n", ESP.getFreeHeap());
        Serial.printf("Minimum free heap: %d bytes\n", ESP.getMinFreeHeap());
        Serial.printf("Heap size: %d bytes\n", ESP.getHeapSize());
        rbdimmer_init();
        Serial.printf("After init: %d bytes\n", ESP.getFreeHeap());
        // Create maximum channels
        rbdimmer_register_zero_cross(2, 0, 50);
        rbdimmer_channel_t* channels[8];
        for(int i = 0; i < 8; i++) {
            rbdimmer_config_t config = {4+i, 0, 0, RBDIMMER_CURVE_LINEAR};
            rbdimmer_err_t err = rbdimmer_create_channel(&config, &channels[i]);
            if(err == RBDIMMER_OK) {
                Serial.printf("Channel %d created, Free heap: %d bytes\n",
                              i, ESP.getFreeHeap());
            } else {
                Serial.printf("Channel %d failed: %d\n", i, err);
                break;
            }
        }
        if(ESP.getFreeHeap() < 10000) {
            Serial.println("WARNING: Low memory");
        }
    }

    Solutions :

    1. Réduire l'utilisation de mémoire : - Limiter le nombre de canaux - Optimiser l'utilisation des chaînes de caractères - Utiliser PROGMEM pour les constantes

    2. Vérifier les fuites mémoire : ```cpp void monitor_memory() { static unsigned long last_check = 0; static uint32_t last_free_heap = 0;

      if(millis() - last_check > 5000) { uint32_t current_heap = ESP.getFreeHeap(); Serial.printf("Heap: %d (change: %d)\n", current_heap, (int32_t)current_heap - last_free_heap);

      plaintext
      last_free_heap = current_heap;
         last_check = millis();

      } } ```

    Problèmes de gradation et de scintillement

    v2.0.0 résout quatre problèmes de scintillement distincts découverts lors de la validation du matériel 4 canaux. Chacun a une cause racinaire spécifique et une correction.

    Problème : Scintillement général à tous les niveaux de luminosité

    Cause racinaire : La commutation TRIAC injecte une pointe de tension sur la broche de l'optcoupleur de passage par zéro. Cette pointe retriggerise l'ISR ZC au milieu du demi-cycle, ce qui pousse la bibliothèque à calculer une synchronisation incorrecte et à déclencher le TRIAC au mauvais moment.

    Correction (v2.0.0) : Le gestionnaire zero_cross_isr_handler implémente maintenant une porte de bruit. Tout bord ZC qui arrive dans les ZC_DEBOUNCE_US (3000 us par défaut) du bord valide précédent est rejeté. Cela élimine les fausses détections de passage par zéro causées par le bruit de commutation TRIAC.

    Réglage : Si vous voyez toujours un scintillement sur les installations électriquement bruyantes, augmentez la fenêtre de filtre anti-rebond. Si la détection automatique de fréquence est lente ou échoue, diminuez-la.

    cpp
    // ESP-IDF: set via menuconfig -> Component config -> RBDimmer
    // Or as a compile-time define:
    #define CONFIG_RBDIMMER_ZC_DEBOUNCE_US 4000  // default is 3000

    Voir la section Réglage Kconfig pour plus de détails.

    Problème : Scintillement à 100% de luminosité

    Cause racinaire : À 100% de luminosité, le délai calculé était de 50 us. À ce stade du cycle CA, la tension instantanée est d'environ 5V seulement -- en dessous du seuil de courant d'accrochage du TRIAC. De plus, la distribution d'une ISR de minuterie à partir d'une ISR GPIO via esp_timer rendait les délais infér à 100 us imprévisibles.

    Correction (v2.0.0) : Deux changements : - MIN_DELAY_US relevé de 50 à 100 us, assurant que le TRIAC se déclenche à un point où la tension CA est suffisamment élevée pour un accrochage fiable. - Les niveaux à ou au-dessus de 100% sont mappés à LEVEL_MAX (99% par défaut), ce qui évite entièrement le délai near-zéro problématique.

    Réglage : Ajustez via Kconfig si votre matériel peut s'accrocher de manière fiable à un délai plus court :

    cpp
    #define CONFIG_RBDIMMER_MIN_DELAY_US 100     // default 100
    #define CONFIG_RBDIMMER_LEVEL_MAX    99      // default 99

    Problème : Synchronisation multi-canaux -- Les canaux se déclenchent avec des décalages différents

    Root cause: In v1.x, the ZC ISR processed all channels in a single loop: for each channel it reset the GPIO LOW and then armed the delay timer. Because each channel's GPIO reset happened at a slightly different time within that loop iteration, channels that should have fired simultaneously appeared offset from each other.

    Correction (v2.0.0) : L'ISR ZC utilise maintenant une approche à deux passes : - Passe 1 : Définit tous les GPIO de canal à FAIBLE (réinitialise les signaux de porte TRIAC). - Passe 2 : Arme tous les minuteurs de délai.

    Cela garantit que toutes les réinitialisations GPIO se produisent aussi proches que possible, et l'armement du minuteur n'entrelace pas avec les opérations GPIO.

    Problème : Scintillement aux niveaux inférieurs à 3%

    Cause racinaire : À très bas niveaux de luminosité (en dessous de 3%), le délai calculé se déclenche près de la fin du demi-cycle où la tension CA est trop basse pour l'accrochage TRIAC fiable. Le TRIAC échoue à s'accrocher ou s'accroche par intermittence, produisant un scintillement visible.

    Correction (v2.0.0) : Les niveaux en dessous de LEVEL_MIN (3% par défaut) retournent maintenant delay=0, ce qui éteint le canal plutôt que de tenter une gradation à faible niveau peu fiable.

    Réglage :

    cpp
    #define CONFIG_RBDIMMER_LEVEL_MIN 3  // default 3

    Si votre charge et combinaison TRIAC peuvent s'accrocher de manière fiable à des niveaux inférieurs, vous pouvez réduire cette valeur.

    Problème : Pas de réaction aux changements de niveau

    Étapes de diagnostic :

    1. Verify Channel State: ```cpp void check_channel_state() { if(!rbdimmer_is_active(channel)) { Serial.println("Channel is inactive"); rbdimmer_set_active(channel, true); }

      uint8_t level = rbdimmer_get_level(channel); Serial.printf("Current level: %d%%\n", level);

      uint32_t delay_us = rbdimmer_get_delay(channel); Serial.printf("Current delay: %d us\n", delay_us); } ```

    2. Test Manual Level Changes: ```cpp void test_level_changes() { Serial.println("Testing level changes...");

      for(int level = 0; level <= 100; level += 10) { rbdimmer_set_level(channel, level); delay(500);

      plaintext
      uint8_t actual = rbdimmer_get_level(channel);
         if(actual != level) {
             Serial.printf("Level mismatch: set %d, got %d\n", level, actual);
         }

      } } ```

    Problème : Réaction incorrecte de la luminosité

    Solutions :

    1. Essayer des courbes différentes : ```cpp void test_curves() { rbdimmer_curve_t curves[] = { RBDIMMER_CURVE_LINEAR, RBDIMMER_CURVE_RMS, RBDIMMER_CURVE_LOGARITHMIC };

      const char* names[] = {"Linear", "RMS", "Logarithmic"};

      for(int i = 0; i < 3; i++) { Serial.printf("Testing %s curve...\n", names[i]); rbdimmer_set_curve(channel, curves[i]);

      plaintext
      rbdimmer_set_level(channel, 50);
         delay(2000);
         Serial.printf("Delay at 50%%: %d us\n", rbdimmer_get_delay(channel));

      } } ```

    2. Vérifier la compatibilité de la charge : - Charges résistives : Utilisez la courbe RMS - Charges LED : Utilisez la courbe logarithmique - Charges moteurs : Utilisez la courbe linéaire

    Problèmes de détection de fréquence

    Problème : Détection incorrecte de la fréquence

    Code de diagnostic :

    cpp
    void diagnose_frequency_detection() {
        Serial.println("Frequency detection diagnostic...");
        rbdimmer_init();
        rbdimmer_register_zero_cross(2, 0, 0); // Auto-detect
        // Monitor detection process
        uint16_t readings[100];
        for(int i = 0; i < 100; i++) {
            delay(500);
            readings[i] = rbdimmer_get_frequency(0);
            Serial.printf("Reading %d: %d Hz\n", i, readings[i]);
            if(readings[i] > 0) {
                Serial.printf("Frequency detected at reading %d\n", i);
                break;
            }
        }
        // Analyze final frequency
        uint16_t final_freq = rbdimmer_get_frequency(0);
        if(final_freq == 50) {
            Serial.println("Detected 50Hz mains");
        } else if(final_freq == 60) {
            Serial.println("Detected 60Hz mains");
        } else if(final_freq == 0) {
            Serial.println("No frequency detected");
        } else {
            Serial.printf("Unusual frequency: %d Hz\n", final_freq);
        }
    }

    Solutions :

    1. Forcer la fréquence connue : cpp // If auto-detection fails, use known frequency rbdimmer_register_zero_cross(2, 0, 50); // Force 50Hz rbdimmer_register_zero_cross(2, 0, 60); // Force 60Hz

    2. Vérifier la qualité du signal de passage par zéro : - Le signal doit être composé d'impulsions numériques propres - Vérifiez le bruit électrique - Vérifiez les spécifications du module de variation de lumière

    3. Filtre anti-rebond ZC trop agressif : - Si ZC_DEBOUNCE_US est défini trop haut, les bords ZC légitimes peuvent être rejetés - Pour le réseau 60Hz, le demi-cycle est ~8333 us ; le filtre anti-rebond doit être bien en dessous - Les 3000 us par défaut fonctionnent pour les réseaux 50Hz et 60Hz

    Problèmes multi-canaux

    Problème : Interférence de canal

    Symptômes : - Les canaux s'affectent mutuellement - Scintillement synchronisé

    Code de diagnostic :

    cpp
    void diagnose_multi_channel() {
        Serial.println("Multi-channel diagnostic...");
        rbdimmer_init();
        rbdimmer_register_zero_cross(2, 0, 50);
        // Create multiple channels
        rbdimmer_channel_t* channels[4];
        uint8_t pins[] = {4, 5, 18, 19};
        for(int i = 0; i < 4; i++) {
            rbdimmer_config_t config = {pins[i], 0, 0, RBDIMMER_CURVE_LINEAR};
            rbdimmer_create_channel(&config, &channels[i]);
        }
        // Test individual control
        Serial.println("Testing individual channel control...");
        for(int ch = 0; ch < 4; ch++) {
            Serial.printf("Activating channel %d only\n", ch);
            for(int i = 0; i < 4; i++) {
                rbdimmer_set_level(channels[i], (i == ch) ? 50 : 0);
            }
            delay(2000);
        }
        // Test simultaneous control
        Serial.println("Testing simultaneous control...");
        for(int level = 0; level <= 100; level += 25) {
            for(int i = 0; i < 4; i++) {
                rbdimmer_set_level(channels[i], level);
            }
            Serial.printf("All channels set to %d%%\n", level);
            delay(1000);
        }
    }

    Solutions :

    1. Vérifier les assignations de broche GPIO : - Assurez-vous que les broches uniques pour chaque canal - Évitez l'utilisation conflictuelle de broche

    2. Capacité de l'alimentation : - Plusieurs canaux augmentent le tirage de courant - Utilisez une alimentation adéquate

    3. Problèmes de synchronisation multi-canaux (v2.0.0) : - v2.0.0 utilise une ISR ZC à deux passes pour éliminer le décalage inter-canal - Si les canaux semblent toujours décalés, vérifiez que vous exécutez v2.0.0 - Vérifiez que tous les canaux sont enregistrés sur la même phase s'ils partagent un signal ZC

    Réglage Kconfig

    v2.0.0 expose quatre paramètres via Kconfig (ESP-IDF menuconfig) ou en tant que définitions au moment de la compilation pour Arduino. Ceux-ci contrôlent les corrections de scintillement et ne doivent être modifiés que si les paramètres par défaut ne conviennent pas à votre matériel.

    ZC_DEBOUNCE_US -- Fenêtre de filtre anti-rebond de passage par zéro

    plaintext
    CONFIG_RBDIMMER_ZC_DEBOUNCE_US (default: 3000)

    Le temps minimum en microsecondes entre deux bords de passage par zéro valides. Tout bord arrivant plus tôt est traité comme du bruit et rejeté.

    Quand ajuster : - Augmentez si vous voyez toujours un scintillement général (le bruit TRIAC traverse). Essayez 4000-5000. - Diminuez si la détection automatique de fréquence est peu fiable ou lente. Ne descendez pas en dessous de 1500 pour le réseau 60Hz. - Doit être significativement inférieur à la moitié de la période CA (10000 us à 50Hz, 8333 us à 60Hz).

    MIN_DELAY_US -- Délai de déclenchement TRIAC minimum

    plaintext
    CONFIG_RBDIMMER_MIN_DELAY_US (default: 100)

    Le délai le plus court autorisé entre un événement de passage par zéro et l'impulsion de porte TRIAC. Empêche le déclenchement à une tension CA near-zéro où l'accrochage TRIAC est peu fiable.

    Quand ajuster : - Augmentez si vous voyez un scintillement aux niveaux de luminosité élevée. Essayez 150-200. - Diminuez uniquement si votre combinaison TRIAC et charge s'accroche de manière fiable à des délais très courts. Non recommandé en dessous de 80.

    LEVEL_MAX -- Niveau de gradation effectif maximum

    plaintext
    CONFIG_RBDIMMER_LEVEL_MAX (default: 99)

    Les niveaux à ou au-dessus de cette valeur sont limités à ce pourcentage. Empêche le délai calculé de chuter en dessous de MIN_DELAY_US.

    Quand ajuster : - Normalement laissez à 99. Régler à 100 désactive effectivement la pince de niveau maximum et peut causer un scintillement à luminosité complète.

    LEVEL_MIN -- Niveau de gradation effectif minimum

    plaintext
    CONFIG_RBDIMMER_LEVEL_MIN (default: 3)

    Les niveaux en dessous de cette valeur se traduit par le canal étant éteint (délai=0) plutôt que de tenter de déclencher le TRIAC près de la fin du demi-cycle.

    Quand ajuster : - Diminuez si votre TRIAC et charge peuvent s'assombrir de manière fiable en dessous de 3%. Testez avec soin. - Augmentez si vous voyez un scintillement à faible luminosité. Essayez 5.

    Définition des paramètres

    ESP-IDF (menuconfig) :

    plaintext
    idf.py menuconfig
    -> Component config -> RBDimmer ESP32

    Arduino (définitions au moment de la compilation) :

    ini
    # platformio.ini
    build_flags =
        -DCONFIG_RBDIMMER_ZC_DEBOUNCE_US=3000
        -DCONFIG_RBDIMMER_MIN_DELAY_US=100
        -DCONFIG_RBDIMMER_LEVEL_MAX=99
        -DCONFIG_RBDIMMER_LEVEL_MIN=3
    cpp
    // Or in code, before including the library header:
    #define CONFIG_RBDIMMER_ZC_DEBOUNCE_US 3000
    #define CONFIG_RBDIMMER_MIN_DELAY_US   100
    #define CONFIG_RBDIMMER_LEVEL_MAX      99
    #define CONFIG_RBDIMMER_LEVEL_MIN      3
    #include 

    Sécurité et défaillances matérielles

    CRITIQUE : Problèmes de sécurité

    Actions immédiates pour les problèmes de sécurité :

    1. Odeur de brûlure ou fumée : - Déconnectez immédiatement l'alimentation - N'essayez pas de diagnostiquer sous tension - Vérifiez toutes les connexions une fois l'état sûr

    2. Choc électrique : - Déconnectez immédiatement l'alimentation - Vérifiez l'isolation appropriée - Vérifiez l'intégrité du module de variation de lumière

    3. Surchauffe : - Vérifiez les cotes de courant - Vérifiez la dissipation thermique adéquate - Réduisez la charge si nécessaire

    Diagnostic de défaillance matérielle

    Approche systématique :

    1. Inspection visuelle : - Vérifiez les composants brûlés - Recherchez les connexions desserrées - Vérifiez le montage approprié

    2. Tests électriques (uniquement électricité coupée) : - Vérifications de continuité - Résistance d'isolation - Valeurs des composants

    3. Test de remplacement : - Échangez les composants suspectés - Testez avec des modules connus comme bons - Isolez les composants problématiques

    Outils et techniques de débogage

    Débogage du moniteur série

    Sortie de débogage améliorée :

    cpp
    #define DEBUG_LEVEL 3 // 0=none, 1=error, 2=warning, 3=info
    void debug_print(int level, const char* message) {
        if(level <= DEBUG_LEVEL) {
            const char* prefixes[] = {"", "[ERROR]", "[WARN]", "[INFO]"};
            Serial.printf("%s %s\n", prefixes[level], message);
        }
    }
    void detailed_status() {
        debug_print(3, "=== System Status ===");
        debug_print(3, String("Free heap: " + String(ESP.getFreeHeap())).c_str());
        debug_print(3, String("CPU freq: " + String(ESP.getCpuFreqMHz()) + "MHz").c_str());
        debug_print(3, String("Frequency: " + String(rbdimmer_get_frequency(0)) + "Hz").c_str());
        if(channel) {
            debug_print(3, String("Channel level: " + String(rbdimmer_get_level(channel)) + "%").c_str());
            debug_print(3, String("Channel delay: " + String(rbdimmer_get_delay(channel)) + "us").c_str());
            debug_print(3, String("Channel active: " + String(rbdimmer_is_active(channel) ? "Yes" : "No")).c_str());
        }
    }

    Analyse oscilloscope

    Mesures clés : 1. Signal de passage par zéro : Doit être composé d'impulsions propres à 50/60Hz 2. Commande de porte : Synchronisation précise par rapport au passage par zéro 3. Tension de charge : Forme d'onde à découpe de phase 4. Courant de charge : Doit suivre le motif de tension

    Analyseur logique

    Pour l'analyse de signal numérique : - Synchronisation de passage par zéro - Synchronisation de commande de porte - Synchronisation multi-canaux (vérifiez que l'ISR à deux passes élimine le décalage)

    Questions fréquemment posées

    Q : Pourquoi mon variateur scintille-t-il ?

    R : v2.0.0 corrige les quatre causes de scintillement les plus courantes. Vérifiez quel motif correspond au vôtre : 1. Scintillement à tous les niveaux -- Bruit ZC provenant de la commutation TRIAC. Corrigé par filtre anti-rebond ZC. Voir Scintillement général. 2. Scintillement à 100% -- TRIAC échoue à s'accrocher à un délai near-zéro. Corrigé par augmentation MIN_DELAY_US. Voir Scintillement à 100%. 3. Scintillement en dessous de 3% -- Tension CA trop basse à la fin du demi-cycle. Corrigé par coupure LEVEL_MIN. Voir Scintillement en dessous de 3%. 4. Décalage/scintillement multi-canaux -- Ordre de boucle ISR. Corrigé par ISR à deux passes. Voir Synchronisation multi-canaux.

    Si aucun de ceux-ci ne correspond, vérifiez aussi : 5. Incompatibilité de charge -- Essayez une charge résistive pour les tests 6. Problèmes d'alimentation -- Vérifiez la stabilité de l'alimentation ESP32 7. Interférences électriques -- Séparez le câblage CA et CC 8. Type de courbe incorrect -- Essayez des paramètres de courbe différents

    Q : Puis-je l'utiliser avec des LED ?

    A: Yes, but with limitations: - Use only "dimmable" rated LED bulbs - Try RBDIMMER_CURVE_LOGARITHMIC - Some LEDs may flicker at low levels -- consider increasing LEVEL_MIN - Test compatibility first

    Q : Pourquoi la détection de fréquence échoue-t-elle ?

    R : Raisons possibles : 1. Aucun signal de passage par zéro -- Vérifiez le câblage 2. Module de variation de lumière incorrect -- Vérifiez la sortie ZC 3. Bruit électrique -- Améliorez la qualité du signal 4. Filtre anti-rebond ZC trop agressif -- Essayez de réduire ZC_DEBOUNCE_US 5. Problème logiciel -- Essayez d'abord la fréquence fixe

    Q : Combien de canaux puis-je utiliser ?

    R : Limites techniques : - Maximum 8 canaux par ESP32 - Chaque canal utilise ~200 octets de RAM - Tous les canaux sur la même phase partagent le passage par zéro - L'alimentation doit supporter tous les canaux - L'ISR à deux passes v2.0.0 garantit une synchronisation appropriée sur tous les canaux

    Q : Est-il sûr d'utiliser avec des moteurs ?

    R : Avec précautions : - Utilisez des modules de variation de lumière adaptés aux moteurs - Tenez compte des exigences de démarrage progressif - Surveillez le courant et la température - Utilisez la courbe appropriée (généralement linéaire)

    Q : Puis-je contrôler des charges 220V ?

    R : Oui, si le module de variation de lumière le supporte : - Vérifiez la cote de tension du variateur - Utilisez les mesures de sécurité appropriées - Respectez les codes électriques locaux - Envisagez l'installation professionnelle

    Q : Quelle version d'ESP-IDF est requise ?

    R : ESP-IDF 5.3 ou ultérieur est requis pour v2.0.0. La bibliothèque utilise Kconfig pour la configuration des paramètres, qui s'intègre au système menuconfig d'ESP-IDF. Les utilisateurs Arduino peuvent définir les paramètres via des définitions de temps de compilation à la place.

    Obtenir de l'aide supplémentaire

    Avant de demander de l'aide

    Veuillez rassembler ces informations :

    1. Configuration matérielle : - Type de carte ESP32 - Modèle du module de variation de lumière - Type de charge et puissance - Schéma de câblage

    2. Configuration logicielle : - IDE et version - Version de la bibliothèque (v2.0.0 ou antérieure) - Version d'ESP-IDF (le cas échéant) - Code complet (exemple minimal) - Messages d'erreur - Remplacements de paramètres Kconfig / temps de compilation

    3. Description du problème : - Comportement attendu - Comportement réel - Étapes pour reproduire - Quand le problème a commencé

    Canaux de support

    1. Problèmes GitHub : Signaler les bugs et les problèmes
    2. Forum communautaire : Discussion et aide
    3. Support par e-mail : [email protected]
    4. Documentation : Guides complets

    Créer de bons rapports de problème

    Modèle pour les rapports de problème :

    markdown
    ## Problem Description
    Brief description of the issue
    ## Hardware Setup
    - ESP32 Board: [e.g., ESP32 DevKit V1]
    - Dimmer Module: [e.g., RobotDyn AC Light Dimmer]
    - Load: [e.g., 100W incandescent bulb]
    - Wiring: [pin connections]
    ## Software Environment
    - IDE: [Arduino IDE 2.x]
    - ESP32 Core / ESP-IDF: [version]
    - Library Version: [2.0.0]
    - Kconfig overrides: [list any non-default values]
    ## Expected Behavior
    What should happen
    ## Actual Behavior
    What actually happens
    ## Code Example
    \```cpp
    // Minimal code that reproduces the problem
    \```
    ## Additional Information
    - Error messages
    - Serial output
    - Oscilloscope traces (if available)

    Remember: Most problems have simple solutions. Work through the diagnostics systematically, and don't hesitate to ask for help with detailed information about your setup.

    Guide de dépannage pour rbdimmerESP32 v2.0.0