doc: updated readme

This commit is contained in:
aZholtikov committed 2026-08-30 17:11:10 +03:00
1 parent 4cbd742102
commit 07d8133d44
4 files changed
+56 -870

No files matched your search

+47 -11
View File
@@ -1,13 +1,5 @@
# ESP32 ESP-IDF component for AHT Series Humidity & Temperature Sensor # 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 ## 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. [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. 3. CRC8 data integrity verification.
4. Error statistics tracking. 4. Error statistics tracking.
## Note
Enable the following settings in menuconfig:
```text
I2C_ISR_IRAM_SAFE
I2C_MASTER_ISR_HANDLER_IN_IRAM
```
## Using ## Using
In an existing project, run the following command to install the component: In an existing project, run the following command to install the component:
```text ```bash
cd ../your_project/components cd ../your_project/components
git clone https://github.com/aZholtikov/zh_aht git clone https://github.com/aZholtikov/zh_aht
``` ```
@@ -34,6 +35,41 @@ In the application, add the component:
#include "zh_aht.h" #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);
}
}
```
-425
View File
@@ -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*
-425
View File
@@ -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*
+9 -9
View File
@@ -1,7 +1,7 @@
/** /**
* @file zh_aht.h * @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, * Provides I2C-based communication with AHT sensors including initialization,
* data reading with CRC validation, reset functionality, and error statistics. * 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; 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 typedef struct
{ {
@@ -52,7 +52,7 @@ extern "C"
} zh_aht_init_config_t; } zh_aht_init_config_t;
/** /**
* @brief Structure containing sensor error statistics * @brief Structure containing sensor error statistics.
*/ */
typedef struct typedef struct
{ {
@@ -60,7 +60,7 @@ extern "C"
} zh_aht_stats_t; } 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, * Allocates handle, configures I2C device, probes sensor presence,
* and sends initialization command if required. * 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); 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. * 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); 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, * Sends read command, receives 7-byte response with CRC validation,
* and converts raw data to engineering units. * 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); 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. * 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); 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. * Returns read-only pointer to global statistics structure.
* *
@@ -130,7 +130,7 @@ extern "C"
const zh_aht_stats_t *zh_aht_get_stats(void); 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. * Clears all error counters tracked in the global statistics structure.
*/ */