Passa al contenuto

Guida alla Risoluzione dei Problemi rbdimmerESP32

Aggiornato per la v2.0.0 -- include correzioni per quattro problemi di sfarfallio scoperti durante la convalida hardware a 4 canali.

Checklist di Diagnostica Rapida

Prima di approfondire la risoluzione dei problemi, esegui questa checklist rapida:

Controllo del Sistema di Base

  • Scheda ESP32 selezionata correttamente nell'IDE
  • ESP-IDF 5.3 o successivo (se si usa il framework ESP-IDF)
  • Libreria installata correttamente e inclusa
  • Tutte le connessioni di cablaggio sicure
  • Alimentazione adeguata (3,3V, >500mA)
  • Modulo dimmer alimentato e operativo
  • Carico AC compatibile con il dimming
  • Procedure di sicurezza seguite
  • Codice di Test Rapido

    Esegui questo test minimalista per verificare la funzionalità di 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);
    }

    Problemi di Compilazione

    Problema: Libreria Non Trovata

    Messaggi di Errore:

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

    Soluzioni:

    Arduino IDE

    1. Verifica Installazione: - Controlla File -> Esempi -> rbdimmerESP32 - Se non visibile, la libreria non è stata installata correttamente

    2. Reinstalla Libreria: Sketch -> Include Library -> Manage Libraries Search "rbdimmerESP32" -> Install

    3. Controllo Installazione Manuale: - La libreria dovrebbe essere in: ~/Documents/Arduino/libraries/rbdimmerESP32/ - Assicurati che rbdimmerESP32.h sia nella cartella src/

    Problema: Errori di Compilazione

    Messaggi di Errore:

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

    Soluzioni:

    1. Controlla Selezione della Scheda: - Deve essere un tipo di scheda ESP32 - Arduino IDE: Strumenti -> Scheda -> 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. Controlla Framework:

    Messaggi di Errore:

    plaintext
    error: conflicting declaration of C function

    Soluzioni:

    1. Controlla Include Multipli: - Includi rbdimmerESP32.h solo una volta per file - Controlla conflitti con altre librerie dimmer

    2. Pulizia Build: - Elimina la cartella build e ricompila

    Problema: Errori del Linker

    Messaggi di Errore:

    plaintext
    undefined reference to `rbdimmer_init'

    Soluzioni:

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

    La libreria utilizza un'architettura modulare con il proprio file Kconfig. ESP-IDF raccoglierà automaticamente le opzioni Kconfig quando il componente è registrato correttamente.

    Problema: Inizializzazione della Libreria Fallisce

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

    Codice di Diagnostica:

    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);
        }
    }

    Soluzioni:

    1. Problemi di Memoria: - Controlla la memoria heap disponibile - Riduci l'utilizzo di memoria di altro codice - Aumenta la dimensione dell'heap se possibile

    2. Inizializzazioni Multiple: - Chiama rbdimmer_init() solo una volta - Controlla le chiamate duplicate

    Problema: Registrazione Zero-Cross Fallisce

    Codici di Errore e Soluzioni:

    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");
        }
    }

    Soluzioni: - Usa pin GPIO 2, 4, 5, 12-15, 25-27 - Evita i pin 0, 1, 3 (boot/serial) - Evita i pin 6-11 (memoria 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);
        }
    }

    Soluzioni: - Controlla le chiamate duplicate di rbdimmer_register_zero_cross() - Usa rbdimmer_deinit() per ripristinare se necessario

    Problema: Creazione del Canale Fallisce

    Codice di Diagnostica:

    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);
        }
    }

    Soluzioni:

    1. Fase Non Registrata: - Registra prima il rilevatore zero-cross - Verifica che il numero di fase corrisponda

    2. Problemi di Memoria: - Massimo 8 canali supportati - Ogni canale utilizza ~200 byte di RAM - Libera memoria se necessario

    3. Problemi GPIO: - Prova un pin GPIO diverso - Controlla i conflitti di pin con altro codice

    Problemi di Connessione Hardware

    Problema: Nessun Rilevamento Zero-Cross

    Sintomi: - rbdimmer_get_frequency() restituisce 0 - Nessuna risposta di dimming

    Codice di Diagnostica:

    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;
            }
        }
    }

    Soluzioni:

    1. Controlla Connessioni Fisiche: - Verifica la connessione del pin di uscita zero-cross - Controlla la connessione di terra tra ESP32 e modulo dimmer - Assicurati che il modulo dimmer sia alimentato

    2. Testa Modulo Dimmer: - Usa un multimetro per controllare l'uscita zero-cross (tensione DC) - Dovrebbe mostrare impulsi ~3,3V alla frequenza di rete - Se nessun segnale, il modulo dimmer potrebbe essere difettoso

    3. Prova un Pin Diverso: cpp // Testa diversi pin GPIO 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... }

    Problema: TRIAC Non Commuta

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

    Codice di Diagnostica:

    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);
        }
    }

    Soluzioni:

    1. Controlla Connessione Controllo Gate: - Verifica il pin GPIO all'ingresso gate del dimmer - Assicurati della corretta polarità - Controlla i collegamenti allentati

    2. Test con Indicatore LED: cpp // Aggiungi LED al pin di controllo del gate pinMode(4, OUTPUT); // LED dovrebbe pulsare con il dimming

    3. Problemi Modulo Dimmer: - Controlla l'alimentazione del modulo - Verifica che il modulo sia progettato per logica 3,3V - Testa con un modulo dimmer diverso

    Problema: Comportamento di Dimming Erratico

    Sintomi: - Livelli di luminosità incoerenti - Sfarfallio o salti - Accensione/spegnimento casuale

    Codice di Diagnostica:

    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");
        }
    }

    Soluzioni:

    1. Problemi di Alimentazione: - Controlla la stabilità dell'alimentazione dell'ESP32 - Usa un adattatore di qualità (>500mA) - Aggiungi condensatori di filtraggio all'alimentazione

    2. Interferenze Elettriche: - Separa il cablaggio a bassa e alta tensione - Aggiungi nuclei ferromagnetici sui cavi - Usa cavi schermati se necessario

    3. Problemi di Carico: - Testa con tipo di carico diverso - Controlla la compatibilità del carico - Verifica che la corrente del carico sia entro i limiti del dimmer

    4. Rumore Zero-Cross (v2.0.0): - Vedi la sezione Problemi di Dimming e Sfarfallio per la sintonizzazione del debounce ZC

    Problemi di Prestazioni

    Problema: Imprecisione Temporale

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

    Codice di Diagnostica:

    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);
        }
    }

    Soluzioni:

    1. Controlla Carico di Sistema: ```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. Ottimizza Gestione Interrupt: - Mantieni il codice ISR minimalista - Evita Serial.print() nei callback - Usa code FreeRTOS per il trasferimento dati

    3. Controlla Frequenza 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"); } }

    Problema: Problemi di Memoria

    Sintomi: - Sistema si arresta in crash o si ripristina - Creazione del canale fallisce - Comportamento erratico

    Codice di Diagnostica:

    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");
        }
    }

    Soluzioni:

    1. Riduci Utilizzo di Memoria: - Limita il numero di canali - Ottimizza l'utilizzo di stringhe - Usa PROGMEM per le costanti

    2. Controlla Perdite di Memoria: ```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();

      } } ```

    Problemi di Dimming e Sfarfallio

    v2.0.0 affronta quattro distinti problemi di sfarfallio scoperti durante la convalida hardware a 4 canali. Ognuno ha una causa radice e una correzione specifiche.

    Problema: Sfarfallio Generale a Tutti i Livelli di Luminosità

    Causa radice: La commutazione del TRIAC inietta uno spike di tensione sul pin dell'optoaccoppiatore zero-cross. Questo spike innesca nuovamente l'ISR ZC a metà del semi-ciclo, causando alla libreria di calcolare i tempi errati e di far partire il TRIAC nel momento sbagliato.

    Correzione (v2.0.0): L'zero_cross_isr_handler ora implementa una noise gate. Qualsiasi fronte ZC che arrivi entro ZC_DEBOUNCE_US (default 3000 us) dal precedente fronte valido viene scartato. Questo elimina i falsi rilevamenti zero-cross causati dal rumore di commutazione del TRIAC.

    Sintonizzazione: Se continui a vedere sfarfallio su setup elettricamente rumorosi, aumenta la finestra di debounce. Se il rilevamento automatico della frequenza è lento o fallisce, diminuiscilo.

    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

    Vedi la sezione Sintonizzazione Kconfig per i dettagli.

    Problema: Sfarfallio al 100% di Luminosità

    Causa radice: Al 100% di luminosità il ritardo calcolato era di 50 us. A quel punto del ciclo AC la tensione istantanea è solo intorno ai 5V -- al di sotto della soglia di corrente di latch del TRIAC. Inoltre, l'invio di un ISR timer dall'interno di un ISR GPIO via esp_timer rendeva i ritardi sotto 100 us imprevedibili.

    Correzione (v2.0.0): Due cambiamenti: - MIN_DELAY_US aumentato da 50 a 100 us, assicurando che il TRIAC si attivi in un punto dove la tensione AC è abbastanza alta per il latch affidabile. - I livelli al 100% o superiori sono mappati a LEVEL_MAX (default 99%), che evita completamente il problematico ritardo quasi zero.

    Sintonizzazione: Regola via Kconfig se il tuo hardware può fare il latch affidabilmente con un ritardo più breve:

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

    Problema: Sincronizzazione Multi-Canale -- I Canali si Attivano a Offset Diversi

    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.

    Correzione (v2.0.0): L'ISR ZC ora usa un approccio a due passaggi: - Passaggio 1: Imposta tutti i GPIO dei canali LOW (ripristina i segnali del gate TRIAC). - Passaggio 2: Arma tutti i timer di ritardo.

    Questo assicura che tutti i reset GPIO avvengano il più vicino possibile, e l'armamento del timer non si interleaccia con le operazioni GPIO.

    Problema: Sfarfallio ai Livelli Sotto il 3%

    Causa radice: A livelli di luminosità molto bassi (sotto il 3%), il ritardo calcolato si attiva vicino alla fine del semi-ciclo dove la tensione AC è troppo bassa per il latch affidabile del TRIAC. Il TRIAC non riesce a fare il latch o fa il latch intermittentemente, producendo sfarfallio visibile.

    Correzione (v2.0.0): I livelli sotto LEVEL_MIN (default 3%) ora restituiscono delay=0, che spegne il canale piuttosto che tentare un dimming inaffidabile a basso livello.

    Sintonizzazione:

    cpp
    #define CONFIG_RBDIMMER_LEVEL_MIN 3  // default 3

    Se la tua combinazione di carico e TRIAC può fare il latch affidabilmente a livelli inferiori, puoi ridurre questo valore.

    Problema: Nessuna Risposta ai Cambiamenti di Livello

    Passaggi di Diagnostica:

    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);
         }

      } } ```

    Problema: Risposta di Luminosità Incorretta

    Soluzioni:

    1. Prova Curve Diverse: ```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. Controlla Compatibilità del Carico: - Carichi resistivi: Usa curva RMS - Carichi LED: Usa curva Logarithmica - Carichi motore: Usa curva Linear

    Problemi di Rilevamento della Frequenza

    Problema: Rilevamento Frequenza Errato

    Codice di Diagnostica:

    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);
        }
    }

    Soluzioni:

    1. Forza Frequenza Nota: cpp // Se il rilevamento automatico fallisce, usa frequenza nota rbdimmer_register_zero_cross(2, 0, 50); // Force 50Hz rbdimmer_register_zero_cross(2, 0, 60); // Force 60Hz

    2. Controlla Qualità del Segnale Zero-Cross: - Il segnale dovrebbe essere impulsi digitali puliti - Controlla il rumore elettrico - Verifica le specifiche del modulo dimmer

    3. ZC Debounce Troppo Aggressivo: - Se ZC_DEBOUNCE_US è impostato troppo alto, i fronti ZC legittimi potrebbero essere scartati - Per mains a 60Hz il semi-ciclo è ~8333 us; il debounce deve essere ben al di sotto di questo - Il default 3000 us funziona per mains sia 50Hz che 60Hz

    Problemi Multi-Canale

    Problema: Interferenza tra Canali

    Sintomi: - I canali si influenzano a vicenda - Sfarfallio sincronizzato

    Codice di Diagnostica:

    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);
        }
    }

    Soluzioni:

    1. Controlla Assegnazioni dei Pin GPIO: - Assicurati che ogni canale abbia pin unici - Evita l'utilizzo di pin in conflitto

    2. Capacità dell'Alimentazione: - Più canali aumentano il consumo di corrente - Usa un'alimentazione adeguata

    3. Problemi di Sincronizzazione Multi-Canale (v2.0.0): - v2.0.0 usa un ISR ZC a due passaggi per eliminare l'offset tra canali - Se i canali sembrano ancora offset, verifica che stai usando v2.0.0 - Controlla che tutti i canali siano registrati sulla stessa fase se condividono un segnale ZC

    Sintonizzazione Kconfig

    v2.0.0 espone quattro parametri via Kconfig (ESP-IDF menuconfig) o come define di compilazione per Arduino. Questi controllano le correzioni dello sfarfallio e dovrebbero essere modificati solo se i default non si adattano al tuo hardware.

    ZC_DEBOUNCE_US -- Finestra di Debounce Zero-Cross

    plaintext
    CONFIG_RBDIMMER_ZC_DEBOUNCE_US (default: 3000)

    Il tempo minimo in microsecondi tra due fronti zero-cross validi. Qualsiasi fronte che arriva prima viene trattato come rumore e scartato.

    Quando regolare: - Aumenta se vedi ancora sfarfallio generale (rumore TRIAC che passa attraverso). Prova 4000-5000. - Diminuisci se il rilevamento automatico della frequenza è inaffidabile o lento. Non scendere sotto 1500 per mains a 60Hz. - Deve essere significativamente inferiore a metà del periodo AC (10000 us a 50Hz, 8333 us a 60Hz).

    MIN_DELAY_US -- Ritardo Minimo di Attivazione TRIAC

    plaintext
    CONFIG_RBDIMMER_MIN_DELAY_US (default: 100)

    Il ritardo più breve consentito tra un evento zero-cross e l'impulso del gate TRIAC. Impedisce l'attivazione a tensione AC quasi zero dove il latch del TRIAC è inaffidabile.

    Quando regolare: - Aumenta se vedi sfarfallio ai livelli di luminosità alti. Prova 150-200. - Diminuisci solo se la tua combinazione di TRIAC e carico fa il latch affidabilmente a ritardi molto brevi. Non consigliato al di sotto di 80.

    LEVEL_MAX -- Livello di Dimming Massimo Effettivo

    plaintext
    CONFIG_RBDIMMER_LEVEL_MAX (default: 99)

    I livelli al 100% o superiori a questo valore sono limitati a questa percentuale. Impedisce al ritardo calcolato di scendere al di sotto di MIN_DELAY_US.

    Quando regolare: - Normalmente lascia a 99. Impostando a 100 disabilita effettivamente il limite di max-level e potrebbe causare sfarfallio al 100% di luminosità.

    LEVEL_MIN -- Livello di Dimming Minimo Effettivo

    plaintext
    CONFIG_RBDIMMER_LEVEL_MIN (default: 3)

    I livelli al di sotto di questo valore risultano nello spegnimento del canale (delay=0) piuttosto che tentare di attivare il TRIAC vicino alla fine del semi-ciclo.

    Quando regolare: - Diminuisci se il tuo TRIAC e carico possono fare dimming affidabilmente al di sotto del 3%. Testa con attenzione. - Aumenta se vedi sfarfallio ai bassi livelli di luminosità. Prova 5.

    Impostazione Parametri

    ESP-IDF (menuconfig):

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

    Arduino (define di compilazione):

    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 

    Sicurezza e Guasti Hardware

    CRITICO: Problemi di Sicurezza

    Azioni Immediate per Problemi di Sicurezza:

    1. Odore di Bruciato o Fumo: - Scollega immediatamente l'alimentazione - Non tentare di diagnosticare mentre alimentato - Controlla tutte le connessioni quando è sicuro

    2. Scossa Elettrica: - Scollega l'alimentazione immediatamente - Controlla l'isolamento adeguato - Verifica l'integrità del modulo dimmer

    3. Surriscaldamento: - Controlla i valori di corrente - Verifica dissipazione termica adeguata - Riduci il carico se necessario

    Diagnostica Guasto Hardware

    Approccio Sistematico:

    1. Ispezione Visiva: - Controlla componenti bruciati - Cerca connessioni allentate - Verifica il montaggio adeguato

    2. Test Elettrico (Solo con Alimentazione Spenta): - Controlli di continuità - Resistenza di isolamento - Valori componenti

    3. Test di Sostituzione: - Scambia componenti sospetti - Testa con moduli noti come funzionanti - Isola componenti problematici

    Strumenti e Tecniche di Debug

    Debug del Monitor Seriale

    Output Debug Migliorato:

    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());
        }
    }

    Analisi Oscilloscopio

    Misurazioni Chiave: 1. Segnale zero-cross: Dovrebbe essere impulsi puliti a 50/60Hz 2. Controllo gate: Timing preciso rispetto a zero-cross 3. Tensione carico: Forma d'onda a taglio di fase 4. Corrente carico: Dovrebbe seguire il pattern di tensione

    Analizzatore Logico

    Per Analisi dei Segnali Digitali: - Timing zero-cross - Timing controllo gate - Sincronizzazione multi-canale (verifica che l'ISR a due passaggi elimina l'offset)

    Domande Frequenti

    D: Perché il mio dimmer sta sfarfallando?

    R: v2.0.0 corregge le quattro cause di sfarfallio più comuni. Controlla quale pattern corrisponde al tuo: 1. Sfarfallio a tutti i livelli -- Rumore ZC dalla commutazione del TRIAC. Corretto dal debounce ZC. Vedi Sfarfallio Generale. 2. Sfarfallio al 100% -- TRIAC non riesce a fare il latch a ritardo quasi zero. Corretto dall'aumento di MIN_DELAY_US. Vedi Sfarfallio al 100%. 3. Sfarfallio sotto il 3% -- Tensione AC troppo bassa alla fine del semi-ciclo. Corretto dal cutoff di LEVEL_MIN. Vedi Sfarfallio Sotto il 3%. 4. Offset multi-canale/sfarfallio -- Ordinamento del loop ISR. Corretto da ISR a due passaggi. Vedi Sincronizzazione Multi-Canale.

    Se nessuno di questi corrisponde, controlla anche: 5. Incompatibilità carico -- Prova carico resistivo per il test 6. Problemi alimentazione -- Controlla la stabilità dell'alimentazione ESP32 7. Interferenza elettrica -- Separa il cablaggio AC e DC 8. Tipo di curva sbagliato -- Prova impostazioni di curva diverse

    D: Posso usare questo con luci 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

    D: Perché il rilevamento della frequenza fallisce?

    R: Possibili motivi: 1. Nessun segnale zero-cross -- Controlla il cablaggio 2. Modulo dimmer sbagliato -- Verifica l'uscita ZC 3. Rumore elettrico -- Migliora la qualità del segnale 4. Debounce ZC troppo aggressivo -- Prova a ridurre ZC_DEBOUNCE_US 5. Problema software -- Prova prima frequenza fissa

    D: Quanti canali posso usare?

    R: Limiti tecnici: - Massimo 8 canali per ESP32 - Ogni canale usa ~200 byte di RAM - Tutti i canali sulla stessa fase condividono zero-cross - L'alimentazione deve supportare tutti i canali - L'ISR a due passaggi di v2.0.0 assicura sincronizzazione adeguata tra tutti i canali

    D: È sicuro usare con motori?

    R: Con precauzioni: - Usa moduli dimmer con rating per motore - Considera i requisiti di soft-start - Monitora corrente e temperatura - Usa curva appropriata (solitamente Linear)

    D: Posso controllare carichi a 220V?

    R: Sì, se il modulo dimmer lo supporta: - Verifica il rating di tensione del dimmer - Usa misure di sicurezza appropriate - Segui i codici elettrici locali - Considera l'installazione professionale

    D: Quale versione di ESP-IDF è richiesta?

    R: ESP-IDF 5.3 o successivo è richiesto per v2.0.0. La libreria utilizza Kconfig per la configurazione dei parametri, che si integra con il sistema menuconfig di ESP-IDF. Gli utenti di Arduino possono invece impostare i parametri tramite define di compilazione.

    Come Ottenere Ulteriore Aiuto

    Prima di Chiedere Aiuto

    Raccogli queste informazioni:

    1. Setup Hardware: - Tipo di scheda ESP32 - Modello modulo dimmer - Tipo e potenza del carico - Schema di cablaggio

    2. Configurazione Software: - IDE e versione - Versione libreria (v2.0.0 o precedente) - Versione ESP-IDF (se applicabile) - Codice completo (esempio minimalista) - Messaggi di errore - Override di parametri Kconfig / compilazione

    3. Descrizione del Problema: - Comportamento previsto - Comportamento effettivo - Passaggi per riprodurre - Quando il problema è iniziato

    Canali di Supporto

    1. GitHub Issues: Segnala bug e problemi
    2. Forum Comunità: Discussione e aiuto
    3. Supporto Email: [email protected]
    4. Documentazione: Guide complete

    Creazione di Buone Segnalazioni di Problemi

    Template per Segnalazioni di Problemi:

    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.

    Guida alla risoluzione dei problemi per rbdimmerESP32 v2.0.0