Ir al contenido

Guía de Solución de Problemas de rbdimmerESP32

Actualizado para v2.0.0 -- incluye correcciones para cuatro problemas de parpadeo descubiertos durante la validación de hardware de 4 canales.

Lista de Verificación de Diagnóstico Rápido

Antes de adentrarse en la solución de problemas detallada, repase esta lista de verificación rápida:

Verificación Básica del Sistema

  • Placa ESP32 seleccionada correctamente en IDE
  • ESP-IDF 5.3 o posterior (si utiliza el marco ESP-IDF)
  • Biblioteca correctamente instalada e incluida
  • Todas las conexiones de cableado aseguradas
  • Suministro de energía adecuado (3.3V, >500mA)
  • Módulo regulador de luminosidad alimentado y operativo
  • Carga AC compatible con atenuación
  • Procedimientos de seguridad seguidos
  • Código de Prueba Rápida

    Ejecute esta prueba mínima para verificar la funcionalidad básica:

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

    Problemas de Compilación

    Problema: Biblioteca No Encontrada

    Mensajes de Error:

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

    Soluciones:

    Arduino IDE

    1. Verificar Instalación: - Verifique Archivo -> Ejemplos -> rbdimmerESP32 - Si no es visible, la biblioteca no se instaló correctamente

    2. Reinstalar Biblioteca: Sketch -> Include Library -> Manage Libraries Search "rbdimmerESP32" -> Install

    3. Verificación Manual de Instalación: - La biblioteca debe estar en: ~/Documents/Arduino/libraries/rbdimmerESP32/ - Asegúrese de que rbdimmerESP32.h esté en la carpeta src/

    Problema: Errores de Compilación

    Mensajes de Error:

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

    Soluciones:

    1. Verificar Selección de Placa: - Debe ser tipo de placa ESP32 - Arduino IDE: Herramientas -> Placa -> 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. Verificar Marco:

    Mensajes de Error:

    plaintext
    error: conflicting declaration of C function

    Soluciones:

    1. Verificar Inclusiones Múltiples: - Incluya rbdimmerESP32.h solo una vez por archivo - Verifique conflictos con otras bibliotecas de atenuación

    2. Compilación Limpia: - Elimine la carpeta de compilación y recompile

    Problema: Errores de Vinculación

    Mensajes de Error:

    plaintext
    undefined reference to `rbdimmer_init'

    Soluciones:

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

    La biblioteca utiliza una arquitectura modular con su propio archivo Kconfig. ESP-IDF recogerá automáticamente las opciones de Kconfig cuando el componente se registre correctamente.

    Problema: La Inicialización de la Biblioteca Falla

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

    Código de Diagnóstico:

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

    Soluciones:

    1. Problemas de Memoria: - Verifique la memoria heap disponible - Reduzca otro uso de memoria - Aumente el tamaño del heap si es posible

    2. Inicializaciones Múltiples: - Llame a rbdimmer_init() solo una vez - Verifique llamadas duplicadas

    Problema: El Registro de Zero-Cross Falla

    Códigos de Error y Soluciones:

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

    Soluciones: - Utilice pines GPIO 2, 4, 5, 12-15, 25-27 - Evite los pines 0, 1, 3 (arranque/serie) - Evite los pines 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);
        }
    }

    Soluciones: - Verifique llamadas duplicadas a rbdimmer_register_zero_cross() - Utilice rbdimmer_deinit() para reiniciar si es necesario

    Problema: La Creación del Canal Falla

    Código de Diagnóstico:

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

    Soluciones:

    1. Fase No Registrada: - Registre el detector de zero-cross primero - Verifique que el número de fase coincida

    2. Problemas de Memoria: - Se admiten máximo 8 canales - Cada canal utiliza ~200 bytes de RAM - Libere memoria si es necesario

    3. Problemas de GPIO: - Pruebe un pin GPIO diferente - Verifique conflictos de pines con otro código

    Problemas de Conexión de Hardware

    Problema: No Hay Detección de Zero-Cross

    Síntomas: - rbdimmer_get_frequency() devuelve 0 - No hay respuesta de atenuación

    Código de Diagnóstico:

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

    Soluciones:

    1. Verificar Conexiones Físicas: - Verifique la conexión del pin de salida zero-cross - Compruebe la conexión de tierra entre ESP32 y el módulo regulador - Asegúrese de que el módulo regulador esté alimentado

    2. Prueba del Módulo Regulador: - Utilice un multímetro para verificar la salida zero-cross (voltaje DC) - Debe mostrar pulsos ~3.3V a la frecuencia de la red eléctrica - Si no hay señal, el módulo regulador puede estar defectuoso

    3. Probar Pin Diferente: 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... }

    Problema: TRIAC No Conmuta

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

    Código de Diagnóstico:

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

    Soluciones:

    1. Verificar Conexión de Control de Puerta: - Verifique el pin GPIO a la entrada de puerta del regulador - Asegúrese de la polaridad correcta - Verifique conexiones sueltas

    2. Prueba con Indicador LED: cpp // Add LED to gate control pin pinMode(4, OUTPUT); // LED should pulse with dimming

    3. Problemas del Módulo Regulador: - Verifique la fuente de alimentación del módulo - Verifique que el módulo esté diseñado para lógica 3.3V - Pruebe con un módulo regulador diferente

    Problema: Comportamiento de Atenuación Errático

    Síntomas: - Niveles de brillo inconsistentes - Parpadeo o cambios bruscos - Conmutación aleatoria de encendido/apagado

    Código de Diagnóstico:

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

    Soluciones:

    1. Problemas de Fuente de Alimentación: - Verifique la estabilidad de la fuente de alimentación de ESP32 - Utilice adaptador de alimentación de calidad (>500mA) - Agregue capacitores de filtrado de fuente de alimentación

    2. Interferencia Eléctrica: - Separe el cableado de bajo voltaje y AC - Agregue núcleos de ferrita en cables - Utilice cables blindados si es necesario

    3. Problemas de Carga: - Pruebe con un tipo de carga diferente - Verifique compatibilidad de carga - Verifique que la corriente de carga esté dentro del rango del regulador

    4. Ruido Zero-Cross (v2.0.0): - Consulte la sección Problemas de Atenuación y Parpadeo a continuación para ajuste de deshabilitación de ZC

    Problemas de Rendimiento

    Problema: Imprecisión de Sincronización

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

    Código de Diagnóstico:

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

    Soluciones:

    1. Verificar Carga del 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. Optimizar Manejo de Interrupciones: - Mantenga el código ISR mínimo - Evite Serial.print() en devoluciones de llamada - Utilice colas FreeRTOS para transferencia de datos

    3. Verificar Reloj de 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: Problemas de Memoria

    Síntomas: - El sistema se bloquea o reinicia - La creación de canal falla - Comportamiento errático

    Código de Diagnóstico:

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

    Soluciones:

    1. Reducir Uso de Memoria: - Limitar número de canales - Optimizar uso de cadenas - Utilizar PROGMEM para constantes

    2. Verificar Pérdidas de 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();

      } } ```

    Problemas de Atenuación y Parpadeo

    v2.0.0 aborda cuatro problemas de parpadeo distintos descubiertos durante la validación de hardware de 4 canales. Cada uno tiene una causa raíz y una corrección específicas.

    Problema: Parpadeo General en Todos los Niveles de Brillo

    Causa raíz: La conmutación TRIAC inyecta un pico de voltaje en el pin del optoacoplador zero-cross. Este pico vuelve a activar el ISR de ZC en medio del medio ciclo, haciendo que la biblioteca calcule una sincronización incorrecta y dispare el TRIAC en el momento incorrecto.

    Corrección (v2.0.0): El zero_cross_isr_handler ahora implementa una puerta de ruido. Cualquier borde de ZC que llegue dentro de ZC_DEBOUNCE_US (predeterminado 3000 us) del borde válido anterior se descarta. Esto elimina detecciones falsas de zero-cross causadas por ruido de conmutación TRIAC.

    Ajuste: Si aún ve parpadeo en configuraciones eléctricamente ruidosas, aumente la ventana de deshabilitación. Si la detección automática de frecuencia es lenta o falla, disminúyala.

    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

    Consulte la sección Ajuste de Kconfig para más detalles.

    Problema: Parpadeo al 100% de Brillo

    Causa raíz: Al 100% de brillo, el retraso calculado fue de 50 us. En ese punto del ciclo AC el voltaje instantáneo es solo alrededor de 5V -- por debajo del umbral de corriente de retención TRIAC. Además, enviar una ISR de temporizador desde una ISR de GPIO a través de esp_timer hizo que los retrasos inferiores a 100 us fueran impredecibles.

    Corrección (v2.0.0): Dos cambios: - MIN_DELAY_US aumentado de 50 a 100 us, asegurando que el TRIAC se dispare en un punto donde el voltaje AC sea lo suficientemente alto para una retención confiable. - Los niveles al 100% o superiores se asignan a LEVEL_MAX (predeterminado 99%), lo que evita completamente el retraso problemático cercano a cero.

    Ajuste: Ajuste vía Kconfig si su hardware puede retener de manera confiable con un retraso más corto:

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

    Problema: Sincronización Multicanal -- Canales se Disparan en Desplazamientos Diferentes

    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.

    Corrección (v2.0.0): El ISR de ZC ahora utiliza un enfoque de dos pasos: - Paso 1: Establece todos los GPIO de canal en BAJO (restablece las señales de puerta TRIAC). - Paso 2: Arma todos los temporizadores de retraso.

    Esto asegura que todos los restablecimientos de GPIO suceda lo más cerca posible, y el armado del temporizador no se intercale con operaciones de GPIO.

    Problema: Parpadeo en Niveles Inferiores al 3%

    Causa raíz: A niveles de brillo muy bajos (inferiores al 3%), el retraso calculado se dispara cerca del final del medio ciclo donde el voltaje AC es demasiado bajo para una retención TRIAC confiable. El TRIAC no se retiene o se retiene de manera intermitente, produciendo parpadeo visible.

    Corrección (v2.0.0): Los niveles inferiores a LEVEL_MIN (predeterminado 3%) ahora devuelven delay=0, lo que apaga el canal en lugar de intentar atenuación confiable de bajo nivel.

    Ajuste:

    cpp
    #define CONFIG_RBDIMMER_LEVEL_MIN 3  // default 3

    Si su combinación de carga y TRIAC puede retener de manera confiable en niveles más bajos, puede reducir este valor.

    Problema: Sin Respuesta a Cambios de Nivel

    Pasos de Diagnóstico:

    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: Respuesta de Brillo Incorrecta

    Soluciones:

    1. Probar Diferentes Curvas: ```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. Verificar Compatibilidad de Carga: - Cargas resistivas: Utilice curva RMS - Cargas LED: Utilice curva Logarítmica - Cargas de motor: Utilice curva Lineal

    Problemas de Detección de Frecuencia

    Problema: Detección de Frecuencia Incorrecta

    Código de Diagnóstico:

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

    Soluciones:

    1. Forzar Frecuencia Conocida: 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. Verificar Calidad de Señal Zero-Cross: - La señal debe ser pulsos digitales limpios - Verifique ruido eléctrico - Verifique especificaciones del módulo regulador

    3. Deshabilitación de ZC Demasiado Agresiva: - Si ZC_DEBOUNCE_US está establecido demasiado alto, los bordes legítimos de ZC pueden descartarse - Para la red de 60Hz, el medio ciclo es ~8333 us; la deshabilitación debe estar muy por debajo de esto - El valor predeterminado 3000 us funciona tanto para redes de 50Hz como de 60Hz

    Problemas Multicanal

    Problema: Interferencia de Canal

    Síntomas: - Los canales se afectan entre sí - Parpadeo sincronizado

    Código de Diagnóstico:

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

    Soluciones:

    1. Verificar Asignaciones de Pines GPIO: - Asegúrese de pines únicos para cada canal - Evite uso de pines conflictivos

    2. Capacidad de Fuente de Alimentación: - Múltiples canales aumentan el consumo de corriente - Utilice una fuente de alimentación adecuada

    3. Problemas de Sincronización Multicanal (v2.0.0): - v2.0.0 utiliza un ISR de ZC de dos pasos para eliminar desplazamientos entre canales - Si los canales aún parecen desplazados, verifique que está ejecutando v2.0.0 - Verifique que todos los canales estén registrados en la misma fase si comparten una señal ZC

    Ajuste de Kconfig

    v2.0.0 expone cuatro parámetros a través de Kconfig (ESP-IDF menuconfig) o como defines de tiempo de compilación para Arduino. Estos controlan las correcciones de parpadeo y solo deben cambiarse si los valores predeterminados no se adecuan a su hardware.

    ZC_DEBOUNCE_US -- Ventana de Deshabilitación Zero-Cross

    plaintext
    CONFIG_RBDIMMER_ZC_DEBOUNCE_US (default: 3000)

    El tiempo mínimo en microsegundos entre dos bordes zero-cross válidos. Cualquier borde que llegue más pronto se trata como ruido y se descarta.

    Cuándo ajustar: - Aumentar si aún ve parpadeo general (ruido TRIAC atravesando). Pruebe 4000-5000. - Disminuir si la detección automática de frecuencia no es confiable o es lenta. No descienda por debajo de 1500 para la red de 60Hz. - Debe ser significativamente menor que la mitad del período AC (10000 us a 50Hz, 8333 us a 60Hz).

    MIN_DELAY_US -- Retraso Mínimo de Disparo TRIAC

    plaintext
    CONFIG_RBDIMMER_MIN_DELAY_US (default: 100)

    El retraso más corto permitido entre un evento zero-cross y el pulso de puerta TRIAC. Evita disparar a voltaje AC cercano a cero donde la retención TRIAC no es confiable.

    Cuándo ajustar: - Aumentar si ve parpadeo a altos niveles de brillo. Pruebe 150-200. - Disminuir solo si su combinación de TRIAC y carga se retiene de manera confiable con retrasos muy cortos. No recomendado por debajo de 80.

    LEVEL_MAX -- Nivel Máximo de Atenuación Efectiva

    plaintext
    CONFIG_RBDIMMER_LEVEL_MAX (default: 99)

    Los niveles al 100% o superiores se fijan a este porcentaje. Evita que el retraso calculado caiga por debajo de MIN_DELAY_US.

    Cuándo ajustar: - Normalmente déjelo en 99. Configurar a 100 efectivamente deshabilita el fijador de nivel máximo y puede causar parpadeo a brillo completo.

    LEVEL_MIN -- Nivel Mínimo de Atenuación Efectiva

    plaintext
    CONFIG_RBDIMMER_LEVEL_MIN (default: 3)

    Los niveles inferiores a este valor dan como resultado que el canal se apague (delay=0) en lugar de intentar disparar el TRIAC cerca del final del medio ciclo.

    Cuándo ajustar: - Disminuir si su TRIAC y carga pueden regular de manera confiable por debajo del 3%. Pruebe cuidadosamente. - Aumentar si ve parpadeo a bajo brillo. Pruebe 5.

    Configuración de Parámetros

    ESP-IDF (menuconfig):

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

    Arduino (defines de tiempo de compilación):

    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 

    Seguridad y Fallos de Hardware

    CRÍTICO: Problemas de Seguridad

    Acciones Inmediatas para Problemas de Seguridad:

    1. Olor a Quemado o Humo: - Desconecte inmediatamente la alimentación - No intente diagnosticar mientras esté alimentado - Verifique todas las conexiones cuando sea seguro

    2. Descarga Eléctrica: - Desconecte inmediatamente la alimentación - Verifique el aislamiento adecuado - Verifique la integridad del módulo regulador

    3. Sobrecalentamiento: - Verifique las clasificaciones de corriente - Verifique el disipador de calor adecuado - Reduzca la carga si es necesario

    Diagnóstico de Fallo de Hardware

    Enfoque Sistemático:

    1. Inspección Visual: - Verifique componentes quemados - Busque conexiones sueltas - Verifique el montaje adecuado

    2. Prueba Eléctrica (Solo con Energía Desconectada): - Pruebas de continuidad - Resistencia de aislamiento - Valores de componentes

    3. Prueba de Reemplazo: - Intercambie componentes sospechosos - Pruebe con módulos conocidos de buena fe - Aísle componentes problemáticos

    Herramientas y Técnicas de Depuración

    Depuración del Monitor Serial

    Salida de Depuración Mejorada:

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

    Análisis de Osciloscopio

    Mediciones Clave: 1. Señal zero-cross: Debe ser pulsos limpios de 50/60Hz 2. Control de puerta: Sincronización precisa relativa a zero-cross 3. Voltaje de carga: Forma de onda de corte de fase 4. Corriente de carga: Debe seguir el patrón de voltaje

    Analizador Lógico

    Para Análisis de Señal Digital: - Sincronización zero-cross - Sincronización de control de puerta - Sincronización multicanal (verifique que el ISR de dos pasos elimina desplazamientos)

    Preguntas Frecuentes

    P: ¿Por qué mi regulador parpadea?

    R: v2.0.0 corrige las cuatro causas más comunes de parpadeo. Verifique cuál de estos patrones coincide con el suyo: 1. Parpadeo a todos los niveles -- Ruido de ZC por conmutación TRIAC. Corregido por deshabilitación de ZC. Consulte Parpadeo General. 2. Parpadeo al 100% -- TRIAC falla al retener con retraso cercano a cero. Corregido por aumento de MIN_DELAY_US. Consulte Parpadeo al 100%. 3. Parpadeo por debajo del 3% -- Voltaje AC demasiado bajo al final del medio ciclo. Corregido por corte de LEVEL_MIN. Consulte Parpadeo Inferiores al 3%. 4. Desplazamiento/parpadeo multicanal -- Ordenamiento de bucle ISR. Corregido por ISR de dos pasos. Consulte Sincronización Multicanal.

    Si ninguno de estos coincide, también verifique: 5. Incompatibilidad de carga -- Pruebe carga resistiva para pruebas 6. Problemas de fuente de alimentación -- Verifique estabilidad de alimentación ESP32 7. Interferencia eléctrica -- Separe cableado AC y DC 8. Tipo de curva incorrecto -- Pruebe diferentes configuraciones de curva

    P: ¿Puedo usar esto con luces 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

    P: ¿Por qué falla la detección de frecuencia?

    R: Posibles razones: 1. No hay señal zero-cross -- Verifique cableado 2. Módulo regulador incorrecto -- Verifique salida ZC 3. Ruido eléctrico -- Mejore la calidad de la señal 4. Deshabilitación de ZC demasiado agresiva -- Intente reducir ZC_DEBOUNCE_US 5. Problema de software -- Intente frecuencia fija primero

    P: ¿Cuántos canales puedo usar?

    R: Límites técnicos: - Máximo 8 canales por ESP32 - Cada canal utiliza ~200 bytes de RAM - Todos los canales en la misma fase comparten zero-crossing - La fuente de alimentación debe ser compatible con todos los canales - El ISR de dos pasos v2.0.0 asegura sincronización adecuada en todos los canales

    P: ¿Es seguro usar con motores?

    R: Con precauciones: - Utilice módulos reguladores con calificación de motor - Considere los requisitos de arranque suave - Monitoree corriente y temperatura - Utilice curva apropiada (usualmente Lineal)

    P: ¿Puedo controlar cargas de 220V?

    R: Sí, si el módulo regulador lo permite: - Verifique la clasificación de voltaje del regulador - Utilice medidas de seguridad apropiadas - Siga los códigos eléctricos locales - Considere instalación profesional

    P: ¿Qué versión de ESP-IDF se requiere?

    R: Se requiere ESP-IDF 5.3 o posterior para v2.0.0. La biblioteca utiliza Kconfig para configuración de parámetros, que se integra con el sistema menuconfig de ESP-IDF. Los usuarios de Arduino pueden establecer parámetros a través de defines de tiempo de compilación en su lugar.

    Obtener Ayuda Adicional

    Antes de Solicitar Ayuda

    Reúna esta información:

    1. Configuración de Hardware: - Tipo de placa ESP32 - Modelo del módulo regulador - Tipo de carga y potencia - Esquema de cableado

    2. Configuración de Software: - IDE y versión - Versión de biblioteca (v2.0.0 o anterior) - Versión de ESP-IDF (si corresponde) - Código completo (ejemplo mínimo) - Mensajes de error - Anulaciones de parámetros Kconfig / tiempo de compilación

    3. Descripción del Problema: - Comportamiento esperado - Comportamiento real - Pasos para reproducir - Cuándo comenzó el problema

    Canales de Soporte

    1. Problemas de GitHub: Reportar errores y problemas
    2. Foro Comunitario: Discusión y ayuda
    3. Soporte por Email: [email protected]
    4. Documentación: Guías Completas

    Creación de Buenos Reportes de Problemas

    Plantilla para Reportes de Problemas:

    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.

    Guía de solución de problemas para rbdimmerESP32 v2.0.0