Referencia de API de rbdimmerESP32
Actualizado para v2.0.0 -- la API pública no ha cambiado, pero la arquitectura interna es completamente modular.
Descripción General
La biblioteca rbdimmerESP32 proporciona una API completa para controlar dimmers AC con microcontroladores ESP32. La API está diseñada teniendo en cuenta la seguridad, el rendimiento y la facilidad de uso, con integración de temporizadores de hardware y operación controlada por interrupciones.
Principios de Diseño Clave
- Segura para Hilos: Todas las funciones son seguras para llamarse desde múltiples tareas FreeRTOS
- Optimizada por Hardware: Utiliza temporizadores de hardware ESP32 para precisión de microsegundos
- Gestión de Recursos: Limpieza automática y manejo de errores
- Extensible: Soporte para múltiples fases y canales
- Modular (v2.0.0): La arquitectura interna es completamente modular -- el motor de curvas, el backend del temporizador y el detector de cruce cero son componentes independientes
Tipos de Datos
Tipos Opacos
rbdimmer_channel_t
typedef struct rbdimmer_channel_s rbdimmer_channel_t;Identificador opaco que representa un canal dimmer. Todas las operaciones del canal utilizan este identificador.
Notas de Uso:
- Creado por rbdimmer_create_channel()
- Debe ser destruido correctamente con rbdimmer_delete_channel()
- No puede ser copiado o serializado
Estructuras de Configuración
rbdimmer_config_t
typedef struct {
uint8_t gpio_pin; // Output signal pin
uint8_t phase; // Phase number (for multi-phase systems)
uint8_t initial_level; // Initial level percentage (0-100)
rbdimmer_curve_t curve_type; // Level curve type
} rbdimmer_config_t;Estructura de configuración para crear canales dimmer.
Fields:
- gpio_pin: GPIO pin connected to the dimmer's gate control (0-39)
- phase: Phase identifier (0-3) - must be registered first
- initial_level: Starting brightness level (0-100%)
- curve_type: Brightness curve algorithm
Ejemplo:
rbdimmer_config_t config = {
.gpio_pin = 4,
.phase = 0,
.initial_level = 50,
.curve_type = RBDIMMER_CURVE_RMS
};Enumeraciones
rbdimmer_curve_t
typedef enum {
RBDIMMER_CURVE_LINEAR, // Linear curve (no RMS consideration)
RBDIMMER_CURVE_RMS, // RMS-compensated curve
RBDIMMER_CURVE_LOGARITHMIC, // Logarithmic curve (for LEDs)
RBDIMMER_CURVE_CUSTOM // Custom curve (reserved)
} rbdimmer_curve_t;Define el tipo de curva de brillo para el cálculo de potencia.
Tipos de Curva: - LINEAR: Conversión directa de porcentaje a ángulo de fase - RMS: Potencia compensada para cargas resistivas (bombillas incandescentes) - LOGARITHMIC: Lineal perceptivamente para cargas LED - CUSTOM: Reservado para implementación de curva personalizada futura
Limitación de nivel (v2.0.0): Todos los cálculos de curva aplican límites LEVEL_MIN y LEVEL_MAX. Los niveles >= 100% se limitan a RBDIMMER_LEVEL_MAX (99% por defecto). Los niveles por debajo de RBDIMMER_LEVEL_MIN (3% por defecto) devuelven delay = 0, lo que significa que el canal está APAGADO. Esto evita disparo TRIAC no confiable en ángulos de conducción casi cero o casi completos.
rbdimmer_err_t
typedef enum {
RBDIMMER_OK = 0, // Operation completed successfully
RBDIMMER_ERR_INVALID_ARG, // Invalid argument
RBDIMMER_ERR_NO_MEMORY, // Memory allocation failed
RBDIMMER_ERR_NOT_FOUND, // Object not found
RBDIMMER_ERR_ALREADY_EXIST, // Object already exists
RBDIMMER_ERR_TIMER_FAILED, // Timer initialization failed
RBDIMMER_ERR_GPIO_FAILED // GPIO initialization failed
} rbdimmer_err_t;Códigos de error devueltos por funciones de la biblioteca.
timer_state_t
typedef enum {
TIMER_STATE_IDLE, // Waiting for zero-crossing
TIMER_STATE_DELAY, // Waiting for delay to finish
TIMER_STATE_PULSE_ON, // Pulse is active, waiting to turn off
} timer_state_t;Enumeración de estado de temporizador interno (utilizada internamente por la biblioteca).
Constantes
Límites del Sistema
#define RBDIMMER_MAX_PHASES 4 // Maximum number of phases
#define RBDIMMER_MAX_CHANNELS 8 // Maximum number of channelsConstantes de Temporización
#define RBDIMMER_DEFAULT_PULSE_WIDTH_US 50 // Default pulse width in microseconds
#define RBDIMMER_MIN_DELAY_US 100 // Minimum delay for safe triac operation (was 50 in v1)Puerta de Ruido de Cruce Cero (v2.0.0)
#define RBDIMMER_ZC_DEBOUNCE_US 3000 // Noise gate window in microsecondsDespués de que se dispara una interrupción de cruce cero, las interrupciones posteriores dentro de esta ventana se ignoran. Esto elimina los disparos falsos causados por ruido eléctrico cerca del punto de cruce cero. El valor predeterminado de 3000 µs funciona bien tanto para 50 Hz como para 60 Hz (medio ciclo es 8333 µs a 60 Hz y 10000 µs a 50 Hz, por lo que 3 ms está seguramente por debajo de cualquiera).
Constantes de Límite de Nivel (v2.0.0)
#define RBDIMMER_LEVEL_MIN 3 // Levels below this -> OFF (delay = 0)
#define RBDIMMER_LEVEL_MAX 99 // Levels above this -> capped to this valueEstas constantes definen el rango operativo efectivo para todos los cálculos de curva:
- RBDIMMER_LEVEL_MIN (3%): Solicitar un nivel por debajo de este umbral produce un delay de 0, lo que significa que el TRIAC nunca se dispara y el canal está completamente APAGADO. Esto evita conducción parcial no confiable en ciclos de trabajo muy bajos.
- RBDIMMER_LEVEL_MAX (99%): Solicitar un nivel del 100% o superior se limita a este valor. Esto asegura que siempre se aplique un delay mínimo, evitando que el pulso TRIAC se superponga con el punto de cruce cero.
Configurabilidad: En proyectos ESP-IDF, estas constantes pueden ser anuladas a través de Kconfig (menuconfig). En proyectos Arduino, actúan como valores predeterminados en tiempo de compilación y pueden ser redefinidos antes de incluir el encabezado de la biblioteca.
Constantes de Frecuencia
#define RBDIMMER_DEFAULT_FREQUENCY 0 // Auto-detect frequency
#define RBDIMMER_FREQUENCY_MIN 45 // Minimum allowed frequency
#define RBDIMMER_FREQUENCY_MAX 65 // Maximum allowed frequency
#define RBDIMMER_MEASURE_CYCLES 10 // Number of cycles for measurementFunciones de Inicialización
rbdimmer_init()
rbdimmer_err_t rbdimmer_init(void);Inicializa la biblioteca rbdimmerESP32. Debe ser llamada antes de cualquier otra función de la biblioteca.
Devuelve:
- RBDIMMER_OK: Inicialización exitosa
- RBDIMMER_ERR_NO_MEMORY: Falló la asignación de memoria
Ejemplo:
void setup() {
rbdimmer_err_t err = rbdimmer_init();
if (err != RBDIMMER_OK) {
Serial.println("Failed to initialize rbdimmer library");
return;
}
Serial.println("rbdimmer initialized successfully");
}Notas: - Inicializa estructuras de datos internas - Prepara tablas de búsqueda para curvas de brillo - Debe ser llamada desde la tarea principal/función setup
rbdimmer_deinit()
rbdimmer_err_t rbdimmer_deinit(void);Desinicializa la biblioteca y libera todos los recursos.
Devuelve:
- RBDIMMER_OK: Desinicialization exitosa
Ejemplo:
void cleanup() {
rbdimmer_deinit();
Serial.println("Library deinitialized");
}Notas: - Elimina automáticamente todos los canales - Elimina todos los manejadores de interrupciones - Libera recursos GPIO - Llame antes de reiniciar el sistema o dormir profundamente
Gestión de Cruce Cero
rbdimmer_register_zero_cross()
rbdimmer_err_t rbdimmer_register_zero_cross(uint8_t pin, uint8_t phase, uint16_t frequency);Registra un detector de cruce cero para sincronización AC.
Parámetros:
- pin: Pin GPIO conectado al detector de cruce cero (0-39)
- phase: Identificador de fase (0-3)
- frequency: Frecuencia de red esperada en Hz (0 para auto-detección, 50, 60)
Devuelve:
- RBDIMMER_OK: Registro exitoso
- RBDIMMER_ERR_INVALID_ARG: Pin o número de fase inválido
- RBDIMMER_ERR_ALREADY_EXIST: Fase ya registrada
- RBDIMMER_ERR_NO_MEMORY: Máximo de fases alcanzado
- RBDIMMER_ERR_GPIO_FAILED: Falló la configuración de GPIO
Ejemplo:
// Auto-detect frequency on phase 0
rbdimmer_err_t err = rbdimmer_register_zero_cross(2, 0, 0);
if (err == RBDIMMER_OK) {
Serial.println("Zero-cross detector registered on pin 2");
}
// Fixed 60Hz frequency on phase 1
rbdimmer_register_zero_cross(3, 1, 60);Notas: - Debe ser llamada antes de crear canales en la misma fase - El pin será configurado como entrada con interrupción en flanco ascendente - Frecuencia 0 habilita la detección automática (recomendado) - Cada fase requiere un detector de cruce cero separado
Puerta de ruido (v2.0.0): Después de cada cruce cero detectado, el ISR ignora interrupciones adicionales en la misma fase durante RBDIMMER_ZC_DEBOUNCE_US microsegundos (3000 por defecto). Esto suprime disparos falsos causados por ruido, ringing o señales de cruce cero de aumento lento. La ventana de debounce se aplica por fase, por lo que los sistemas multifase se manejan independientemente.
Gestión de Canales
rbdimmer_create_channel()
rbdimmer_err_t rbdimmer_create_channel(rbdimmer_config_t* config, rbdimmer_channel_t** channel);Crea un nuevo canal dimmer con la configuración especificada.
Parámetros:
- config: Puntero a la estructura de configuración
- channel: Puntero para almacenar el identificador del canal creado
Devuelve:
- RBDIMMER_OK: Canal creado exitosamente
- RBDIMMER_ERR_INVALID_ARG: Configuración inválida o punteros NULL
- RBDIMMER_ERR_NOT_FOUND: Fase referenciada no registrada
- RBDIMMER_ERR_NO_MEMORY: Falló la asignación de memoria o máximo de canales alcanzado
- RBDIMMER_ERR_GPIO_FAILED: Falló la configuración de GPIO
- RBDIMMER_ERR_TIMER_FAILED: Falló la creación del temporizador
Ejemplo:
rbdimmer_channel_t* my_channel;
rbdimmer_config_t config = {
.gpio_pin = 4,
.phase = 0,
.initial_level = 0,
.curve_type = RBDIMMER_CURVE_RMS
};
rbdimmer_err_t err = rbdimmer_create_channel(&config, &my_channel);
if (err == RBDIMMER_OK) {
Serial.println("Channel created successfully");
}Notas: - El pin GPIO será configurado como salida - El canal comienza en estado activo - Se asignan dos temporizadores de hardware por canal - El nivel inicial se aplica inmediatamente
rbdimmer_delete_channel()
rbdimmer_err_t rbdimmer_delete_channel(rbdimmer_channel_t* channel);Elimina un canal dimmer y libera todos los recursos asociados.
Parámetros:
- channel: Identificador del canal a eliminar
Devuelve:
- RBDIMMER_OK: Canal eliminado exitosamente
- RBDIMMER_ERR_INVALID_ARG: Identificador de canal NULL
- RBDIMMER_ERR_NOT_FOUND: Canal no encontrado en el gestor
Ejemplo:
rbdimmer_err_t err = rbdimmer_delete_channel(my_channel);
if (err == RBDIMMER_OK) {
my_channel = NULL; // Prevent accidental reuse
Serial.println("Channel deleted successfully");
}Notas: - Detiene todos los temporizadores en ejecución - Establece la salida GPIO en LOW - Libera memoria asignada - El identificador del canal se vuelve inválido después de la eliminación
Control de Nivel
rbdimmer_set_level()
rbdimmer_err_t rbdimmer_set_level(rbdimmer_channel_t* channel, uint8_t level_percent);Establece el nivel de brillo de un canal dimmer inmediatamente.
Parámetros:
- channel: Identificador del canal destino
- level_percent: Nivel de brillo (0-100%)
Devuelve:
- RBDIMMER_OK: Nivel establecido exitosamente
- RBDIMMER_ERR_INVALID_ARG: Identificador de canal NULL
Ejemplo:
// Set to 50% brightness
rbdimmer_set_level(my_channel, 50);
// Turn off
rbdimmer_set_level(my_channel, 0);
// Full brightness (clamped to LEVEL_MAX = 99%)
rbdimmer_set_level(my_channel, 100);Notas: - Los cambios de nivel toman efecto en el próximo cruce cero - Los valores >= 100 se limitan a RBDIMMER_LEVEL_MAX (99%) - Los valores por debajo de RBDIMMER_LEVEL_MIN (3%) resultan en que el canal esté APAGADO (delay = 0) - Nivel 0 = completamente apagado - Seguro para hilos - puede ser llamado desde cualquier tarea
rbdimmer_set_level_transition()
rbdimmer_err_t rbdimmer_set_level_transition(rbdimmer_channel_t* channel, uint8_t level_percent, uint32_t transition_ms);Establece el nivel de brillo con una transición suave en el tiempo.
Parámetros:
- channel: Identificador del canal destino
- level_percent: Nivel de brillo objetivo (0-100%)
- transition_ms: Duración de la transición en milisegundos
Devuelve:
- RBDIMMER_OK: Transición iniciada exitosamente
- RBDIMMER_ERR_INVALID_ARG: Identificador de canal NULL
- RBDIMMER_ERR_NO_MEMORY: Falló la creación de la tarea de transición
Ejemplo:
// Fade to 75% over 3 seconds
rbdimmer_set_level_transition(my_channel, 75, 3000);
// Quick fade to off over 500ms
rbdimmer_set_level_transition(my_channel, 0, 500);Notas:
- Crea una tarea FreeRTOS para transiciones suaves
- No bloqueante - devuelve inmediatamente
- El tiempo mínimo de transición es 50ms
- Las transiciones más cortas que 50ms usan configuración inmediata
- Múltiples transiciones pueden ejecutarse simultáneamente en diferentes canales
- El nivel objetivo está sujeto a la misma limitación LEVEL_MIN / LEVEL_MAX que rbdimmer_set_level()
Funciones de Configuración
rbdimmer_set_curve()
rbdimmer_err_t rbdimmer_set_curve(rbdimmer_channel_t* channel, rbdimmer_curve_t curve_type);Establece el tipo de curva de brillo para un canal.
Parámetros:
- channel: Identificador del canal destino
- curve_type: Tipo de curva deseado
Devuelve:
- RBDIMMER_OK: Curva establecida exitosamente
- RBDIMMER_ERR_INVALID_ARG: Identificador de canal NULL
Ejemplo:
// For incandescent bulbs
rbdimmer_set_curve(my_channel, RBDIMMER_CURVE_RMS);
// For LED strips
rbdimmer_set_curve(my_channel, RBDIMMER_CURVE_LOGARITHMIC);
// For motor control
rbdimmer_set_curve(my_channel, RBDIMMER_CURVE_LINEAR);Notas: - El cambio toma efecto en el próximo cruce cero - Diferentes curvas optimizan para diferentes tipos de carga - Puede ser cambiado durante la operación sin reinicio - Todas las curvas aplican límites LEVEL_MIN / LEVEL_MAX
rbdimmer_set_active()
rbdimmer_err_t rbdimmer_set_active(rbdimmer_channel_t* channel, bool active);Habilita o deshabilita un canal dimmer.
Parámetros:
- channel: Identificador del canal destino
- active: true para habilitar, false para deshabilitar
Devuelve:
- RBDIMMER_OK: Estado cambiado exitosamente
- RBDIMMER_ERR_INVALID_ARG: Identificador de canal NULL
Ejemplo:
// Enable channel
rbdimmer_set_active(my_channel, true);
// Disable channel (output goes to 0)
rbdimmer_set_active(my_channel, false);Notas: - Los canales deshabilitados no consumen tiempo de CPU - La salida se establece inmediatamente en LOW cuando está deshabilitada - La configuración del canal se conserva cuando está deshabilitado - La reactivación reanuda la operación anterior
Recuperación de Información
rbdimmer_get_level()
uint8_t rbdimmer_get_level(rbdimmer_channel_t* channel);Obtiene el nivel de brillo actual de un canal.
Parámetros:
- channel: Identificador del canal a consultar
Devuelve: - Nivel de brillo actual (0-100%), o 0 si el canal es NULL
Ejemplo:
uint8_t current_level = rbdimmer_get_level(my_channel);
Serial.printf("Current brightness: %d%%\n", current_level);rbdimmer_get_frequency()
uint16_t rbdimmer_get_frequency(uint8_t phase);Obtiene la frecuencia de red medida para una fase específica.
Parámetros:
- phase: Número de fase a consultar (0-3)
Devuelve: - Frecuencia medida en Hz, o 0 si aún no se ha medido o la fase no se encontró
Ejemplo:
uint16_t freq = rbdimmer_get_frequency(0);
if (freq > 0) {
Serial.printf("Mains frequency: %d Hz\n", freq);
} else {
Serial.println("Frequency not measured yet");
}Notas: - Devuelve 0 durante el período de medición inicial - La detección de frecuencia toma aproximadamente 20 ciclos AC - Útil para monitoreo de calidad de potencia
rbdimmer_is_active()
bool rbdimmer_is_active(rbdimmer_channel_t* channel);Verifica si un canal está activo actualmente.
Parámetros:
- channel: Identificador del canal a consultar
Devuelve:
- true si el canal está activo, false si está inactivo o NULL
Ejemplo:
if (rbdimmer_is_active(my_channel)) {
Serial.println("Channel is active");
} else {
Serial.println("Channel is inactive");
}rbdimmer_get_curve()
rbdimmer_curve_t rbdimmer_get_curve(rbdimmer_channel_t* channel);Obtiene el tipo de curva actual de un canal.
Parámetros:
- channel: Identificador del canal a consultar
Devuelve:
- Tipo de curva actual, o RBDIMMER_CURVE_LINEAR si el canal es NULL
Ejemplo:
rbdimmer_curve_t curve = rbdimmer_get_curve(my_channel);
switch(curve) {
case RBDIMMER_CURVE_LINEAR:
Serial.println("Using linear curve");
break;
case RBDIMMER_CURVE_RMS:
Serial.println("Using RMS curve");
break;
case RBDIMMER_CURVE_LOGARITHMIC:
Serial.println("Using logarithmic curve");
break;
}rbdimmer_get_delay()
uint32_t rbdimmer_get_delay(rbdimmer_channel_t* channel);Obtiene la configuración de delay actual en microsegundos.
Parámetros:
- channel: Identificador del canal a consultar
Devuelve: - Delay actual en microsegundos, o 0 si el canal es NULL
Ejemplo:
uint32_t delay_us = rbdimmer_get_delay(my_channel);
Serial.printf("Current delay: %d microseconds\n", delay_us);Notas: - Útil para depuración y optimización - El delay varía con el nivel de brillo y tipo de curva - Medido desde cruce cero a disparo TRIAC - Devuelve 0 cuando el nivel está por debajo de RBDIMMER_LEVEL_MIN (canal APAGADO) - El valor no cero mínimo es RBDIMMER_MIN_DELAY_US (100 µs)
Funciones de Callback
rbdimmer_set_callback()
rbdimmer_err_t rbdimmer_set_callback(uint8_t phase, void (*callback)(void*), void* user_data);Establece una función de callback para ser llamada en eventos de cruce cero.
Parámetros:
- phase: Número de fase (0-3)
- callback: Función a llamar en cruce cero (NULL para deshabilitar)
- user_data: Puntero de datos de usuario pasado al callback
Devuelve:
- RBDIMMER_OK: Callback establecido exitosamente
- RBDIMMER_ERR_NOT_FOUND: Fase no registrada
Firma de Función de Callback:
void zero_cross_callback(void* user_data);Ejemplo:
typedef struct {
uint32_t cross_count;
unsigned long last_time;
} callback_data_t;
callback_data_t cb_data = {0, 0};
void my_zero_cross_callback(void* user_data) {
callback_data_t* data = (callback_data_t*)user_data;
data->cross_count++;
data->last_time = millis();
// Note: Keep ISR code minimal and fast!
if (data->cross_count % 100 == 0) {
// Schedule a task to print statistics
// Don't use Serial.print() directly in ISR!
}
}
// Register the callback
rbdimmer_set_callback(0, my_zero_cross_callback, &cb_data);Notas Importantes: - El callback se ejecuta en contexto de interrupción (ISR) - Mantenga el código del callback mínimo y rápido - No hay operaciones de bloqueo (delays, prints, etc.) - Use colas FreeRTOS para comunicación con tareas - El callback se llama en cada cruce cero (100-120 veces por segundo) - En v2.0.0, el callback se dispara solo para cruces cero válidos que pasan la puerta de ruido (debounce). Los disparos espurios dentro de RBDIMMER_ZC_DEBOUNCE_US de un cruce anterior no invocan el callback.
Funciones de Utilidad
rbdimmer_update_all()
rbdimmer_err_t rbdimmer_update_all(void);Fuerza una actualización inmediata de todos los canales activos.
Devuelve:
- RBDIMMER_OK: Todos los canales actualizados exitosamente
Ejemplo:
// After changing multiple channel parameters
rbdimmer_update_all();Notas: - Normalmente no es necesario - los canales se actualizan automáticamente - Útil después de cambios de configuración en bulk - Recalcula la temporización para todos los canales activos
Manejo de Errores
Descripción de Códigos de Error
| Código de Error | Descripción | Causas Comunes |
|---|---|---|
RBDIMMER_OK |
Éxito | Operación completada normalmente |
RBDIMMER_ERR_INVALID_ARG |
Argumento inválido | Punteros NULL, valores fuera de rango |
RBDIMMER_ERR_NO_MEMORY |
Falló la asignación de memoria | Memoria heap insuficiente |
RBDIMMER_ERR_NOT_FOUND |
Objeto no encontrado | Fase no registrada, canal no encontrado |
RBDIMMER_ERR_ALREADY_EXIST |
Objeto ya existe | Fase ya registrada |
RBDIMMER_ERR_TIMER_FAILED |
Falló la operación del temporizador | Temporizador de hardware no disponible |
RBDIMMER_ERR_GPIO_FAILED |
Falló la operación de GPIO | Pin inválido, pin ya en uso |
Mejores Prácticas de Manejo de Errores
rbdimmer_err_t err;
rbdimmer_channel_t* channel;
// Always check return values
err = rbdimmer_init();
if (err != RBDIMMER_OK) {
Serial.printf("Initialization failed: %d\n", err);
return;
}
// Handle specific error conditions
err = rbdimmer_register_zero_cross(2, 0, 0);
switch (err) {
case RBDIMMER_OK:
Serial.println("Zero-cross registered successfully");
break;
case RBDIMMER_ERR_ALREADY_EXIST:
Serial.println("Phase already registered - continuing");
break;
case RBDIMMER_ERR_GPIO_FAILED:
Serial.println("GPIO configuration failed - check wiring");
return;
default:
Serial.printf("Unexpected error: %d\n", err);
return;
}Ejemplos de Código
Configuración Básica Completa
#include
rbdimmer_channel_t* dimmer;
void setup() {
Serial.begin(115200);
// Initialize library
if (rbdimmer_init() != RBDIMMER_OK) {
Serial.println("Library initialization failed");
return;
}
// Register zero-cross detector
if (rbdimmer_register_zero_cross(2, 0, 0) != RBDIMMER_OK) {
Serial.println("Zero-cross registration failed");
return;
}
// Create dimmer channel
rbdimmer_config_t config = {
.gpio_pin = 4,
.phase = 0,
.initial_level = 0,
.curve_type = RBDIMMER_CURVE_RMS
};
if (rbdimmer_create_channel(&config, &dimmer) != RBDIMMER_OK) {
Serial.println("Channel creation failed");
return;
}
Serial.println("Setup complete");
}
void loop() {
// Fade up over 2 seconds
rbdimmer_set_level_transition(dimmer, 100, 2000);
delay(3000);
// Fade down over 1 second
rbdimmer_set_level_transition(dimmer, 0, 1000);
delay(2000);
} Control Multicanal
#include
#define NUM_CHANNELS 3
rbdimmer_channel_t* channels[NUM_CHANNELS];
uint8_t dimmer_pins[] = {4, 5, 6};
void setup() {
Serial.begin(115200);
rbdimmer_init();
rbdimmer_register_zero_cross(2, 0, 0);
// Create multiple channels
for (int i = 0; i < NUM_CHANNELS; i++) {
rbdimmer_config_t config = {
.gpio_pin = dimmer_pins[i],
.phase = 0,
.initial_level = 0,
.curve_type = RBDIMMER_CURVE_RMS
};
rbdimmer_create_channel(&config, &channels[i]);
}
Serial.println("Multi-channel setup complete");
}
void loop() {
// Sequential fade effect
for (int i = 0; i < NUM_CHANNELS; i++) {
rbdimmer_set_level_transition(channels[i], 100, 1000);
delay(500);
}
delay(2000);
// All off together
for (int i = 0; i < NUM_CHANNELS; i++) {
rbdimmer_set_level_transition(channels[i], 0, 1000);
}
delay(2000);
} Uso de Callback Avanzado
#include
typedef struct {
uint32_t zero_cross_count;
uint16_t frequency;
bool frequency_stable;
} system_stats_t;
system_stats_t stats = {0, 0, false};
rbdimmer_channel_t* dimmer;
void zero_cross_isr(void* user_data) {
system_stats_t* s = (system_stats_t*)user_data;
s->zero_cross_count++;
// Check frequency every 100 crossings (avoid frequent updates)
if (s->zero_cross_count % 100 == 0) {
s->frequency = rbdimmer_get_frequency(0);
s->frequency_stable = (s->frequency == 50 || s->frequency == 60);
}
}
void setup() {
Serial.begin(115200);
rbdimmer_init();
rbdimmer_register_zero_cross(2, 0, 0);
// Set up callback for monitoring
rbdimmer_set_callback(0, zero_cross_isr, &stats);
rbdimmer_config_t config = {
.gpio_pin = 4,
.phase = 0,
.initial_level = 50,
.curve_type = RBDIMMER_CURVE_RMS
};
rbdimmer_create_channel(&config, &dimmer);
}
void loop() {
// Print statistics every 5 seconds
static unsigned long last_print = 0;
if (millis() - last_print > 5000) {
Serial.printf("Zero crossings: %d\n", stats.zero_cross_count);
Serial.printf("Frequency: %d Hz\n", stats.frequency);
Serial.printf("Frequency stable: %s\n", stats.frequency_stable ? "Yes" : "No");
Serial.printf("Current level: %d%%\n", rbdimmer_get_level(dimmer));
Serial.println("---");
last_print = millis();
}
delay(100);
} Consideraciones de Rendimiento
Uso de Memoria
- Cada canal utiliza aproximadamente 200 bytes de RAM
- Sobrecarga de biblioteca global: ~1KB RAM
- Uso de memoria flash: ~32KB
Precisión de Temporización
- Detección de cruce cero: +/-10 microsegundos (después del filtrado de puerta de ruido)
- Disparo TRIAC: +/-1 microsegundo
- Medición de frecuencia: +/-0.1 Hz
Sobrecarga de CPU
- Manejo de interrupciones: <50 microsegundos por cruce cero
- Procesamiento en background: <1% de uso de CPU
- Tareas de transición: Impacto mínimo en otras operaciones
Limitaciones
- Máximo 8 canales por ESP32
- Máximo 4 fases independientes
- Ancho de pulso mínimo: 50 microsegundos
- Delay de disparo mínimo: 100 microsegundos (RBDIMMER_MIN_DELAY_US)
- Rango de dimming efectivo: 3%-99% (RBDIMMER_LEVEL_MIN a RBDIMMER_LEVEL_MAX)
- Tiempo de transición máximo: Limitado por memoria disponible para tareas
Esta referencia de API cubre todas las funciones públicas y tipos de datos en rbdimmerESP32 v2.0.0