Zum Inhalt springen

← - Arduino-Anleitung und Beispiele. | Inhalt | Weiter: ESPHome-Komponente →

ESP-IDF Anleitung & Beispiele

Universelle Dimmer-Bibliothek für ESP32. ESP-IDF Framework C-Anleitung und Beispiele.

Vor dem Start die Bibliotheksübersicht lesen: Universelle Bibliothek für ESP32

Anforderungen und Kompatibilität

  • Minimale ESP-IDF-Version: 5.3
  • Unterstützte Chips: ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6
  • Die Bibliothek verwendet Standard-Kconfig für die Build-Konfiguration (umbenennt von Kconfig.txt in v2.0.0)

Neu in v2.0.0

Version 2.0.0 ist ein großes internes Rewrite. Die öffentliche API ist vollständig abwärtskompatibel — keine Änderungen an Ihrem Anwendungscode erforderlich.

Interne Verbesserungen:

  • Modulare Architektur — der Codebase ist in 7 interne Module aufgeteilt (Phase Engine, Channel Manager, Curve Tables, ISR Core, etc.). Der einzelne öffentliche Header rbdimmerESP32.h bleibt das einzige Include, das Sie benötigen.
  • Alle ISRs verwenden IRAM_ATTR und Timer verwenden ESP_TIMER_ISR Dispatch für deterministische Sub-Mikrosekunden-Timing.
  • Zero-Cross Noise Gate — ein konfigurierbares Debounce-Fenster lehnt elektrische Geräusche und falsche Trigger auf dem Zero-Cross-Eingang ab. Standard: 3000 µs.
  • Zwei-Pass ISR für Multi-Channel-Synchronisation — wenn mehrere Kanäle eine Phase teilen, sortiert der ISR diese vor nach Verzögerung und zündet TRIAC-Impulse in einem einzigen konsolidierten Pass, wodurch Timing-Jitter zwischen Kanälen eliminiert wird.
  • Kconfig Build-Konfiguration — die Datei heißt jetzt Kconfig (Standard ESP-IDF-Konvention; zuvor Kconfig.txt).

Neue Kconfig-Parameter:

Parameter Standard Beschreibung
CONFIG_RBDIMMER_ZC_DEBOUNCE_US 3000 Zero-Cross Debounce-Fenster in Mikrosekunden
CONFIG_RBDIMMER_MIN_DELAY_US 100 Minimale TRIAC-Zündeverzögerung in Mikrosekunden
CONFIG_RBDIMMER_LEVEL_MIN 3 Minimales Dimminglevel (%). Werte unter diesem werden als AUS behandelt
CONFIG_RBDIMMER_LEVEL_MAX 99 Maximales Dimminglevel (%)

Installation

Mit CMake und ESP-IDF

  1. Laden Sie die rbdimmerESP32-Bibliothek aus dem GitHub-Repository herunter:
bash
git clone https://github.com/your-username/rbdimmerESP32 components/rbdimmer
  1. Configure your project's CMakeLists.txt to include the library:
cmake
# Main project CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(your_project_name)
  1. Add component dependency in your application's CMakeLists.txt:
cmake
# App CMakeLists.txt
idf_component_register(
    SRCS "main.c"
    INCLUDE_DIRS "."
    REQUIRES rbdimmer
)
  1. The library's CMakeLists.txt and Kconfig are included automatically when placed in components/rbdimmer/. The component CMakeLists.txt registers sources, includes, and dependencies:
cmake
# components/rbdimmer/CMakeLists.txt
idf_component_register(
    SRCS "rbdimmerESP32.c"
    INCLUDE_DIRS "include"
    REQUIRES driver esp_timer freertos
)

Kconfig Konfiguration

Die Bibliothek stellt Tuning-Parameter über das ESP-IDF menuconfig-System bereit. Um sie anzupassen:

bash
idf.py menuconfig
# Navigate to: Component config → RBDimmer Configuration

Verfügbare Optionen:

  • Zero-Cross Debounce (us)CONFIG_RBDIMMER_ZC_DEBOUNCE_US (Standard 3000). Erhöhen Sie diesen Wert, wenn Sie falsche Zero-Cross-Trigger durch elektrisches Rauschen sehen.
  • Minimale TRIAC-Verzögerung (us)CONFIG_RBDIMMER_MIN_DELAY_US (Standard 100). Verhindert, dass der TRIAC zu nah am Zero-Cross zündet, was Flackern bei hoher Helligkeit verursachen kann.
  • Level Min (%)CONFIG_RBDIMMER_LEVEL_MIN (Standard 3). Level unter diesem Schwellenwert werden als AUS behandelt, um instabiles TRIAC-Verhalten zu vermeiden.
  • Level Max (%)CONFIG_RBDIMMER_LEVEL_MAX (Standard 99). Begrenzt den maximalen Zündwinkel.

Hardwareverbindung

Anweisungen zum Verbinden des Dimmers mit dem Mikrocontroller und der AC-Last:

  • Verbinden Sie den Zero-Cross-Pin mit jedem GPIO, der ISR-Funktionalität hat. Überprüfen Sie die Dokumentation Ihres ESP32-Chips
  • Verbinden Sie den Dimmer-Pin mit jedem GPIO
  • VCC mit 3,3 V (für ESP32, VCC = 3,3 V)
  • GND mit GND

Basis-Beispiel (ESP-IDF / C)

c
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "rbdimmerESP32.h"
static const char *TAG = "DIMMER_EXAMPLE";
// Pins
#define ZERO_CROSS_PIN  18   // Zero-Cross pin
#define DIMMER_PIN      19   // Dimming control pin
#define PHASE_NUM       0    // Phase N (0 for single phase)
// Global variables. Dimmer object
rbdimmer_channel_t* dimmer_channel = NULL;
void app_main(void)
{
    ESP_LOGI(TAG, "AC Dimmer Test");
    // Dimmer lib init
    if (rbdimmer_init() != RBDIMMER_OK) {
        ESP_LOGE(TAG, "Failed to initialize AC Dimmer library");
        return;
    }
    // Zero-cross detector and phase registry
    if (rbdimmer_register_zero_cross(ZERO_CROSS_PIN, PHASE_NUM, 0) != RBDIMMER_OK) {
        ESP_LOGE(TAG, "Failed to register zero-cross detector");
        return;
    }
    // Dimmer channel. Configuration data structure.
    rbdimmer_config_t config_channel = {
        .gpio_pin = DIMMER_PIN,
        .phase = PHASE_NUM,
        .initial_level = 50,  // Initial dimming level 50%
        .curve_type = RBDIMMER_CURVE_RMS  // Level Curve Selection. RMS-curve
    };
    if (rbdimmer_create_channel(&config_channel, &dimmer_channel) != RBDIMMER_OK) {
        ESP_LOGE(TAG, "Failed to create dimmer channel");
        return;
    }
    ESP_LOGI(TAG, "AC Dimmer initialized successfully");
    // Main loop
    while (1) {
        // dimming from 10% to 90% with step 10
        for (int brightness = 10; brightness <= 90; brightness += 10) {
            ESP_LOGI(TAG, "Setting brightness to %d%%", brightness);
            rbdimmer_set_level(dimmer_channel, brightness);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
        }
        // Smooth transition from current level to 0 level in 5 sec
        ESP_LOGI(TAG, "Smooth transition to 0%%");
        rbdimmer_set_level_transition(dimmer_channel, 0, 5000);
        vTaskDelay(6000 / portTICK_PERIOD_MS); // delay 6 sec
        // Smooth transition from current level (0) to 100 level in 5 sec
        ESP_LOGI(TAG, "Smooth transition to 100%%");
        rbdimmer_set_level_transition(dimmer_channel, 100, 5000);
        vTaskDelay(6000 / portTICK_PERIOD_MS); // delay 6 sec
    }
}

API-Referenz

Bibliotheksbetrieb

Vorbereitung:

  1. Initialisieren Sie die Bibliothek mit rbdimmer_init()
  2. Registrieren Sie den Zero-Crossing-Detektor mit rbdimmer_register_zero_cross()
  3. Erstellen Sie einen Dimmer-Kanal mit rbdimmer_create_channel()

Dimmsteuerung:

  • Stellen Sie das Dimminglevel mit rbdimmer_set_level() ein. Das Dimminglevel wird im Bereich 0(AUS) ~ 100(AN) eingestellt
  • Sanfte Dimminglevel-Übergang mit rbdimmer_set_level_transition(). Sanfter Übergang vom aktuellen Level zum eingestellten Level über einen Zeitraum (in Millisekunden, 1s=1000ms)

Datenstrukturen

rbdimmer_config_t

c
typedef struct {
    uint8_t gpio_pin;                 // Dimmer GPIO
    uint8_t phase;                    // Phase number
    uint8_t initial_level;            // Initial dimming level
    rbdimmer_curve_t curve_type;      // Level Curve type
} rbdimmer_config_t;

Enumerationen

rbdimmer_curve_t

Typen von Levelkurven:

c
typedef enum {
    RBDIMMER_CURVE_LINEAR,      // Linear curve
    RBDIMMER_CURVE_RMS,         // RMS-compensated curve (for incandescent bulbs)
    RBDIMMER_CURVE_LOGARITHMIC  // Logarithmic curve (for dimmable LED)
} rbdimmer_curve_t;

rbdimmer_err_t

Bibliotheks-Funktionsantworten:

c
typedef enum {
    RBDIMMER_OK = 0,            // Successful execution
    RBDIMMER_ERR_INVALID_ARG,   // Invalid argument
    RBDIMMER_ERR_NO_MEMORY,     // Not enough memory
    RBDIMMER_ERR_NOT_FOUND,     // Object not found
    RBDIMMER_ERR_ALREADY_EXIST, // Object already exists
    RBDIMMER_ERR_TIMER_FAILED,  // Timer initialization error
    RBDIMMER_ERR_GPIO_FAILED    // GPIO initialization error
} rbdimmer_err_t;

Konstanten und Makros

In v2.0.0 wurden die meisten Tuning-Parameter zu Kconfig verschoben (siehe Kconfig Konfiguration oben). Die folgenden Konstanten bleiben in rbdimmerESP32.h:

c
#define RBDIMMER_MAX_PHASES 4                 // Maximum number of phases
#define RBDIMMER_MAX_CHANNELS 8               // Maximum number of channels
#define RBDIMMER_DEFAULT_PULSE_WIDTH_US 50    // Pulse width (us)

Die folgenden sind jetzt konfigurierbar über idf.py menuconfig:

c
// Kconfig defaults (override via menuconfig):
// CONFIG_RBDIMMER_ZC_DEBOUNCE_US  = 3000   // Zero-cross debounce (us)
// CONFIG_RBDIMMER_MIN_DELAY_US    = 100    // Minimum TRIAC delay (us)
// CONFIG_RBDIMMER_LEVEL_MIN       = 3      // Minimum level (%)
// CONFIG_RBDIMMER_LEVEL_MAX       = 99     // Maximum level (%)

Funktionen

Initialisierung und Setup

c
// Initialize the library
rbdimmer_err_t rbdimmer_init(void);
// Register a zero-cross detector
rbdimmer_err_t rbdimmer_register_zero_cross(uint8_t pin, uint8_t phase, uint16_t frequency);
// Create a dimmer channel
rbdimmer_err_t rbdimmer_create_channel(rbdimmer_config_t* config, rbdimmer_channel_t** channel);
// Set callback function for zero-cross events
rbdimmer_err_t rbdimmer_set_callback(uint8_t phase, void (*callback)(void*), void* user_data);

Dimmsteuerung

c
// Set dimming level
rbdimmer_err_t rbdimmer_set_level(rbdimmer_channel_t* channel, uint8_t level_percent);
// Set brightness with smooth transition
rbdimmer_err_t rbdimmer_set_level_transition(rbdimmer_channel_t* channel, uint8_t level_percent, uint32_t transition_ms);
// Set brightness curve type
rbdimmer_err_t rbdimmer_set_curve(rbdimmer_channel_t* channel, rbdimmer_curve_t curve_type);
// Activate/deactivate channel
rbdimmer_err_t rbdimmer_set_active(rbdimmer_channel_t* channel, bool active);

Informationsabfragen

c
// Get current channel brightness
uint8_t rbdimmer_get_level(rbdimmer_channel_t* channel);
// Get measured mains frequency for the specified phase
uint16_t rbdimmer_get_frequency(uint8_t phase);
// Check if channel is active
bool rbdimmer_is_active(rbdimmer_channel_t* channel);
// Get channel curve type
rbdimmer_curve_t rbdimmer_get_curve(rbdimmer_channel_t* channel);
// Get current channel delay
uint32_t rbdimmer_get_delay(rbdimmer_channel_t* channel);

Schritt-für-Schritt Anleitung

Projektstruktur

text
your_project/
├── CMakeLists.txt
├── main/
│   ├── CMakeLists.txt
│   └── main.c
└── components/
    └── rbdimmer/
        ├── CMakeLists.txt
        ├── Kconfig
        ├── include/
        │   └── rbdimmer.h
        └── rbdimmerESP32.c

Implementierungsschritte

  1. Definieren Sie die Bibliothek und Pins in Ihrer main.c Datei:
c
#include "rbdimmer.h"
// Pins
#define ZERO_CROSS_PIN  18   // Zero-Cross pin
#define DIMMER_PIN      19   // Dimming control pin
#define PHASE_NUM       0    // Phase N (0 for single phase)
  1. Erstellen Sie ein Dimmer-Objekt (eines für jeden Dimmer):
c
rbdimmer_channel_t* dimmer_channel = NULL;
  1. Initialisieren Sie die Dimmer-Bibliothek:
c
rbdimmer_init();
  1. Registrieren Sie den Zero-Cross-Detektor und die Phase:
c
rbdimmer_register_zero_cross(ZERO_CROSS_PIN, PHASE_NUM, 0);
  1. Konfigurieren Sie den Dimmer-Kanal und erstellen Sie ihn:
c
rbdimmer_config_t config_channel = {
    .gpio_pin = DIMMER_PIN,
    .phase = PHASE_NUM,
    .initial_level = 50,  // Initial dimming level 50%
    .curve_type = RBDIMMER_CURVE_RMS  // Level Curve Selection. RMS-curve
};
rbdimmer_create_channel(&config_channel, &dimmer_channel);
  1. Steuern Sie das Dimmen:
c
// Set specific level
rbdimmer_set_level(dimmer_channel, level);
// Smooth transition
rbdimmer_set_level_transition(dimmer_channel, 0, 5000);

Erweiterte Beispiele

Multi-Channel Dimmer-Systeme

c
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "rbdimmer.h"
#define ZERO_CROSS_PIN  18
#define DIMMER_PIN_1    19
#define DIMMER_PIN_2    21
#define PHASE_NUM       0
static const char *TAG = "DIMMER_EXAMPLE";
rbdimmer_channel_t* channel1 = NULL;
rbdimmer_channel_t* channel2 = NULL;
void app_main(void)
{
    // Initialize library
    rbdimmer_init();
    // Register zero-cross detector (one per phase)
    rbdimmer_register_zero_cross(ZERO_CROSS_PIN, PHASE_NUM, 0);
    // Create first channel (incandescent bulbs)
    rbdimmer_config_t config1 = {
        .gpio_pin = DIMMER_PIN_1,
        .phase = PHASE_NUM,
        .initial_level = 50,
        .curve_type = RBDIMMER_CURVE_RMS
    };
    rbdimmer_create_channel(&config1, &channel1);
    // Create second channel (dimmable LED lighting)
    rbdimmer_config_t config2 = {
        .gpio_pin = DIMMER_PIN_2,
        .phase = PHASE_NUM,
        .initial_level = 50,
        .curve_type = RBDIMMER_CURVE_LOGARITHMIC
    };
    rbdimmer_create_channel(&config2, &channel2);
    // Main control loop
    while (1) {
        // Control channels independently
        rbdimmer_set_level(channel1, 75);
        rbdimmer_set_level(channel2, 25);
        vTaskDelay(2000 / portTICK_PERIOD_MS);
        rbdimmer_set_level(channel1, 25);
        rbdimmer_set_level(channel2, 75);
        vTaskDelay(2000 / portTICK_PERIOD_MS);
    }
}

Verwendung von Zero-Cross Interrupt Callback-Funktionen

c
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "rbdimmer.h"
#define ZERO_CROSS_PIN  18
#define DIMMER_PIN      19
#define LED_PIN         2  // Built-in LED for zero-cross visualization
#define PHASE_NUM       0
static const char *TAG = "DIMMER_CALLBACK";
rbdimmer_channel_t* dimmer = NULL;
QueueHandle_t zero_cross_queue;
// Simple message for our queue
typedef struct {
    uint32_t timestamp;
} ZeroCrossEvent_t;
// Callback function for zero-cross events
void zero_cross_callback(void* arg)
{
    ZeroCrossEvent_t event;
    event.timestamp = esp_timer_get_time() / 1000; // Current time in ms
    // Send to queue from ISR
    BaseType_t higher_priority_task_woken = pdFALSE;
    xQueueSendFromISR(zero_cross_queue, &event, &higher_priority_task_woken);
    if (higher_priority_task_woken) {
        portYIELD_FROM_ISR();
    }
}
// Task to process zero-cross events
void zero_cross_processing_task(void *pvParameters)
{
    ZeroCrossEvent_t event;
    while (1) {
        if (xQueueReceive(zero_cross_queue, &event, portMAX_DELAY)) {
            // Toggle LED to visualize zero-crossing
            gpio_set_level(LED_PIN, !gpio_get_level(LED_PIN));
            // Additional processing can be done here safely
            ESP_LOGI(TAG, "Zero-cross event at time: %lu ms", event.timestamp);
        }
    }
}
void app_main(void)
{
    // Setup LED
    gpio_reset_pin(LED_PIN);
    gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
    // Create the queue
    zero_cross_queue = xQueueCreate(10, sizeof(ZeroCrossEvent_t));
    if (zero_cross_queue == NULL) {
        ESP_LOGE(TAG, "Failed to create queue");
        return;
    }
    // Create the task to process zero-cross events
    BaseType_t task_created = xTaskCreate(
        zero_cross_processing_task,
        "ZeroCrossTask",
        2048,
        NULL,
        5,
        NULL
    );
    if (task_created != pdPASS) {
        ESP_LOGE(TAG, "Failed to create task");
        return;
    }
    // Initialize dimmer
    rbdimmer_init();
    rbdimmer_register_zero_cross(ZERO_CROSS_PIN, PHASE_NUM, 0);
    // Register callback
    rbdimmer_set_callback(PHASE_NUM, zero_cross_callback, NULL);
    // Create dimmer channel
    rbdimmer_config_t config = {
        .gpio_pin = DIMMER_PIN,
        .phase = PHASE_NUM,
        .initial_level = 60,
        .curve_type = RBDIMMER_CURVE_RMS
    };
    rbdimmer_create_channel(&config, &dimmer);
    ESP_LOGI(TAG, "Dimmer with callback initialized");
    // Main loop - print frequency information
    while (1) {
        uint16_t frequency = rbdimmer_get_frequency(PHASE_NUM);
        ESP_LOGI(TAG, "Detected frequency: %u Hz", frequency);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

Multi-Phase-Systeme

c
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "rbdimmer.h"
#define ZERO_CROSS_PIN_PHASE_A  18
#define ZERO_CROSS_PIN_PHASE_B  19
#define ZERO_CROSS_PIN_PHASE_C  21
#define DIMMER_PIN_PHASE_A      22
#define DIMMER_PIN_PHASE_B      23
#define DIMMER_PIN_PHASE_C      25
#define PHASE_A  0
#define PHASE_B  1
#define PHASE_C  2
static const char *TAG = "DIMMER_MULTIPHASE";
rbdimmer_channel_t* channel_a = NULL;
rbdimmer_channel_t* channel_b = NULL;
rbdimmer_channel_t* channel_c = NULL;
void app_main(void)
{
    // Initialize library
    rbdimmer_init();
    // Register zero-cross detectors for each phase
    rbdimmer_register_zero_cross(ZERO_CROSS_PIN_PHASE_A, PHASE_A, 0);
    rbdimmer_register_zero_cross(ZERO_CROSS_PIN_PHASE_B, PHASE_B, 0);
    rbdimmer_register_zero_cross(ZERO_CROSS_PIN_PHASE_C, PHASE_C, 0);
    // Create channels for each phase
    rbdimmer_config_t config_a = {
        .gpio_pin = DIMMER_PIN_PHASE_A,
        .phase = PHASE_A,
        .initial_level = 50,
        .curve_type = RBDIMMER_CURVE_RMS
    };
    rbdimmer_create_channel(&config_a, &channel_a);
    rbdimmer_config_t config_b = {
        .gpio_pin = DIMMER_PIN_PHASE_B,
        .phase = PHASE_B,
        .initial_level = 50,
        .curve_type = RBDIMMER_CURVE_RMS
    };
    rbdimmer_create_channel(&config_b, &channel_b);
    rbdimmer_config_t config_c = {
        .gpio_pin = DIMMER_PIN_PHASE_C,
        .phase = PHASE_C,
        .initial_level = 50,
        .curve_type = RBDIMMER_CURVE_RMS
    };
    rbdimmer_create_channel(&config_c, &channel_c);
    ESP_LOGI(TAG, "Multi-phase dimmer system initialized");
    // Main control loop
    while (1) {
        // Control phases with different levels
        ESP_LOGI(TAG, "Setting phase A: 75%%, phase B: 50%%, phase C: 25%%");
        rbdimmer_set_level(channel_a, 75);
        rbdimmer_set_level(channel_b, 50);
        rbdimmer_set_level(channel_c, 25);
        vTaskDelay(3000 / portTICK_PERIOD_MS);
        ESP_LOGI(TAG, "Setting phase A: 25%%, phase B: 50%%, phase C: 75%%");
        rbdimmer_set_level(channel_a, 25);
        rbdimmer_set_level(channel_b, 50);
        rbdimmer_set_level(channel_c, 75);
        vTaskDelay(3000 / portTICK_PERIOD_MS);
    }
}

Betriebsüberwachung und Fehlersuche

c
void print_dimmer_status(rbdimmer_channel_t* channel, uint8_t phase)
{
    ESP_LOGI(TAG, "=== Dimmer Status ===");
    ESP_LOGI(TAG, "Mains frequency: %d Hz", rbdimmer_get_frequency(phase));
    ESP_LOGI(TAG, "Brightness: %d%%", rbdimmer_get_level(channel));
    ESP_LOGI(TAG, "Active: %s", rbdimmer_is_active(channel) ? "Yes" : "No");
    ESP_LOGI(TAG, "Curve type: %d", rbdimmer_get_curve(channel));
    ESP_LOGI(TAG, "Delay: %d us", rbdimmer_get_delay(channel));
    ESP_LOGI(TAG, "====================");
}

Fehlerbehebung

Allgemein

  • If the dimmer doesn't work correctly, check your hardware connections, especially the zero-cross detector
  • Stellen Sie sicher, dass der Zero-Cross-Pin mit einem GPIO verbunden ist, der Interrupts unterstützt
  • Verwenden Sie ESP_LOG Funktionen, um die Operation in Echtzeit zu überwachen
  • Für Multi-Channel-Systeme stellen Sie sicher, dass jeder Dimmer-Kanal einen separaten GPIO-Pin hat
  • Die Bibliothek unterstützt automatische Frequenzerkennung. Wenn Sie die Netzfrequenz in Ihrer Region kennen (normalerweise 50 Hz oder 60 Hz), können Sie sie explizit für bessere anfängliche Leistung einstellen

Flackern und Stabilitätsprobleme (v2.0.0 Fixes)

Zufälliges Flackern oder falsche Trigger: Das Zero-Cross Noise Gate (CONFIG_RBDIMMER_ZC_DEBOUNCE_US, Standard 3000 µs) filtert elektrisches Rauschen auf der Zero-Cross-Leitung. Wenn Sie immer noch zufälliges Flackern sehen, versuchen Sie, den Debounce-Wert über idf.py menuconfig zu erhöhen.

Flackern bei 100% (vollständige Helligkeit): Die minimale TRIAC-Verzögerung (CONFIG_RBDIMMER_MIN_DELAY_US, Standard 100 µs) verhindert, dass der TRIAC zu nah an der Zero-Cross-Kante zündet. Der Standard von 100 µs in v2.0.0 löst das Flackern auf, das beim vorherigen Standard von 50 µs auftrat.

Instabiles Verhalten unter 3%: Level unter CONFIG_RBDIMMER_LEVEL_MIN (Standard 3%) werden jetzt als AUS behandelt. Der TRIAC kann die Leitung bei sehr niedrigen Zündwinkeln nicht zuverlässig aufrechterhalten, daher klemmt die Bibliothek an AUS, anstatt erratische Ausgabe zu erzeugen.

Multi-Channel-Jitter: Wenn mehrere Kanäle die gleiche Phase teilen, verwendet v2.0.0 einen Zwei-Pass-ISR, der Kanäle nach Verzögerung vorsortiert und sie in einer einzigen Unterunterbrechung nacheinander zündet. Dies eliminiert das Timing-Jitter, das auftreten konnte, wenn Kanäle ähnliche Verzögerungswerte in früheren Versionen hatten.

Continuous Integration

Die Bibliothek wird in CI gegen die folgende Matrix getestet:

  • ESP-IDF Versionen: v5.3, v5.4, v5.5
  • Target-Chips: ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6

Dies stellt sicher, dass jede Commit sauber über den gesamten Bereich unterstützter Konfigurationen kompiliert wird.

Änderungsprotokoll

Eine vollständige Liste der Änderungen finden Sie unter CHANGELOG.md.

← - Arduino-Anleitung und Beispiele. | Inhalt | Weiter: ESPHome-Komponente →