From 07d8133d444bb7beb7087fce36a7faf1a710aa9b Mon Sep 17 00:00:00 2001 From: Alexey Zholtikov Date: Sun, 30 Aug 2026 17:11:10 +0300 Subject: [PATCH] doc: updated readme --- README.md | 58 +++++-- WIKI_EN.md | 425 ----------------------------------------------- WIKI_RU.md | 425 ----------------------------------------------- include/zh_aht.h | 18 +- 4 files changed, 56 insertions(+), 870 deletions(-) delete mode 100644 WIKI_EN.md delete mode 100644 WIKI_RU.md diff --git a/README.md b/README.md index ef44959..48b8032 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ # ESP32 ESP-IDF component for AHT Series Humidity & Temperature Sensor -## 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,20 @@ 3. CRC8 data integrity verification. 4. Error statistics tracking. +## Note + +Enable the following settings in menuconfig: + +```text +I2C_ISR_IRAM_SAFE +I2C_MASTER_ISR_HANDLER_IN_IRAM +``` + ## 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_aht ``` @@ -34,6 +35,41 @@ In the application, add the component: #include "zh_aht.h" ``` -## Examples +## Example -See Wiki [EN](WIKI_EN.md#usage-examples) | [RU](WIKI_RU.md#примеры-использования) +```c +#include "zh_aht.h" + +#define I2C_PORT (I2C_NUM_MAX - 1) + +zh_aht_handle_t *aht_handle = NULL; + +void app_main(void) +{ + esp_log_level_set("zh_aht", ESP_LOG_ERROR); + i2c_master_bus_config_t i2c_bus_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = I2C_PORT, + .scl_io_num = GPIO_NUM_22, + .sda_io_num = GPIO_NUM_21, + .glitch_ignore_cnt = 7, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t i2c_bus_handle = NULL; + i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle); + zh_aht_init_config_t config = ZH_AHT_INIT_CONFIG_DEFAULT(); + config.i2c_handle = i2c_bus_handle; + zh_aht_init(&config, &aht_handle); + float humidity = 0.0; + float temperature = 0.0; + for (;;) + { + zh_aht_read(&aht_handle, &humidity, &temperature); + printf("Humidity: %.2f%%\n", humidity); + printf("Temperature: %.2f°C\n", temperature); + const zh_aht_stats_t *stats = zh_aht_get_stats(); + printf("I2C errors: %ld\n", stats->i2c_driver_error); + vTaskDelay(5000 / portTICK_PERIOD_MS); + } +} +``` diff --git a/WIKI_EN.md b/WIKI_EN.md deleted file mode 100644 index d4a8710..0000000 --- a/WIKI_EN.md +++ /dev/null @@ -1,425 +0,0 @@ -# zh_aht — AHT Humidity & Temperature Sensor 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_aht` is a lightweight ESP-IDF component for AHT10/AHT15/AHT20/AHT21/AHT25/AHT30/AHT40 humidity and temperature sensors. It provides a simple API to read humidity values from 0 to 100% and temperature values from -40 to +85°C. The component supports multiple sensors on a single I2C bus using the [zh_pca9548a](https://github.com/aZholtikov/zh_pca9548a) I2C multiplexer. - -The component is designed specifically for ESP32 microcontrollers and uses ESP-IDF v5.0+ I2C driver API. - ---- - -## Features - -1. **Humidity and Temperature Measurement**: Reads humidity from 0 to 100% and temperature from -40 to +85°C -2. **I2C Interface**: Uses standard I2C protocol (400 kHz max frequency) -3. **Configurable I2C Address**: Supports 0x38, 0x39 and 0x44 addresses -4. **Multiple Model Support**: AHT10, AHT15, AHT20, AHT21, AHT25, AHT30, AHT40 -5. **Error Statistics**: Built-in error counter for I2C driver errors -6. **Low Power**: Works with ESP-IDF power management -7. **Thread-Safe**: Uses ESP-IDF I2C driver (thread-safe) -8. **Minimal Overhead**: Low memory and CPU overhead -9. **Multiple Sensor Support**: Compatible with I2C multiplexer (zh_pca9548a) - ---- - -## Installation - -Navigate to your project's components directory: - -```bash -cd ../your_project/components -``` - -Clone the repository: - -```bash -git clone https://github.com/aZholtikov/zh_aht.git -``` - -In your application, include the header: - -```c -#include "zh_aht.h" -``` - -The component will be automatically built with your project. - -### Required menuconfig Settings - -For correct operation, enable the following settings in menuconfig: - -```text -I2C_ISR_IRAM_SAFE -I2C_MASTER_ISR_HANDLER_IN_IRAM -``` - -### Optional: Using with I2C Multiplexer (zh_pca9548a) - -To use multiple AHT sensors on the same I2C bus, also install the [zh_pca9548a](https://github.com/aZholtikov/zh_pca9548a) component. - ---- - -## API Reference - -All functions in this library use double pointer (`zh_aht_handle_t **`) for the sensor handler to allow for proper memory management and thread-safe operations. - -### zh_aht_init_config_t Structure - -**Description:** - -Initialization configuration for AHT sensor (I2C bus, address, frequency). - -**Fields (internal):** - -| Field | Type | Description / Описание | -| ------- | ------ | ------------------------ | -| `i2c_handle` | `i2c_master_bus_handle_t` | Unique I2C bus handle. | -| `i2c_address` | `uint8_t` | Sensor I2C address (0x38, 0x39, or 0x44). | -| `i2c_frequency` | `uint32_t` | Sensor I2C frequency (max 400000 Hz). | - -Use `ZH_AHT_INIT_CONFIG_DEFAULT()` macro to initialize with default values: - -- `i2c_frequency`: 400000 Hz -- `i2c_address`: 0x38 - ---- - -### zh_aht_handle_t Structure - -The structure is declared as `typedef struct _zh_aht_handle_t zh_aht_handle_t;` and encapsulates internal implementation details. - -**Fields (internal):** - -| Field | Type | Description / Описание | -|-------|------|------------------------| -| `dev_handle` | `i2c_master_dev_handle_t` | Pointer to I2C device handle. | - ---- - -### zh_aht_stats_t Structure - -**Description:** - -Sensor error statistics structure. - -**Fields (internal):** - -| Field | Type | Description / Описание | -|-------|------|------------------------| -| `i2c_driver_error` | `uint32_t` | Number of I2C driver errors. | - ---- - -### zh_aht_init() - -Initializes the AHT sensor. - -**Parameters:** - -- `config` - Pointer to AHT initialization configuration structure -- `handle` - Double pointer to unique AHT handle (`zh_aht_handle_t **`). If the pointer is NULL, memory will be allocated. - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL config or handle) -- `ESP_ERR_INVALID_STATE` - Sensor is already initialized -- `ESP_ERR_NO_MEM` - Memory allocation failed -- `ESP_FAIL` - Initialization I2C device failed -- `ESP_ERR_NOT_FOUND` - Sensor did not respond - -**Example:** - -```c -zh_aht_handle_t *aht_handle = NULL; -zh_aht_init_config_t config = ZH_AHT_INIT_CONFIG_DEFAULT(); -config.i2c_handle = i2c_bus_handle; -zh_aht_init(&config, &aht_handle); -``` - ---- - -### zh_aht_deinit() - -Deinitializes the AHT sensor and removes it from the I2C bus. Memory for handle is automatically freed and the pointer is set to NULL. - -**Parameters:** - -- `handle` - Double pointer to unique AHT handle (`zh_aht_handle_t **`). Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle pointer) -- `ESP_FAIL` - I2C device removal failed - ---- - -### zh_aht_read() - -Reads humidity and temperature values from the sensor. - -**Parameters:** - -- `handle` - Double pointer to unique AHT handle (`zh_aht_handle_t **`). Must not be NULL -- `humidity` - Pointer to store humidity value (in %). Must not be NULL -- `temperature` - Pointer to store temperature value (in °C). Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle pointer or humidity pointer or temperature pointer) -- `ESP_FAIL` - I2C communication error -- `ESP_ERR_TIMEOUT` - Timeout waiting for data ready -- `ESP_ERR_INVALID_CRC` - Invalid CRC checksum - -**Note:** The function performs measurement and waits ~80ms for data ready. - ---- - -### zh_aht_reset() - -Resets the AHT sensor. - -**Parameters:** - -- `handle` - Double pointer to unique AHT handle (`zh_aht_handle_t **`). Must not be NULL - -**Returns:** - -- `ESP_OK` - Success -- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle pointer) -- `ESP_FAIL` - I2C communication error - ---- - -### zh_aht_get_stats() - -Gets error statistics since last reset. - -**Returns:** - -- Pointer to const `zh_aht_stats_t` structure (valid until `zh_aht_reset_stats()` is called) - ---- - -### zh_aht_reset_stats() - -Resets all error statistics counters to zero. - ---- - -## Usage Examples - -### Example: Single Sensor - -```c -#include "zh_aht.h" - -static const int I2C_PORT = I2C_NUM_MAX - 1; -static const int SDA_IO = GPIO_NUM_21; -static const int SCL_IO = GPIO_NUM_22; - -static zh_aht_handle_t *aht_handle = NULL; - -void app_main(void) -{ - esp_log_level_set("zh_aht", ESP_LOG_ERROR); - i2c_master_bus_config_t bus_config = { - .clk_source = I2C_CLK_SRC_DEFAULT, - .i2c_port = I2C_PORT, - .scl_io_num = SCL_IO, - .sda_io_num = SDA_IO, - .glitch_ignore_cnt = 7, - .flags.enable_internal_pullup = true, - }; - i2c_master_bus_handle_t bus_handle = NULL; - ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &bus_handle)); - zh_aht_init_config_t config = ZH_AHT_INIT_CONFIG_DEFAULT(); - config.i2c_handle = bus_handle; - ESP_ERROR_CHECK(zh_aht_init(&config, &aht_handle)); - float humidity = 0.0f; - float temperature = 0.0f; - for (;;) - { - esp_err_t err = zh_aht_read(&aht_handle, &humidity, &temperature); - if (err == ESP_OK) - { - printf("Humidity: %.2f%%\n", humidity); - printf("Temperature: %.2f°C\n", temperature); - const zh_aht_stats_t *stats = zh_aht_get_stats(); - printf("I2C errors: %lu\n", stats->i2c_driver_error); - } - vTaskDelay(5000 / portTICK_PERIOD_MS); - } - // Resource cleanup (not reached with for(;;)) - // zh_aht_deinit(&aht_handle); - // i2c_del_master_bus(bus_handle); -} -``` - ---- - -### Example: Multiple Sensors via I2C Multiplexer (zh_pca9548a) - -```c -#include "zh_pca9548a.h" -#include "zh_aht.h" - -static const int I2C_PORT = I2C_NUM_MAX - 1; -static const int SDA_IO = GPIO_NUM_21; -static const int SCL_IO = GPIO_NUM_22; - -static zh_pca9548a_handle_t pca9548a_handle = {0}; -static zh_aht_handle_t *aht_handle_chan_0 = NULL; -static zh_aht_handle_t *aht_handle_chan_1 = NULL; -static zh_aht_handle_t *aht_handle_chan_2 = NULL; - -void app_main(void) -{ - esp_log_level_set("zh_pca9548a", ESP_LOG_ERROR); - esp_log_level_set("zh_aht", ESP_LOG_ERROR); - i2c_master_bus_config_t bus_config = { - .clk_source = I2C_CLK_SRC_DEFAULT, - .i2c_port = I2C_PORT, - .scl_io_num = SCL_IO, - .sda_io_num = SDA_IO, - .glitch_ignore_cnt = 7, - .flags.enable_internal_pullup = true, - }; - i2c_master_bus_handle_t bus_handle = NULL; - ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &bus_handle)); - // Initialize I2C multiplexer - zh_pca9548a_init_config_t pca_config = ZH_PCA9548A_INIT_CONFIG_DEFAULT(); - pca_config.i2c_handle = bus_handle; - pca_config.i2c_address = 0x70; - ESP_ERROR_CHECK(zh_pca9548a_init(&pca_config, &pca9548a_handle)); - // Initialize AHT sensors on different channels - zh_aht_init_config_t aht_config = ZH_AHT_INIT_CONFIG_DEFAULT(); - aht_config.i2c_handle = bus_handle; - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_0); - ESP_ERROR_CHECK(zh_aht_init(&aht_config, &aht_handle_chan_0)); - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_1); - ESP_ERROR_CHECK(zh_aht_init(&aht_config, &aht_handle_chan_1)); - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_2); - ESP_ERROR_CHECK(zh_aht_init(&aht_config, &aht_handle_chan_2)); - float humidity = 0.0f; - float temperature = 0.0f; - for (;;) - { - // Read sensor on channel 0 - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_0); - zh_aht_read(&aht_handle_chan_0, &humidity, &temperature); - printf("Sensor 1. Humidity: %.2f%%\n", humidity); - printf("Sensor 1. Temperature: %.2f°C\n", temperature); - // Read sensor on channel 1 - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_1); - zh_aht_read(&aht_handle_chan_1, &humidity, &temperature); - printf("Sensor 2. Humidity: %.2f%%\n", humidity); - printf("Sensor 2. Temperature: %.2f°C\n", temperature); - // Read sensor on channel 2 - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_2); - zh_aht_read(&aht_handle_chan_2, &humidity, &temperature); - printf("Sensor 3. Humidity: %.2f%%\n", humidity); - printf("Sensor 3. Temperature: %.2f°C\n", temperature); - vTaskDelay(5000 / portTICK_PERIOD_MS); - } -} -``` - ---- - -## Technical Specifications - -| Parameter | Value | -| ----------- | ------- | -| **Humidity Range** | 0 - 100% | -| **Temperature Range** | -40 - +85°C. | -| **Humidity Resolution** | 0.01% | -| **Temperature Resolution** | 0.01°C | -| **I2C Address** | 0x38, 0x39, 0x44 | -| **I2C Frequency** | Up to 400 kHz | -| **Measurement Time** | ~80 ms | -| **Supported Models** | AHT10, AHT15, AHT20, AHT21, AHT25, AHT30, AHT40 | -| **ESP-IDF Version** | >= 5.0 | -| **Platform** | ESP32 series | -| **Language** | C (C99) | - ---- - -## Error Codes - -| Error Code | Description | -| ------------ | ------------- | -| `ESP_OK` | Operation successful | -| `ESP_ERR_INVALID_ARG` | Invalid argument (NULL pointer or invalid configuration) | -| `ESP_ERR_INVALID_STATE` | Sensor is already initialized | -| `ESP_ERR_NO_MEM` | Memory allocation failed | -| `ESP_ERR_NOT_FOUND` | Sensor did not respond | -| `ESP_ERR_TIMEOUT` | Timeout waiting for data ready | -| `ESP_ERR_INVALID_CRC` | Invalid CRC checksum | -| `ESP_FAIL` | General failure (I2C communication error) | - ---- - -## 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 - -- **I2C Pull-up Resistors**: Ensure proper pull-up resistors are connected to SDA and SCL lines -- **Measurement Time**: The sensor requires ~80ms for each measurement -- **I2C_ISR_IRAM_SAFE**: For correct operation, enable `I2C_ISR_IRAM_SAFE` and `I2C_MASTER_ISR_HANDLER_IN_IRAM` in menuconfig -- **Thread Safety**: The component uses ESP-IDF I2C driver which is thread-safe -- **Memory Management**: All API functions now use double pointers for handle, which allows automatic memory management (freeing on deinitialization, setting to NULL) - ---- - -*Generated for zh_aht v4.0.0* diff --git a/WIKI_RU.md b/WIKI_RU.md deleted file mode 100644 index ec22db9..0000000 --- a/WIKI_RU.md +++ /dev/null @@ -1,425 +0,0 @@ -# zh_aht — Компонент датчика влажности и температуры AHT для ESP-IDF - -## Содержание - -- [Обзор](#обзор) -- [Возможности](#возможности) -- [Установка](#установка) -- [Справочник API](#справочник-api) -- [Примеры использования](#примеры-использования) -- [Технические характеристики](#технические-характеристики) -- [Коды ошибок](#коды-ошибок) -- [Вклад в проект](#вклад-в-проект) -- [Лицензия](#лицензия) - ---- - -## Обзор - -`zh_aht` - это легковесный компонент ESP-IDF для датчиков влажности и температуры AHT10/AHT15/AHT20/AHT21/AHT25/AHT30/AHT40. Он предоставляет простой API для считывания значений влажности от 0 до 100% и температуры от -40 до +85°C. Компонент поддерживает несколько датчиков на одной шине I2C с использованием I2C мультиплексатора [zh_pca9548a](https://github.com/aZholtikov/zh_pca9548a). - -Компонент разработан специально для микроконтроллеров ESP32 и использует API драйвера I2C ESP-IDF v5.0+. - ---- - -## Возможности - -1. **Измерение влажности и температуры**: Считывание значений влажности от 0 до 100% и температуры от -40 до +85°C -2. **Интерфейс I2C**: Использует стандартный протокол I2C (макс. частота 400 кГц) -3. **Настраиваемый адрес I2C**: Поддерживает адреса 0x38, 0x39 и 0x44 -4. **Поддержка нескольких моделей**: AHT10, AHT15, AHT20, AHT21, AHT25, AHT30, AHT40 -5. **Статистика ошибок**: Встроенный счетчик ошибок драйвера I2C -6. **Низкое энергопотребление**: Работает с системой управления питанием ESP-IDF -7. **Потокобезопасность**: Использует драйвер I2C ESP-IDF (потокобезопасен) -8. **Минимальные накладные расходы**: Низкие накладные расходы на память и процессор -9. **Поддержка нескольких датчиков**: Совместим с I2C мультиплексатором (zh_pca9548a) - ---- - -## Установка - -Перейдите в каталог компонентов вашего проекта: - -```bash -cd ../ваш_проект/components -``` - -Клонируйте репозиторий: - -```bash -git clone https://github.com/aZholtikov/zh_aht -``` - -В вашем приложении подключите заголовочный файл: - -```c -#include "zh_aht.h" -``` - -Компонент будет автоматически собран вместе с вашим проектом. - -### Обязательные настройки в menuconfig - -Для корректной работы компонента включите следующие настройки в menuconfig: - -```text -I2C_ISR_IRAM_SAFE -I2C_MASTER_ISR_HANDLER_IN_IRAM -``` - -### Опционально: Использование с I2C мультиплексатором (zh_pca9548a) - -Для использования нескольких датчиков AHT на одной шине I2C, также установите компонент [zh_pca9548a](https://github.com/aZholtikov/zh_pca9548a). - ---- - -## Справочник API - -Все функции в этой библиотеке используют двойной указатель (`zh_aht_handle_t **`) для дескриптора датчика, чтобы обеспечить правильное управление памятью и потокобезопасность. - -### Структура zh_aht_init_config_t - -**Описание:** - -Конфигурация для инициализации датчика AHT (шина I2C, адрес, частота). - -**Поля (внутренние):** - -| Поле | Тип | Description / Описание | -| ------ | ----- | ------------------------ | -| `i2c_handle` | `i2c_master_bus_handle_t` | Уникальный дескриптор шины I2C. | -| `i2c_address` | `uint8_t` | Адрес устройства датчика I2C (0x38, 0x39 или 0x44). | -| `i2c_frequency` | `uint32_t` | Частота I2C датчика (макс. 400000 Гц). | - -Используйте макрос `ZH_AHT_INIT_CONFIG_DEFAULT()` для инициализации значениями по умолчанию: - -- `i2c_frequency`: 400000 Гц -- `i2c_address`: 0x38 - ---- - -### Структура zh_aht_handle_t - -Структура объявляется как `typedef struct _zh_aht_handle_t zh_aht_handle_t;` и инкапсулирует детали внутренней реализации. - -**Поля (внутренние):** - -| Поле | Тип | Description / Описание | -|------|-----|------------------------| -| `dev_handle` | `i2c_master_dev_handle_t` | Указатель на дескриптор устройства I2C. | - ---- - -### Структура zh_aht_stats_t - -**Описание:** - -Структура статистики ошибок датчика. - -**Поля (внутренние):** - -| Поле | Тип | Description / Описание | -|------|-----|------------------------| -| `i2c_driver_error` | `uint32_t` | Количество ошибок драйвера I2C. | - ---- - -### zh_aht_init() - -Инициализирует датчик AHT. - -**Параметры:** - -- `config` - Указатель на структуру конфигурации инициализации AHT. Не должен быть NULL -- `handle` - Двойной указатель на уникальный дескриптор AHT (`zh_aht_handle_t **`). Должен быть NULL - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL config или handle) -- `ESP_ERR_INVALID_STATE` - Датчик уже инициализирован -- `ESP_ERR_NO_MEM` - Ошибка выделения памяти -- `ESP_FAIL` - Ошибка инициализации устройства I2C -- `ESP_ERR_NOT_FOUND` - Датчик не отвечает - -**Пример:** - -```c -zh_aht_handle_t *aht_handle = NULL; -zh_aht_init_config_t config = ZH_AHT_INIT_CONFIG_DEFAULT(); -config.i2c_handle = i2c_bus_handle; -zh_aht_init(&config, &aht_handle); -``` - ---- - -### zh_aht_deinit() - -Деинициализирует датчик AHT и удаляет его из шины I2C. Память для handle автоматически освобождается, а указатель устанавливается в NULL. - -**Параметры:** - -- `handle` - Двойной указатель на уникальный дескриптор AHT (`zh_aht_handle_t **`). Не должен быть NULL - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle) -- `ESP_FAIL` - Ошибка удаления устройства I2C - ---- - -### zh_aht_read() - -Считывает значения влажности и температуры с датчика. - -**Параметры:** - -- `handle` - Двойной указатель на уникальный дескриптор AHT (`zh_aht_handle_t **`). Не должен быть NULL -- `humidity` - Указатель для хранения значения влажности (в %). Не должен быть NULL -- `temperature` - Указатель для хранения значения температуры (в °C). Не должен быть NULL - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle, humidity или temperature) -- `ESP_FAIL` - Ошибка связи I2C -- `ESP_ERR_TIMEOUT` - Превышено время ожидания готовности данных -- `ESP_ERR_INVALID_CRC` - Неверная CRC контрольная сумма - -**Примечание:** Функция выполняет измерение и ожидает ~80 мс готовности данных. - ---- - -### zh_aht_reset() - -Сбрасывает датчик AHT. - -**Параметры:** - -- `handle` - Двойной указатель на уникальный дескриптор AHT (`zh_aht_handle_t **`). Не должен быть NULL. - -**Возвращает:** - -- `ESP_OK` - Успех -- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle) -- `ESP_FAIL` - Ошибка связи I2C - ---- - -### zh_aht_get_stats() - -Получает статистику ошибок с момента последнего сброса. - -**Возвращает:** - -- Указатель на константную структуру `zh_aht_stats_t` (действителен до вызова `zh_aht_reset_stats()`) - ---- - -### zh_aht_reset_stats() - -Сбрасывает все счётчики статистики ошибок, устанавливая их в ноль. - ---- - -## Примеры использования - -### Пример: Один датчик - -```c -#include "zh_aht.h" - -static const int I2C_PORT = I2C_NUM_MAX - 1; -static const int SDA_IO = GPIO_NUM_21; -static const int SCL_IO = GPIO_NUM_22; - -static zh_aht_handle_t *aht_handle = NULL; - -void app_main(void) -{ - esp_log_level_set("zh_aht", ESP_LOG_ERROR); - i2c_master_bus_config_t bus_config = { - .clk_source = I2C_CLK_SRC_DEFAULT, - .i2c_port = I2C_PORT, - .scl_io_num = SCL_IO, - .sda_io_num = SDA_IO, - .glitch_ignore_cnt = 7, - .flags.enable_internal_pullup = true, - }; - i2c_master_bus_handle_t bus_handle = NULL; - ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &bus_handle)); - zh_aht_init_config_t config = ZH_AHT_INIT_CONFIG_DEFAULT(); - config.i2c_handle = bus_handle; - ESP_ERROR_CHECK(zh_aht_init(&config, &aht_handle)); - float humidity = 0.0f; - float temperature = 0.0f; - for (;;) - { - esp_err_t err = zh_aht_read(&aht_handle, &humidity, &temperature); - if (err == ESP_OK) - { - printf("Влажность: %.2f%%\n", humidity); - printf("Температура: %.2f°C\n", temperature); - const zh_aht_stats_t *stats = zh_aht_get_stats(); - printf("Ошибки I2C: %lu\n", stats->i2c_driver_error); - } - vTaskDelay(5000 / portTICK_PERIOD_MS); - } - // Очистка ресурсов (не достигается в примере с for(;;)) - // zh_aht_deinit(&aht_handle); - // i2c_del_master_bus(bus_handle); -} -``` - ---- - -### Пример: Несколько датчиков через I2C мультиплексор (zh_pca9548a) - -```c -#include "zh_pca9548a.h" -#include "zh_aht.h" - -static const int I2C_PORT = I2C_NUM_MAX - 1; -static const int SDA_IO = GPIO_NUM_21; -static const int SCL_IO = GPIO_NUM_22; - -static zh_pca9548a_handle_t pca9548a_handle = {0}; -static zh_aht_handle_t *aht_handle_chan_0 = NULL; -static zh_aht_handle_t *aht_handle_chan_1 = NULL; -static zh_aht_handle_t *aht_handle_chan_2 = NULL; - -void app_main(void) -{ - esp_log_level_set("zh_pca9548a", ESP_LOG_ERROR); - esp_log_level_set("zh_aht", ESP_LOG_ERROR); - i2c_master_bus_config_t bus_config = { - .clk_source = I2C_CLK_SRC_DEFAULT, - .i2c_port = I2C_PORT, - .scl_io_num = SCL_IO, - .sda_io_num = SDA_IO, - .glitch_ignore_cnt = 7, - .flags.enable_internal_pullup = true, - }; - i2c_master_bus_handle_t bus_handle = NULL; - ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &bus_handle)); - // Инициализация I2C мультиплексора - zh_pca9548a_init_config_t pca_config = ZH_PCA9548A_INIT_CONFIG_DEFAULT(); - pca_config.i2c_handle = bus_handle; - pca_config.i2c_address = 0x70; - ESP_ERROR_CHECK(zh_pca9548a_init(&pca_config, &pca9548a_handle)); - // Инициализация датчиков AHT на разных каналах - zh_aht_init_config_t aht_config = ZH_AHT_INIT_CONFIG_DEFAULT(); - aht_config.i2c_handle = bus_handle; - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_0); - ESP_ERROR_CHECK(zh_aht_init(&aht_config, &aht_handle_chan_0)); - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_1); - ESP_ERROR_CHECK(zh_aht_init(&aht_config, &aht_handle_chan_1)); - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_2); - ESP_ERROR_CHECK(zh_aht_init(&aht_config, &aht_handle_chan_2)); - float humidity = 0.0f; - float temperature = 0.0f; - for (;;) - { - // Считывание с датчика на канале 0 - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_0); - zh_aht_read(&aht_handle_chan_0, &humidity, &temperature); - printf("Датчик 1. Влажность: %.2f%%\n", humidity); - printf("Датчик 1. Температура: %.2f°C\n", temperature); - // Считывание с датчика на канале 1 - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_1); - zh_aht_read(&aht_handle_chan_1, &humidity, &temperature); - printf("Датчик 2. Влажность: %.2f%%\n", humidity); - printf("Датчик 2. Температура: %.2f°C\n", temperature); - // Считывание с датчика на канале 2 - zh_pca9548a_set(&pca9548a_handle, ZH_PCA9548A_CHAN_NUM_2); - zh_aht_read(&aht_handle_chan_2, &humidity, &temperature); - printf("Датчик 3. Влажность: %.2f%%\n", humidity); - printf("Датчик 3. Температура: %.2f°C\n", temperature); - vTaskDelay(5000 / portTICK_PERIOD_MS); - } -} -``` - ---- - -## Технические характеристики - -| Параметр | Значение | -| ---------- | ---------- | -| **Диапазон влажности** | 0 - 100% | -| **Диапазон температуры** | -40 - +85°C | -| **Разрешение измерения влажности** | 0.01% | -| **Разрешение измерения температуры** | 0.01°C | -| **Адрес I2C** | 0x38, 0x39, 0x44 | -| **Частота I2C** | До 400 кГц | -| **Время измерения** | ~80 мс | -| **Поддерживаемые модели** | AHT10, AHT15, AHT20, AHT21, AHT25, AHT30, AHT40 | -| **Версия ESP-IDF** | >= 5.0 | -| **Платформа** | Семейство ESP32 | -| **Язык** | C (C99) | - ---- - -## Коды ошибок - -| Код ошибки | Описание | -| ------------ | ---------- | -| `ESP_OK` | Операция выполнена успешно | -| `ESP_ERR_INVALID_ARG` | Неверный аргумент (NULL указатель или неверная конфигурация) | -| `ESP_ERR_INVALID_STATE` | Датчик уже инициализирован | -| `ESP_ERR_NO_MEM` | Ошибка выделения памяти | -| `ESP_ERR_NOT_FOUND` | Датчик не отвечает | -| `ESP_ERR_TIMEOUT` | Превышено время ожидания готовности данных | -| `ESP_ERR_INVALID_CRC` | Неверная CRC контрольная сумма | -| `ESP_FAIL` | Общая ошибка (ошибка связи I2C) | - ---- - -## Вклад в проект - -Вклад приветствуется! Чтобы внести свой вклад: - -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 - -Если иное не требуется действующим законодательством или не согласовано в письменном виде, -программное обеспечение, распространяемое по Лицензии, распространяется на условиях "КАК ЕСТЬ", -БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, явных или подразумеваемых, включая, но не ограничиваясь, гарантии -ТОВАРНОГО СОСТОЯНИЯ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. -Смотрите Лицензию для получения конкретных прав и ограничений. - ---- - -## Дополнительные заметки - -- **Подтягивающие резисторы I2C**: Убедитесь, что к линиям SDA и SCL подключены соответствующие подтягивающие резисторы -- **Время измерения**: Датчик требует ~80 мс для каждого измерения -- **I2C_ISR_IRAM_SAFE**: Для правильной работы включите `I2C_ISR_IRAM_SAFE` и `I2C_MASTER_ISR_HANDLER_IN_IRAM` в menuconfig -- **Потокобезопасность**: Компонент использует драйвер I2C ESP-IDF, который является потокобезопасным -- **Управление памятью**: Все функции API теперь используют двойные указатели для handle, что позволяет автоматически управлять памятью (освобождение при деинициализации, установка в NULL) - ---- - -*Сгенерировано для zh_aht v4.0.0* diff --git a/include/zh_aht.h b/include/zh_aht.h index 23899d8..af7167f 100644 --- a/include/zh_aht.h +++ b/include/zh_aht.h @@ -1,7 +1,7 @@ /** * @file zh_aht.h * - * @brief Driver for AHT series temperature and humidity sensors (AHT10/AHT15/AHT20/AHT21/AHT25/AHT30/AHT40) + * @brief Driver for AHT series temperature and humidity sensors (AHT10/AHT15/AHT20/AHT21/AHT25/AHT30/AHT40). * * Provides I2C-based communication with AHT sensors including initialization, * data reading with CRC validation, reset functionality, and error statistics. @@ -42,7 +42,7 @@ extern "C" typedef struct _zh_aht_handle_t zh_aht_handle_t; /** - * @brief Configuration structure for AHT sensor initialization + * @brief Configuration structure for AHT sensor initialization. */ typedef struct { @@ -52,7 +52,7 @@ extern "C" } zh_aht_init_config_t; /** - * @brief Structure containing sensor error statistics + * @brief Structure containing sensor error statistics. */ typedef struct { @@ -60,7 +60,7 @@ extern "C" } zh_aht_stats_t; /** - * @brief Initialize AHT sensor and establish I2C communication + * @brief Initialize AHT sensor and establish I2C communication. * * Allocates handle, configures I2C device, probes sensor presence, * and sends initialization command if required. @@ -77,7 +77,7 @@ extern "C" esp_err_t zh_aht_init(const zh_aht_init_config_t *config, zh_aht_handle_t **handle); /** - * @brief Deinitialize AHT sensor and release resources + * @brief Deinitialize AHT sensor and release resources. * * Removes I2C device and frees the sensor handle. * @@ -90,7 +90,7 @@ extern "C" esp_err_t zh_aht_deinit(zh_aht_handle_t **handle); /** - * @brief Read humidity and temperature from AHT sensor + * @brief Read humidity and temperature from AHT sensor. * * Sends read command, receives 7-byte response with CRC validation, * and converts raw data to engineering units. @@ -108,7 +108,7 @@ extern "C" esp_err_t zh_aht_read(zh_aht_handle_t **handle, float *humidity, float *temperature); /** - * @brief Reset AHT sensor via I2C command + * @brief Reset AHT sensor via I2C command. * * Sends reset command and waits for sensor recovery. * @@ -121,7 +121,7 @@ extern "C" esp_err_t zh_aht_reset(zh_aht_handle_t **handle); /** - * @brief Get pointer to sensor error statistics + * @brief Get pointer to sensor error statistics. * * Returns read-only pointer to global statistics structure. * @@ -130,7 +130,7 @@ extern "C" const zh_aht_stats_t *zh_aht_get_stats(void); /** - * @brief Reset all error statistics to zero + * @brief Reset all error statistics to zero. * * Clears all error counters tracked in the global statistics structure. */