From 5dfc8b9033916bf70638d66d9c9f061940a372b4 Mon Sep 17 00:00:00 2001 From: Alexey Zholtikov Date: Mon, 31 Aug 2026 12:36:19 +0300 Subject: [PATCH] doc: updated readme --- README.md | 56 ++++++-- WIKI_EN.md | 394 ----------------------------------------------------- WIKI_RU.md | 394 ----------------------------------------------------- 3 files changed, 45 insertions(+), 799 deletions(-) delete mode 100644 WIKI_EN.md delete mode 100644 WIKI_RU.md diff --git a/README.md b/README.md index fe894ba..df60f42 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ # ESP32 ESP-IDF component for AC dimmer for 115V/400Hz -## Wiki - -[EN](WIKI_EN.md) | [RU](WIKI_RU.md) - -## Tested on - -1. [ESP32 ESP-IDF v6.0.0](https://docs.espressif.com/projects/esp-idf/en/v6.0/esp32/index.html) - ## SAST Tools [PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) — static analyzer for C, C++, C#, and Java code. @@ -19,11 +11,22 @@ 3. IRAM-safe ISR and callback functions for reliable operation. 4. Thread-safe start/stop/set/get API. +## Note + +Enable the following settings in menuconfig: + +```text +GPIO_CTRL_FUNC_IN_IRAM +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM +CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM +CONFIG_GPTIMER_ISR_CACHE_SAFE +``` + ## Using In an existing project, run the following command to install the component: -```text +```bash cd ../your_project/components git clone https://github.com/aZholtikov/zh_ac_dimmer ``` @@ -34,6 +37,37 @@ In the application, add the component: #include "zh_ac_dimmer.h" ``` -## Examples +## Example -See Wiki [EN](WIKI_EN.md#usage-examples) | [RU](WIKI_RU.md#примеры-использования) +```c +#include "zh_ac_dimmer.h" + +zh_ac_dimmer_handle_t *ac_dimmer_handle = NULL; + +void app_main(void) +{ + esp_log_level_set("zh_ac_dimmer", ESP_LOG_ERROR); + zh_ac_dimmer_init_config_t config = ZH_AC_DIMMER_INIT_CONFIG_DEFAULT(); + config.zero_cross_gpio = GPIO_NUM_16; + config.triac_gpio = GPIO_NUM_17; + zh_ac_dimmer_init(&config, &ac_dimmer_handle); + zh_ac_dimmer_start(&ac_dimmer_handle); + uint8_t value = 0; + for (uint8_t i = 0; i <= 100; ++i) + { + zh_ac_dimmer_set(&ac_dimmer_handle, i); + zh_ac_dimmer_get(&ac_dimmer_handle, &value); + printf("Dimmer value: %d.\n", value); + vTaskDelay(100 / portTICK_PERIOD_MS); + } + for (uint8_t i = 100; i > 0; --i) + { + zh_ac_dimmer_set(&ac_dimmer_handle, i); + zh_ac_dimmer_get(&ac_dimmer_handle, &value); + printf("Dimmer value: %d.\n", value); + vTaskDelay(100 / portTICK_PERIOD_MS); + } + zh_ac_dimmer_stop(&ac_dimmer_handle); + zh_ac_dimmer_deinit(&ac_dimmer_handle); +} +``` diff --git a/WIKI_EN.md b/WIKI_EN.md deleted file mode 100644 index 8c3cef9..0000000 --- a/WIKI_EN.md +++ /dev/null @@ -1,394 +0,0 @@ -# zh_ac_dimmer - AC Dimmer Component for ESP-IDF - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Installation](#installation) -- [API Reference](#api-reference) -- [Usage Examples](#usage-examples) -- [Technical Specifications](#technical-specifications) -- [Error Codes](#error-codes) -- [Contributing](#contributing) -- [License](#license) - ---- - -## Overview - -`zh_ac_dimmer` is a lightweight ESP-IDF component for AC dimmer control. It provides a simple API to control AC load power using zero-crossing detection and TRIAC control. The component is designed specifically for ESP32 microcontrollers and uses ESP-IDF v5.0+ drivers (GPTimer, GPIO). - -The component supports AC frequency of 400 Hz and uses hardware timers for precise timing control. - ---- - -## Features - -1. **AC Power Control**: Controls AC load power from 0% to 100% -2. **Zero-Crossing Detection**: Uses GPIO interrupt for precise timing -3. **TRIAC Control**: Controls TRIAC gate with precise timing via GPTimer -4. **Hardware Timer**: Uses GPTimer with 1 MHz resolution (1 µs) -5. **IRAM-safe ISR and Callback**: Interrupts and callbacks are placed in IRAM for reliable operation -6. **Error Handling**: Comprehensive error checking and configuration validation -7. **Thread-Safe**: Uses ESP-IDF drivers (thread-safe) -8. **Minimal Memory Footprint**: Low memory overhead -9. **Simple API**: Lightweight interface with start/stop/set/get support - ---- - -## Installation - -Navigate to your project's components directory: - -```bash -cd ../your_project/components -``` - -Clone the repository: - -```bash -git clone https://github.com/aZholtikov/zh_ac_dimmer.git -``` - -In your application, include the header: - -```c -#include "zh_ac_dimmer.h" -``` - -The component will be automatically built with your project. - -### Required Configuration - -For correct operation, please enable the following settings in menuconfig: - -```text -GPIO_CTRL_FUNC_IN_IRAM -CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM -CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM -CONFIG_GPTIMER_ISR_CACHE_SAFE -``` - ---- - -## API Reference - -### zh_ac_dimmer_init_config_t Structure - -```c -typedef struct -{ - gpio_num_t zero_cross_gpio; // Zero-crossing detection GPIO - gpio_num_t triac_gpio; // TRIAC control GPIO -} zh_ac_dimmer_init_config_t; -``` - -Use the `ZH_AC_DIMMER_INIT_CONFIG_DEFAULT()` macro to initialize with default values: - -- `zero_cross_gpio`: GPIO_NUM_MAX -- `triac_gpio`: GPIO_NUM_MAX - ---- - -### zh_ac_dimmer_handle_t Structure - -```c -typedef struct _zh_ac_dimmer_handle_t zh_ac_dimmer_handle_t; -``` - -Opaque instance descriptor. - ---- - -### zh_ac_dimmer_init() - -Initializes AC dimmer control. - -Allocates memory for handle, validates configuration, initializes GPIO pins (TRIAC as output, zero-crossing as input with positive edge interrupt), sets up ISR service and creates gptimer instance. - -**Parameters:** - -- `config` - Pointer to initialization configuration structure. Must not be NULL -- `handle` - Pointer to pointer to receive the created handle. Must be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle or invalid GPIO) -- `ESP_ERR_INVALID_STATE` - AC dimmer is already initialized -- `ESP_ERR_NO_MEM` - Memory allocation failed -- `ESP_FAIL` - Initialization error (GPIO, ISR service or timer) - -**Example:** - -```c -zh_ac_dimmer_handle_t *dimmer = NULL; -zh_ac_dimmer_init_config_t config = ZH_AC_DIMMER_INIT_CONFIG_DEFAULT(); -config.zero_cross_gpio = GPIO_NUM_16; -config.triac_gpio = GPIO_NUM_17; -esp_err_t err = zh_ac_dimmer_init(&config, &dimmer); -``` - ---- - -### zh_ac_dimmer_deinit() - -Deinitializes AC dimmer control and releases resources. - -Stops and deletes gptimer, removes GPIO ISR handler, resets GPIO pins to input mode, frees handle and sets the output pointer to NULL. - -**Parameters:** - -- `handle` - Pointer to handle. Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - handle or *handle is NULL -- `ESP_FAIL` - Timer stop, detach or delete error, or GPIO reset error - -**Important:** After calling this function, the handle becomes invalid. To reinitialize, call `zh_ac_dimmer_init()` again. - ---- - -### zh_ac_dimmer_start() - -Starts AC dimmer operation. - -Enables the dimmer so that zero-crossing events trigger TRIAC firing according to the current dimming value. - -**Parameters:** - -- `handle` - Pointer to handle. Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - handle or *handle is NULL - ---- - -### zh_ac_dimmer_stop() - -Stops AC dimmer operation. - -Disables TRIAC firing on zero-crossing events. The dimmer can be restarted with `zh_ac_dimmer_start()`. - -**Parameters:** - -- `handle` - Pointer to handle. Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - handle or *handle is NULL - ---- - -### zh_ac_dimmer_set() - -Sets the AC dimmer dimming value. - -Sets the dimming percentage that will be applied on the next zero-crossing event. - -**Parameters:** - -- `handle` - Pointer to handle. Must not be NULL -- `value` - Dimming level from 0 (off) to 100 (full power) - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - handle, *handle or value is invalid - ---- - -### zh_ac_dimmer_get() - -Gets the current AC dimmer dimming value. - -**Parameters:** - -- `handle` - Pointer to handle. Must not be NULL -- `value` - Pointer to receive the current dimming level (0–100). Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - handle, *handle or value is NULL - ---- - -## Usage Examples - -### Basic Example: Dimmer Control - -```c -#include "zh_ac_dimmer.h" - -void app_main(void) -{ - esp_log_level_set("zh_ac_dimmer", ESP_LOG_ERROR); - zh_ac_dimmer_handle_t *dimmer = NULL; - zh_ac_dimmer_init_config_t config = ZH_AC_DIMMER_INIT_CONFIG_DEFAULT(); - config.zero_cross_gpio = GPIO_NUM_16; - config.triac_gpio = GPIO_NUM_17; - zh_ac_dimmer_init(&config, &dimmer); - zh_ac_dimmer_start(&dimmer); - uint8_t value = 0; - for (uint8_t i = 0; i <= 100; ++i) - { - zh_ac_dimmer_set(&dimmer, i); - zh_ac_dimmer_get(&dimmer, &value); - printf("Dimmer value: %d.\n", value); - vTaskDelay(100 / portTICK_PERIOD_MS); - } - for (uint8_t i = 100; i > 0; --i) - { - zh_ac_dimmer_set(&dimmer, i); - zh_ac_dimmer_get(&dimmer, &value); - printf("Dimmer value: %d.\n", value); - vTaskDelay(100 / portTICK_PERIOD_MS); - } - zh_ac_dimmer_stop(&dimmer); - zh_ac_dimmer_deinit(&dimmer); -} -``` - ---- - -### Example: Dimmer with Button Control - -```c -#include "zh_ac_dimmer.h" - -#define ZERO_CROSS_GPIO GPIO_NUM_16 -#define TRIAC_GPIO GPIO_NUM_17 -#define BUTTON_GPIO GPIO_NUM_0 - -static uint8_t dimmer_value = 50; -static zh_ac_dimmer_handle_t *dimmer = NULL; - -static void IRAM_ATTR button_isr_handler(void *arg) -{ - (void)arg; - dimmer_value = (dimmer_value + 10) % 110; - if (dimmer_value > 100) - { - dimmer_value = 0; - } - zh_ac_dimmer_set(&dimmer, dimmer_value); - printf("Dimmer value: %d\n", dimmer_value); -} - -void app_main(void) -{ - esp_log_level_set("zh_ac_dimmer", ESP_LOG_ERROR); - // Initialize dimmer - zh_ac_dimmer_init_config_t config = ZH_AC_DIMMER_INIT_CONFIG_DEFAULT(); - config.zero_cross_gpio = ZERO_CROSS_GPIO; - config.triac_gpio = TRIAC_GPIO; - zh_ac_dimmer_init(&config, &dimmer); - // Initialize button - gpio_config_t button_config = { - .intr_type = GPIO_INTR_POSEDGE, - .mode = GPIO_MODE_INPUT, - .pin_bit_mask = (1ULL << BUTTON_GPIO), - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .pull_up_en = GPIO_PULLUP_ENABLE, - }; - gpio_config(&button_config); - gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); - gpio_isr_handler_add(BUTTON_GPIO, button_isr_handler, NULL); - // Start dimmer - zh_ac_dimmer_start(&dimmer); - printf("Dimmer initialized. Button on GPIO %d changes dimmer value.\n", BUTTON_GPIO); - for (;;) - { - vTaskDelay(1000 / portTICK_PERIOD_MS); - uint8_t current_value; - zh_ac_dimmer_get(&dimmer, ¤t_value); - printf("Current dimmer value: %d\n", current_value); - } -} -``` - ---- - -## Technical Specifications - -| Parameter | Value | -|-----------|-------| -| **Dimming Range** | 0–100% (0 = off, 100 = full power) | -| **AC Frequency** | 400 Hz (zero-crossing period: 1250 µs) | -| **Zero-Crossing Detection** | GPIO interrupt (positive edge) | -| **TRIAC Control** | GPIO output | -| **Timer Resolution** | 1 MHz (1 µs) | -| **Measurement Time** | ~1250 µs per half-cycle | -| **Base TRIAC Delay** | 330 µs (measured with logic analyzer) | -| **ESP-IDF Version** | >= 5.0 | -| **Platform** | ESP32 family | -| **Language** | C (C99) | - ---- - -## Error Codes - -| Error Code | Description | -|------------|-------------| -| `ESP_OK` | Operation successful | -| `ESP_ERR_INVALID_ARG` | Invalid argument (NULL pointer, invalid GPIO or invalid dimming value) | -| `ESP_ERR_INVALID_STATE` | AC dimmer is already initialized (only for `zh_ac_dimmer_init`) | -| `ESP_ERR_NO_MEM` | Memory allocation failed (only for `zh_ac_dimmer_init`) | -| `ESP_FAIL` | General error (GPIO, ISR service, timer initialization/deinitialization) | - ---- - -## Contributing - -Contributions are welcome! To contribute: - -1. Fork the repository -2. Create a feature branch (`git checkout -b feature/AmazingFeature`) -3. Commit your changes (`git commit -m 'Add some AmazingFeature'`) -4. Push to the branch (`git push origin feature/AmazingFeature`) -5. Open a Pull Request - -Please ensure your code follows the existing style and includes appropriate documentation. - ---- - -## License - -This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file for details. - -### Apache License, Version 2.0 - -Copyright (c) 2026 Alexey Zholtikov - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - ---- - -## Additional Notes - -- **AC Frequency**: Currently only 400 Hz frequency is supported (aviation frequency). The period between zero-crossings is 1250 µs. -- **Zero-Crossing Timing**: 1250 µs period (400 Hz) with 330 µs compensation for timer delay. Calculation formula: `alarm_count = (((1250 - 330) / 100) * (100 - dimmer_value)) + 330`. -- **GPIO Interrupt**: Zero-crossing detection uses positive edge interrupt with debounce protection (interrupts arriving earlier than 90% of the period are ignored). -- **IRAM Requirements**: For correct operation, enable `GPIO_CTRL_FUNC_IN_IRAM`, `CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM`, `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` and `CONFIG_GPTIMER_ISR_CACHE_SAFE` in menuconfig. -- **Thread Safety**: The component uses ESP-IDF drivers which are thread-safe. -- **Safety**: This module interacts with mains voltage. Incorrect wiring or insufficient isolation may result in electric shock or equipment damage. Ensure proper optoisolation and safety compliance before deployment. - ---- - -*Generated for zh_ac_dimmer v3.0.0* diff --git a/WIKI_RU.md b/WIKI_RU.md deleted file mode 100644 index e9e4683..0000000 --- a/WIKI_RU.md +++ /dev/null @@ -1,394 +0,0 @@ -# zh_ac_dimmer - Компонент управления освещением переменного тока для ESP-IDF - -## Содержание - -- [Обзор](#обзор) -- [Возможности](#возможности) -- [Установка](#установка) -- [Справочник API](#справочник-api) -- [Примеры использования](#примеры-использования) -- [Технические характеристики](#технические-характеристики) -- [Коды ошибок](#коды-ошибок) -- [Вклад в проект](#вклад-в-проект) -- [Лицензия](#лицензия) - ---- - -## Обзор - -`zh_ac_dimmer` - это легковесный компонент ESP-IDF для управления освещением переменного тока. Он предоставляет простой API для управления мощностью нагрузки переменного тока с использованием детекции перехода через ноль и управления TRIAC. Компонент разработан специально для микроконтроллеров ESP32 и использует драйверы ESP-IDF v5.0+ (GPTimer, GPIO). - -Компонент поддерживает частоту переменного тока 400 Гц и использует аппаратные таймеры для точного управления временем. - ---- - -## Возможности - -1. **Управление мощностью переменного тока**: Управление мощностью нагрузки от 0% до 100% -2. **Детекция перехода через ноль**: Использует прерывание GPIO для точного тайминга -3. **Управление TRIAC**: Управление затвором TRIAC с точным таймингом через GPTimer -4. **Аппаратный таймер**: Использует GPTimer с разрешением 1 МГц (1 мкс) -5. **IRAM-safe ISR и callback**: Прерывания и колбэки размещаются в IRAM для надёжной работы -6. **Обработка ошибок**: Комплексная проверка ошибок и валидация конфигурации -7. **Потокобезопасность**: Использует драйверы ESP-IDF (потокобезопасно) -8. **Минимальный объем памяти**: Низкие накладные расходы на память -9. **Простой API**: Легковесный интерфейс с поддержкой start/stop/set/get - ---- - -## Установка - -Перейдите в каталог компонентов вашего проекта: - -```bash -cd ../ваш_проект/components -``` - -Клонируйте репозиторий: - -```bash -git clone https://github.com/aZholtikov/zh_ac_dimmer.git -``` - -В вашем приложении подключите заголовочный файл: - -```c -#include "zh_ac_dimmer.h" -``` - -Компонент будет автоматически собран вместе с вашим проектом. - -### Необходимая конфигурация - -Для правильной работы включите следующие настройки в menuconfig: - -```text -GPIO_CTRL_FUNC_IN_IRAM -CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM -CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM -CONFIG_GPTIMER_ISR_CACHE_SAFE -``` - ---- - -## Справочник API - -### Структура zh_ac_dimmer_init_config_t - -```c -typedef struct -{ - gpio_num_t zero_cross_gpio; // GPIO детекции перехода через ноль - gpio_num_t triac_gpio; // GPIO управления TRIAC -} zh_ac_dimmer_init_config_t; -``` - -Используйте макрос `ZH_AC_DIMMER_INIT_CONFIG_DEFAULT()` для инициализации значениями по умолчанию: - -- `zero_cross_gpio`: GPIO_NUM_MAX -- `triac_gpio`: GPIO_NUM_MAX - ---- - -### Структура zh_ac_dimmer_handle_t - -```c -typedef struct _zh_ac_dimmer_handle_t zh_ac_dimmer_handle_t; -``` - -Непрозрачный дескриптор экземпляра устройства. - ---- - -### zh_ac_dimmer_init() - -Инициализирует управление освещением переменного тока. - -Выделяет память для handle, валидирует конфигурацию, инициализирует GPIO пины (TRIAC как выход, переход через ноль как вход с прерыванием по положительному фронту), устанавливает ISR-сервис и создаёт экземпляр gptimer. - -**Параметры:** - -- `config` - Указатель на структуру конфигурации инициализации. Не должен быть NULL -- `handle` - Указатель на указатель для получения созданного handle. Должен быть NULL - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или неверный GPIO) -- `ESP_ERR_INVALID_STATE` - Освещение переменного тока уже инициализировано -- `ESP_ERR_NO_MEM` - Не удалось выделить память -- `ESP_FAIL` - Ошибка инициализации (GPIO, ISR-сервис или таймер) - -**Пример:** - -```c -zh_ac_dimmer_handle_t *dimmer = NULL; -zh_ac_dimmer_init_config_t config = ZH_AC_DIMMER_INIT_CONFIG_DEFAULT(); -config.zero_cross_gpio = GPIO_NUM_16; -config.triac_gpio = GPIO_NUM_17; -esp_err_t err = zh_ac_dimmer_init(&config, &dimmer); -``` - ---- - -### zh_ac_dimmer_deinit() - -Деинициализирует управление освещением переменного тока и освобождает ресурсы. - -Останавливает и удаляет gptimer, удаляет ISR-обработчик GPIO, сбрасывает пины GPIO в режим ввода, освобождает handle и устанавливает выходной указатель в NULL. - -**Параметры:** - -- `handle` - Указатель на handle. Не должен быть NULL - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - handle или *handle равен NULL -- `ESP_FAIL` - Ошибка остановки таймера, отключения или удаления, или сброса GPIO - -**Важно:** После вызова этой функции handle становится недействительным. Для повторной инициализации вызовите `zh_ac_dimmer_init()` заново. - ---- - -### zh_ac_dimmer_start() - -Запускает работу освещения переменного тока. - -Включает диммер, чтобы события перехода через ноль запускали срабатывание TRIAC в соответствии с текущим значением затухания. - -**Параметры:** - -- `handle` - Указатель на handle. Не должен быть NULL - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - handle или *handle равен NULL - ---- - -### zh_ac_dimmer_stop() - -Останавливает работу освещения переменного тока. - -Отключает срабатывание TRIAC на событиях перехода через ноль. Диммер может быть перезапущен с помощью `zh_ac_dimmer_start()`. - -**Параметры:** - -- `handle` - Указатель на handle. Не должен быть NULL - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - handle или *handle равен NULL - ---- - -### zh_ac_dimmer_set() - -Устанавливает значение затухания освещения переменного тока. - -Устанавливает процент затухания, который будет применён на следующем событии перехода через ноль. - -**Параметры:** - -- `handle` - Указатель на handle. Не должен быть NULL -- `value` - Уровень затухания от 0 (выключено) до 100 (полная мощность) - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - handle, *handle или value недействительны - ---- - -### zh_ac_dimmer_get() - -Получает текущее значение затухания освещения переменного тока. - -**Параметры:** - -- `handle` - Указатель на handle. Не должен быть NULL -- `value` - Указатель для получения текущего уровня затухания (0–100). Не должен быть NULL - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - handle, *handle или value равен NULL - ---- - -## Примеры использования - -### Базовый пример: Управление затуханием - -```c -#include "zh_ac_dimmer.h" - -void app_main(void) -{ - esp_log_level_set("zh_ac_dimmer", ESP_LOG_ERROR); - zh_ac_dimmer_handle_t *dimmer = NULL; - zh_ac_dimmer_init_config_t config = ZH_AC_DIMMER_INIT_CONFIG_DEFAULT(); - config.zero_cross_gpio = GPIO_NUM_16; - config.triac_gpio = GPIO_NUM_17; - zh_ac_dimmer_init(&config, &dimmer); - zh_ac_dimmer_start(&dimmer); - uint8_t value = 0; - for (uint8_t i = 0; i <= 100; ++i) - { - zh_ac_dimmer_set(&dimmer, i); - zh_ac_dimmer_get(&dimmer, &value); - printf("Значение затухания: %d.\n", value); - vTaskDelay(100 / portTICK_PERIOD_MS); - } - for (uint8_t i = 100; i > 0; --i) - { - zh_ac_dimmer_set(&dimmer, i); - zh_ac_dimmer_get(&dimmer, &value); - printf("Значение затухания: %d.\n", value); - vTaskDelay(100 / portTICK_PERIOD_MS); - } - zh_ac_dimmer_stop(&dimmer); - zh_ac_dimmer_deinit(&dimmer); -} -``` - ---- - -### Пример: Управление затуханием с кнопкой - -```c -#include "zh_ac_dimmer.h" - -#define ZERO_CROSS_GPIO GPIO_NUM_16 -#define TRIAC_GPIO GPIO_NUM_17 -#define BUTTON_GPIO GPIO_NUM_0 - -static uint8_t dimmer_value = 50; -static zh_ac_dimmer_handle_t *dimmer = NULL; - -static void IRAM_ATTR button_isr_handler(void *arg) -{ - (void)arg; - dimmer_value = (dimmer_value + 10) % 110; - if (dimmer_value > 100) - { - dimmer_value = 0; - } - zh_ac_dimmer_set(&dimmer, dimmer_value); - printf("Значение затухания: %d\n", dimmer_value); -} - -void app_main(void) -{ - esp_log_level_set("zh_ac_dimmer", ESP_LOG_ERROR); - // Инициализация затухания - zh_ac_dimmer_init_config_t config = ZH_AC_DIMMER_INIT_CONFIG_DEFAULT(); - config.zero_cross_gpio = ZERO_CROSS_GPIO; - config.triac_gpio = TRIAC_GPIO; - zh_ac_dimmer_init(&config, &dimmer); - // Инициализация кнопки - gpio_config_t button_config = { - .intr_type = GPIO_INTR_POSEDGE, - .mode = GPIO_MODE_INPUT, - .pin_bit_mask = (1ULL << BUTTON_GPIO), - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .pull_up_en = GPIO_PULLUP_ENABLE, - }; - gpio_config(&button_config); - gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); - gpio_isr_handler_add(BUTTON_GPIO, button_isr_handler, NULL); - // Запуск затухания - zh_ac_dimmer_start(&dimmer); - printf("Затухание инициализировано. Кнопка на GPIO %d меняет значение затухания.\n", BUTTON_GPIO); - for (;;) - { - vTaskDelay(1000 / portTICK_PERIOD_MS); - uint8_t current_value; - zh_ac_dimmer_get(&dimmer, ¤t_value); - printf("Текущее значение затухания: %d\n", current_value); - } -} -``` - ---- - -## Технические характеристики - -| Параметр | Значение | -|----------|----------| -| **Диапазон затухания** | 0–100% (0 = выкл, 100 = полная мощность) | -| **Частота переменного тока** | 400 Гц (период перехода через ноль: 1250 мкс) | -| **Детекция перехода через ноль** | Прерывание GPIO (положительный фронт) | -| **Управление TRIAC** | Выход GPIO | -| **Разрешение таймера** | 1 МГц (1 мкс) | -| **Время измерения** | ~1250 мкс на полупериод | -| **Базовая задержка TRIAC** | 330 мкс (измерено логическим анализатором) | -| **Версия ESP-IDF** | >= 5.0 | -| **Платформа** | Семейство ESP32 | -| **Язык** | C (C99) | - ---- - -## Коды ошибок - -| Код ошибки | Описание | -|------------|----------| -| `ESP_OK` | Операция выполнена успешно | -| `ESP_ERR_INVALID_ARG` | Неверный аргумент (NULL указатель, неверный GPIO или неверное значение затухания) | -| `ESP_ERR_INVALID_STATE` | Освещение переменного тока уже инициализировано (только для `zh_ac_dimmer_init`) | -| `ESP_ERR_NO_MEM` | Не удалось выделить память (только для `zh_ac_dimmer_init`) | -| `ESP_FAIL` | Общая ошибка (GPIO, ISR-сервис, инициализация/деинициализация таймера) | - ---- - -## Вклад в проект - -Вклад приветствуется! Чтобы внести свой вклад: - -1. Сделайте форк репозитория -2. Создайте ветку функции (`git checkout -b feature/AmazingFeature`) -3. Закоммитьте ваши изменения (`git commit -m 'Add some AmazingFeature'`) -4. Отправьте в ветку (`git push origin feature/AmazingFeature`) -5. Откройте Pull Request - -Пожалуйста, убедитесь, что ваш код следует существующему стилю и включает соответствующую документацию. - ---- - -## Лицензия - -Этот проект лицензирован по лицензии Apache, версия 2.0 - см. файл [LICENSE](LICENSE) для подробной информации. - -### Apache License, Version 2.0 - -Авторское право (c) 2026 Алексей Жолтиков - -Лицензировано по лицензии Apache License, Version 2.0 (далее — "Лицензия"); -вы не можете использовать этот файл, кроме случаев, предусмотренных Лицензией. -Копию Лицензии можно получить по адресу: - - http://www.apache.org/licenses/LICENSE-2.0 - -Если иное не требуется действующим законодательством или не согласовано в письменном виде, -программное обеспечение, распространяемое по Лицензии, распространяется на условиях "КАК ЕСТЬ", -БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, явных или подразумеваемых, включая, но не ограничиваясь, гарантии -ТОВАРНОГО СОСТОЯНИЯ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. -Смотрите Лицензию для получения конкретных прав и ограничений. - ---- - -## Дополнительные заметки - -- **Частота переменного тока**: В настоящее время поддерживается только частота 400 Гц (авиационная частота). Период между переходами через ноль составляет 1250 мкс. -- **Тайминг перехода через ноль**: 1250 мкс период (400 Гц) с компенсацией 330 мкс для задержки таймера. Формула расчёта: `alarm_count = (((1250 - 330) / 100) * (100 - dimmer_value)) + 330`. -- **Прерывание GPIO**: Детекция перехода через ноль использует прерывание положительного фронта с защитой от дребезга (игнорируются прерывания, пришедшие ранее 90% от периода). -- **Требования IRAM**: Для правильной работы включите `GPIO_CTRL_FUNC_IN_IRAM`, `CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM`, `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` и `CONFIG_GPTIMER_ISR_CACHE_SAFE` в menuconfig. -- **Потокобезопасность**: Компонент использует драйверы ESP-IDF, которые являются потокобезопасными. -- **Безопасность**: Данный модуль взаимодействует с сетевым напряжением. Неправильное подключение или недостаточная изоляция могут привести к поражению электрическим током или повреждению оборудования. Убедитесь в наличии правильной оптоизоляции и соблюдении требований безопасности перед развёртыванием. - ---- - -*Сгенерировано для zh_ac_dimmer v3.0.0*