Initial commit

This commit is contained in:
Andrey Aleksandrov
2025-12-30 21:48:48 +02:00
commit 236d5e4a8c
5 changed files with 581 additions and 0 deletions

12
CHANGELOG.md Normal file
View File

@@ -0,0 +1,12 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.0.0] - 2024-12-30
### Added
- Repository

134
README.md Normal file
View File

@@ -0,0 +1,134 @@
# ESP32 Custom Libraries Collection
A collection of custom libraries designed for ESP32 development with ESP-IDF framework. These libraries are optimized for IoT sensor projects and provide reliable, reusable components.
## Libraries Overview
### 🌡️ DHT22 Sensor (`dht22_sensor`)
- **Version**: 1.0.0
- **Description**: Custom DHT22/AM2302 sensor library with bit-banging implementation
- **Features**: Temperature and humidity reading with robust timing control
- **Use Case**: Environmental monitoring projects
### Method 1: Git
```bash
cd your_project_directory
mkdir dht22
git clone https://home.arcoa.eu:8413/esp32libs/dht22_sensor.git
```
### Method 2: Manual Copy
1. Clone or download this repository
2. Copy the desired library folders to your project's `lib/` directory
3. Include the headers in your main code
### Method 3: PlatformIO Library
Each library contains a `library.json` file for PlatformIO compatibility.
## Usage Example
```c
#include "dht22_sensor.h"
#include "wifi_manager.h"
#include "mqtt_manager.h"
#include "led_manager.h"
void app_main(void) {
// Initialize WiFi
wifi_manager_config_t wifi_config = {
.ssid = "YourSSID",
.password = "YourPassword"
};
wifi_manager_init(&wifi_config);
// Initialize MQTT
mqtt_manager_config_t mqtt_config = {
.broker_url = "mqtt://your-broker.com",
.client_id = "esp32_sensor"
};
mqtt_manager_init(&mqtt_config);
// Initialize DHT22 sensor
dht22_init(GPIO_NUM_4);
// Initialize LED for status indication
led_manager_init(GPIO_NUM_8, 1);
// Your application logic here
while (1) {
float temperature, humidity;
if (dht22_read(&temperature, &humidity) == ESP_OK) {
mqtt_publish_sensor_data(temperature, humidity);
led_manager_set_color(0, 255, 0); // Green for success
} else {
led_manager_set_color(255, 0, 0); // Red for error
}
vTaskDelay(pdMS_TO_TICKS(30000)); // 30 second interval
}
}
```
## Library Dependencies
```
mqtt_manager → (none)
```
## Configuration
Library includes configuration options through header files. Check individual library documentation for specific configuration parameters.
### Common GPIO Assignments
- **DHT22**: Any GPIO pin (recommended: GPIO 4)
- **LED Strip**: Any GPIO pin (recommended: GPIO 8)
- **Built-in LED**: GPIO 2 (ESP32-C6)
## Compatibility
- **Framework**: ESP-IDF
- **Platforms**: ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6
- **Tested**: ESP32-C6 DevKit
- **License**: MIT
## Project Structure
```
MyESP32Libs/
├── README.md
├── CHANGELOG.md
├── dht22_sensor.c
├── dht22_sensor.h
├── README.md
├── CHANGELOG.md
├── library.json
```
## Contributing
1. Fork this repository
2. Create a feature branch (`git checkout -b feature/new-library`)
3. Commit your changes (`git commit -am 'Add new library'`)
4. Push to the branch (`git push origin feature/new-library`)
5. Create a Pull Request
## Development Notes
⚠️ **VSCode Include Errors**: If you see `cannot open source file "esp_err.h"` errors in VSCode, this is expected for standalone library development. See [DEVELOPMENT.md](DEVELOPMENT.md) for solutions.
## License
This project is licensed under the MIT License - see individual library.json files for details.
## Support
For issues and questions:
- Create an issue in this repository
- Check individual library headers for API documentation
- Refer to ESP-IDF documentation for framework-specific details

307
dht22_sensor.c Normal file
View File

@@ -0,0 +1,307 @@
#include "dht22_sensor.h"
#include "esp_log.h"
#include "esp_rom_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include <string.h>
static const char *TAG = "DHT22_SENSOR";
// Default DHT22 timing constants (microseconds)
#define DHT22_DEFAULT_START_SIGNAL_US 18000 // 18ms start signal
#define DHT22_DEFAULT_RESPONSE_TIMEOUT_US 500 // 500us timeout for response
#define DHT22_DEFAULT_DATA_TIMEOUT_US 150 // 150us timeout for data bits
#define DHT22_DEFAULT_BIT_THRESHOLD_US 40 // Threshold for 0/1 detection
// Global configuration
static dht22_config_t current_config = {0};
static bool is_initialized = false;
// Internal function to read from DHT22
static dht22_result_t dht22_read_internal(int gpio_pin, float *temperature, float *humidity, const dht22_config_t *config);
esp_err_t dht22_init(int gpio_pin)
{
dht22_config_t default_config = {
.gpio_pin = gpio_pin,
.start_signal_us = DHT22_DEFAULT_START_SIGNAL_US,
.response_timeout_us = DHT22_DEFAULT_RESPONSE_TIMEOUT_US,
.data_timeout_us = DHT22_DEFAULT_DATA_TIMEOUT_US,
.bit_threshold_us = DHT22_DEFAULT_BIT_THRESHOLD_US};
return dht22_init_with_config(&default_config);
}
esp_err_t dht22_init_with_config(const dht22_config_t *config)
{
if (config == NULL)
{
ESP_LOGE(TAG, "DHT22 config cannot be NULL");
return ESP_ERR_INVALID_ARG;
}
if (config->gpio_pin < 0)
{
ESP_LOGE(TAG, "Invalid GPIO pin: %d", config->gpio_pin);
return ESP_ERR_INVALID_ARG;
}
ESP_LOGI(TAG, "Initializing DHT22 on GPIO %d", config->gpio_pin);
// Store configuration
memcpy(&current_config, config, sizeof(dht22_config_t));
is_initialized = true;
ESP_LOGI(TAG, "DHT22 initialized successfully");
return ESP_OK;
}
dht22_result_t dht22_read(float *temperature, float *humidity)
{
if (!is_initialized)
{
ESP_LOGE(TAG, "DHT22 not initialized");
return DHT22_TIMEOUT_ERROR;
}
return dht22_read_internal(current_config.gpio_pin, temperature, humidity, &current_config);
}
dht22_result_t dht22_read_data(dht22_data_t *data)
{
if (data == NULL)
{
ESP_LOGE(TAG, "DHT22 data pointer cannot be NULL");
return DHT22_TIMEOUT_ERROR;
}
return dht22_read(&data->temperature, &data->humidity);
}
dht22_result_t dht22_read_from_pin(int gpio_pin, float *temperature, float *humidity)
{
dht22_config_t temp_config = {
.gpio_pin = gpio_pin,
.start_signal_us = DHT22_DEFAULT_START_SIGNAL_US,
.response_timeout_us = DHT22_DEFAULT_RESPONSE_TIMEOUT_US,
.data_timeout_us = DHT22_DEFAULT_DATA_TIMEOUT_US,
.bit_threshold_us = DHT22_DEFAULT_BIT_THRESHOLD_US};
return dht22_read_internal(gpio_pin, temperature, humidity, &temp_config);
}
static dht22_result_t dht22_read_internal(int gpio_pin, float *temperature, float *humidity, const dht22_config_t *config)
{
if (temperature == NULL || humidity == NULL)
{
ESP_LOGE(TAG, "Temperature and humidity pointers cannot be NULL");
return DHT22_TIMEOUT_ERROR;
}
uint8_t data[5] = {0};
int counter = 0;
ESP_LOGD(TAG, "Reading DHT22 from GPIO %d", gpio_pin);
// Disable interrupts during critical timing
portDISABLE_INTERRUPTS();
// Configure GPIO
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << gpio_pin),
.mode = GPIO_MODE_OUTPUT_OD,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_conf);
// Send start signal
gpio_set_level(gpio_pin, 0);
esp_rom_delay_us(config->start_signal_us);
gpio_set_level(gpio_pin, 1);
esp_rom_delay_us(40);
// Switch to input mode
io_conf.mode = GPIO_MODE_INPUT;
gpio_config(&io_conf);
// Wait for DHT22 response (should go low then high)
counter = 0;
while (gpio_get_level(gpio_pin) == 1)
{
esp_rom_delay_us(1);
if (++counter > config->response_timeout_us)
{
portENABLE_INTERRUPTS();
ESP_LOGD(TAG, "DHT22 timeout waiting for initial response");
return DHT22_TIMEOUT_ERROR;
}
}
// Wait for response signal to go high
counter = 0;
while (gpio_get_level(gpio_pin) == 0)
{
esp_rom_delay_us(1);
if (++counter > config->response_timeout_us)
{
portENABLE_INTERRUPTS();
ESP_LOGD(TAG, "DHT22 timeout waiting for response high");
return DHT22_TIMEOUT_ERROR;
}
}
// Wait for response signal to go low (start of data)
counter = 0;
while (gpio_get_level(gpio_pin) == 1)
{
esp_rom_delay_us(1);
if (++counter > config->response_timeout_us)
{
portENABLE_INTERRUPTS();
ESP_LOGD(TAG, "DHT22 timeout waiting for data start");
return DHT22_TIMEOUT_ERROR;
}
}
// Read 40 bits of data
for (int i = 0; i < 40; i++)
{
// Wait for signal to go high
counter = 0;
while (gpio_get_level(gpio_pin) == 0)
{
esp_rom_delay_us(1);
if (++counter > config->data_timeout_us)
{
portENABLE_INTERRUPTS();
ESP_LOGD(TAG, "DHT22 timeout waiting for bit %d high signal", i);
return DHT22_TIMEOUT_ERROR;
}
}
// Measure high pulse duration
counter = 0;
while (gpio_get_level(gpio_pin) == 1)
{
esp_rom_delay_us(1);
if (++counter > config->data_timeout_us)
{
portENABLE_INTERRUPTS();
ESP_LOGD(TAG, "DHT22 timeout during bit %d high pulse", i);
return DHT22_TIMEOUT_ERROR;
}
}
// DHT22 protocol: '0' = ~26-28us high, '1' = ~70us high
data[i / 8] <<= 1;
if (counter > config->bit_threshold_us)
{
data[i / 8] |= 1;
}
// Debug first few bits if we're getting all zeros
if (i < 8)
{
ESP_LOGD(TAG, "Bit %d: pulse=%dus, value=%d", i, counter, (counter > config->bit_threshold_us) ? 1 : 0);
}
}
// Re-enable interrupts
portENABLE_INTERRUPTS();
// Verify checksum
uint8_t checksum = data[0] + data[1] + data[2] + data[3];
// Debug output for problematic readings
if ((data[0] == 0 && data[1] == 0 && data[2] == 0 && data[3] == 0) || checksum != data[4])
{
ESP_LOGD(TAG, "DHT22 raw data: %02X %02X %02X %02X %02X",
data[0], data[1], data[2], data[3], data[4]);
ESP_LOGD(TAG, "Calculated checksum: %02X, Received: %02X", checksum, data[4]);
}
if (checksum != data[4])
{
ESP_LOGD(TAG, "DHT22 checksum mismatch");
return DHT22_CHECKSUM_ERROR;
}
// Check for all-zero data (sensor not responding properly)
if (data[0] == 0 && data[1] == 0 && data[2] == 0 && data[3] == 0)
{
ESP_LOGD(TAG, "DHT22 returned all zeros - sensor may not be connected");
return DHT22_TIMEOUT_ERROR; // Treat as timeout to trigger retry
}
// Convert data to temperature and humidity
*humidity = ((data[0] << 8) | data[1]) / 10.0f;
int temp_raw = (data[2] << 8) | data[3];
if (temp_raw & 0x8000)
{
*temperature = -(temp_raw & 0x7FFF) / 10.0f;
}
else
{
*temperature = temp_raw / 10.0f;
}
ESP_LOGD(TAG, "DHT22 read successful: T=%.2f°C, H=%.2f%%", *temperature, *humidity);
return DHT22_OK;
}
const char *dht22_get_error_string(dht22_result_t result)
{
switch (result)
{
case DHT22_OK:
return "Success";
case DHT22_TIMEOUT_ERROR:
return "Timeout error";
case DHT22_CHECKSUM_ERROR:
return "Checksum error";
default:
return "Unknown error";
}
}
bool dht22_test_connection(void)
{
if (!is_initialized)
{
ESP_LOGW(TAG, "DHT22 not initialized for connection test");
return false;
}
float temp, humid;
dht22_result_t result = dht22_read(&temp, &humid);
if (result == DHT22_OK)
{
ESP_LOGI(TAG, "DHT22 connection test successful: T=%.2f°C, H=%.2f%%", temp, humid);
return true;
}
else
{
ESP_LOGW(TAG, "DHT22 connection test failed: %s", dht22_get_error_string(result));
return false;
}
}
esp_err_t dht22_deinit(void)
{
if (!is_initialized)
{
ESP_LOGW(TAG, "DHT22 not initialized");
return ESP_OK;
}
ESP_LOGI(TAG, "Deinitializing DHT22 sensor");
is_initialized = false;
memset(&current_config, 0, sizeof(dht22_config_t));
ESP_LOGI(TAG, "DHT22 sensor deinitialized");
return ESP_OK;
}

112
dht22_sensor.h Normal file
View File

@@ -0,0 +1,112 @@
#ifndef DHT22_SENSOR_H
#define DHT22_SENSOR_H
#include "driver/gpio.h"
#include "esp_err.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief DHT22 result codes
*/
typedef enum
{
DHT22_OK = 0, /**< Reading successful */
DHT22_TIMEOUT_ERROR = -1, /**< Timeout during communication */
DHT22_CHECKSUM_ERROR = -2 /**< Checksum verification failed */
} dht22_result_t;
/**
* @brief DHT22 sensor configuration
*/
typedef struct
{
int gpio_pin; /**< GPIO pin number where DHT22 is connected */
uint32_t start_signal_us; /**< Start signal duration in microseconds (default: 18000) */
uint32_t response_timeout_us; /**< Response timeout in microseconds (default: 500) */
uint32_t data_timeout_us; /**< Data bit timeout in microseconds (default: 150) */
uint32_t bit_threshold_us; /**< Threshold for distinguishing 0/1 bits (default: 40) */
} dht22_config_t;
/**
* @brief DHT22 sensor data structure
*/
typedef struct
{
float temperature; /**< Temperature in degrees Celsius */
float humidity; /**< Relative humidity percentage */
} dht22_data_t;
/**
* @brief Initialize DHT22 sensor with default configuration
*
* @param gpio_pin GPIO pin number where DHT22 is connected
* @return esp_err_t ESP_OK on success, error code on failure
*/
esp_err_t dht22_init(int gpio_pin);
/**
* @brief Initialize DHT22 sensor with custom configuration
*
* @param config DHT22 configuration parameters
* @return esp_err_t ESP_OK on success, error code on failure
*/
esp_err_t dht22_init_with_config(const dht22_config_t *config);
/**
* @brief Read temperature and humidity from DHT22 sensor
*
* @param temperature Pointer to store temperature value (in Celsius)
* @param humidity Pointer to store humidity value (in percentage)
* @return dht22_result_t DHT22_OK on success, error code on failure
*/
dht22_result_t dht22_read(float *temperature, float *humidity);
/**
* @brief Read temperature and humidity into data structure
*
* @param data Pointer to DHT22 data structure to fill
* @return dht22_result_t DHT22_OK on success, error code on failure
*/
dht22_result_t dht22_read_data(dht22_data_t *data);
/**
* @brief Read from specific GPIO pin (for multiple sensors)
*
* @param gpio_pin GPIO pin number
* @param temperature Pointer to store temperature value
* @param humidity Pointer to store humidity value
* @return dht22_result_t DHT22_OK on success, error code on failure
*/
dht22_result_t dht22_read_from_pin(int gpio_pin, float *temperature, float *humidity);
/**
* @brief Get last error message as string
*
* @param result DHT22 result code
* @return const char* Human-readable error message
*/
const char *dht22_get_error_string(dht22_result_t result);
/**
* @brief Check if DHT22 sensor is properly connected and responding
*
* @return true if sensor responds correctly, false otherwise
*/
bool dht22_test_connection(void);
/**
* @brief Deinitialize DHT22 sensor
*
* @return esp_err_t ESP_OK on success, error code on failure
*/
esp_err_t dht22_deinit(void);
#ifdef __cplusplus
}
#endif
#endif // DHT22_SENSOR_H

16
library.json Normal file
View File

@@ -0,0 +1,16 @@
{
"name": "dht22_sensor",
"version": "1.0.0",
"description": "Custom DHT22 sensor library with bit-banging implementation for ESP32",
"keywords": "dht22, am2302, temperature, humidity, sensor, esp32, bitbang",
"authors": {
"name": "ESP32C6-DHT22 Project"
},
"license": "MIT",
"frameworks": [
"espidf"
],
"platforms": [
"espressif32"
]
}