# DHT22 Sensor Library for ESP32 A robust and feature-rich DHT22/AM2302 sensor library designed for ESP32 development with ESP-IDF framework. This library uses bit-banging implementation for reliable temperature and humidity readings. ## 📋 Features - ✅ **Robust bit-banging implementation** - No dependency on specific hardware timers - ✅ **Configurable timing parameters** - Adjust for different sensor variants - ✅ **Multiple sensor support** - Read from different GPIO pins - ✅ **Comprehensive error handling** - Timeout and checksum validation - ✅ **Thread-safe operations** - Safe for use in multi-task environments - ✅ **Flexible initialization** - Default or custom configuration options - ✅ **Memory efficient** - Minimal RAM footprint - ✅ **Well documented** - Complete API documentation ## 📦 Installation ### Method 1: Git Submodule ```bash cd your_project_directory/lib git submodule add https://home.arcoa.eu:8413/esp32libs/dht22_sensor.git ``` ### Method 2: Manual Copy 1. Clone or download this repository 2. Copy the `dht22_sensor` folder to your project's `lib/` or `components/` directory 3. Include the header in your code: `#include "dht22_sensor.h"` ### Method 3: PlatformIO Library Add to your `platformio.ini`: ```ini lib_deps = git+https://home.arcoa.eu:8413/esp32libs/dht22_sensor.git ``` ## 🚀 Quick Start ### Basic Usage ```c #include "dht22_sensor.h" void app_main(void) { // Initialize DHT22 on GPIO 4 esp_err_t ret = dht22_init(GPIO_NUM_4); if (ret != ESP_OK) { printf("DHT22 initialization failed: %s\n", esp_err_to_name(ret)); return; } while (1) { float temperature, humidity; dht22_result_t result = dht22_read(&temperature, &humidity); if (result == DHT22_OK) { printf("Temperature: %.2f°C, Humidity: %.2f%%\n", temperature, humidity); } else { printf("Read error: %s\n", dht22_get_error_string(result)); } vTaskDelay(pdMS_TO_TICKS(2000)); // Wait 2 seconds } } ``` ### Advanced Usage with Custom Configuration ```c #include "dht22_sensor.h" void app_main(void) { // Custom configuration for different timing requirements dht22_config_t config = { .gpio_pin = GPIO_NUM_4, .start_signal_us = 18000, // 18ms start signal .response_timeout_us = 500, // 500µs response timeout .data_timeout_us = 150, // 150µs data timeout .bit_threshold_us = 40 // 40µs threshold for 0/1 detection }; esp_err_t ret = dht22_init_with_config(&config); if (ret != ESP_OK) { printf("DHT22 initialization failed!\n"); return; } // Test connection if (dht22_test_connection()) { printf("DHT22 sensor detected and responding\n"); } else { printf("DHT22 sensor not responding\n"); return; } while (1) { dht22_data_t sensor_data; dht22_result_t result = dht22_read_data(&sensor_data); if (result == DHT22_OK) { printf("Temperature: %.2f°C\n", sensor_data.temperature); printf("Humidity: %.2f%%\n", sensor_data.humidity); } else { printf("Error reading sensor: %s\n", dht22_get_error_string(result)); } vTaskDelay(pdMS_TO_TICKS(2000)); } } ``` ## 📚 API Reference ### Data Types #### `dht22_result_t` (Enum) Result codes returned by DHT22 read functions: | Value | Description | | --------------------------- | ---------------------------- | | `DHT22_OK` (0) | Reading successful | | `DHT22_TIMEOUT_ERROR` (-1) | Timeout during communication | | `DHT22_CHECKSUM_ERROR` (-2) | Checksum verification failed | #### `dht22_config_t` (Struct) Configuration structure for DHT22 sensor: ```c 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 0/1 bit detection (default: 40) } dht22_config_t; ``` **Field Descriptions:** - `gpio_pin`: Any valid GPIO pin number (0-39 depending on ESP32 variant) - `start_signal_us`: Duration of start signal sent to DHT22 (typically 18000µs) - `response_timeout_us`: Maximum time to wait for sensor response - `data_timeout_us`: Maximum time to wait for each data bit - `bit_threshold_us`: Time threshold to distinguish between 0 and 1 bits #### `dht22_data_t` (Struct) Structure to hold sensor readings: ```c typedef struct { float temperature; // Temperature in degrees Celsius float humidity; // Relative humidity percentage } dht22_data_t; ``` ### Constants #### Default Timing Constants (microseconds) | Constant | Value | Description | | ----------------------------------- | ----- | ----------------------------------- | | `DHT22_DEFAULT_START_SIGNAL_US` | 18000 | Default start signal duration | | `DHT22_DEFAULT_RESPONSE_TIMEOUT_US` | 500 | Default response timeout | | `DHT22_DEFAULT_DATA_TIMEOUT_US` | 150 | Default data bit timeout | | `DHT22_DEFAULT_BIT_THRESHOLD_US` | 40 | Default 0/1 bit detection threshold | ### Functions #### Initialization Functions ##### `esp_err_t dht22_init(int gpio_pin)` Initialize DHT22 sensor with default configuration. **Parameters:** - `gpio_pin`: GPIO pin number where DHT22 data line is connected **Returns:** - `ESP_OK`: Success - `ESP_ERR_INVALID_ARG`: Invalid GPIO pin number - Other ESP error codes on failure **Example:** ```c esp_err_t ret = dht22_init(GPIO_NUM_4); if (ret != ESP_OK) { printf("Init failed: %s\n", esp_err_to_name(ret)); } ``` ##### `esp_err_t dht22_init_with_config(const dht22_config_t *config)` Initialize DHT22 sensor with custom configuration. **Parameters:** - `config`: Pointer to configuration structure **Returns:** - `ESP_OK`: Success - `ESP_ERR_INVALID_ARG`: Invalid configuration or NULL pointer - Other ESP error codes on failure **Example:** ```c dht22_config_t config = { .gpio_pin = GPIO_NUM_4, .start_signal_us = 20000, // Longer start signal .response_timeout_us = 600, .data_timeout_us = 200, .bit_threshold_us = 50 }; esp_err_t ret = dht22_init_with_config(&config); ``` ##### `esp_err_t dht22_deinit(void)` Deinitialize the DHT22 sensor and free resources. **Returns:** - `ESP_OK`: Success - Error code on failure **Example:** ```c dht22_deinit(); ``` #### Reading Functions ##### `dht22_result_t dht22_read(float *temperature, float *humidity)` Read temperature and humidity from the initialized DHT22 sensor. **Parameters:** - `temperature`: Pointer to store temperature value (°C) - `humidity`: Pointer to store humidity value (%) **Returns:** - `DHT22_OK`: Reading successful - `DHT22_TIMEOUT_ERROR`: Communication timeout - `DHT22_CHECKSUM_ERROR`: Data integrity check failed **Example:** ```c float temp, hum; dht22_result_t result = dht22_read(&temp, &hum); if (result == DHT22_OK) { printf("Temp: %.1f°C, Humidity: %.1f%%\n", temp, hum); } ``` ##### `dht22_result_t dht22_read_data(dht22_data_t *data)` Read temperature and humidity into a data structure. **Parameters:** - `data`: Pointer to `dht22_data_t` structure to fill **Returns:** - Same as `dht22_read()` **Example:** ```c dht22_data_t sensor_data; if (dht22_read_data(&sensor_data) == DHT22_OK) { printf("Temperature: %.1f°C\n", sensor_data.temperature); printf("Humidity: %.1f%%\n", sensor_data.humidity); } ``` ##### `dht22_result_t dht22_read_from_pin(int gpio_pin, float *temperature, float *humidity)` Read from a specific GPIO pin (useful for multiple sensors). **Parameters:** - `gpio_pin`: GPIO pin number to read from - `temperature`: Pointer to store temperature value - `humidity`: Pointer to store humidity value **Returns:** - Same as `dht22_read()` **Example:** ```c float temp1, hum1, temp2, hum2; // Read from sensor on GPIO 4 dht22_read_from_pin(GPIO_NUM_4, &temp1, &hum1); // Read from sensor on GPIO 5 dht22_read_from_pin(GPIO_NUM_5, &temp2, &hum2); ``` #### Utility Functions ##### `const char *dht22_get_error_string(dht22_result_t result)` Get human-readable error message for a result code. **Parameters:** - `result`: DHT22 result code **Returns:** - Pointer to error message string **Example:** ```c dht22_result_t result = dht22_read(&temp, &hum); if (result != DHT22_OK) { printf("Error: %s\n", dht22_get_error_string(result)); } ``` ##### `bool dht22_test_connection(void)` Test if DHT22 sensor is properly connected and responding. **Returns:** - `true`: Sensor is connected and responding - `false`: Sensor not detected or not responding **Example:** ```c if (dht22_test_connection()) { printf("Sensor OK\n"); } else { printf("Sensor not detected!\n"); } ``` ## 🔧 Configuration Guide ### GPIO Configuration **Compatible GPIO pins:** - ESP32: All GPIO pins except GPIO 0, 2, 5, 12, 15 (used for boot/flash) - ESP32-C3/C6: GPIO 0-21 (avoid GPIO 18, 19 for USB) - ESP32-S2/S3: GPIO 0-21, 26-45 **Recommended pins:** - GPIO 4, 16, 17, 21, 22, 23 ### Timing Parameters The library uses these timing parameters that can be customized: | Parameter | Default | Range | Description | | ---------------- | ------- | ------------ | ------------------------------------ | | Start Signal | 18000µs | 1000-25000µs | Initial low pulse to wake up sensor | | Response Timeout | 500µs | 100-1000µs | Max time to wait for sensor response | | Data Timeout | 150µs | 50-300µs | Max time to wait for each data bit | | Bit Threshold | 40µs | 20-80µs | Time threshold for 0/1 detection | ### Multiple Sensors To use multiple DHT22 sensors: ```c void multi_sensor_example(void) { // Read from multiple sensors float temp1, hum1, temp2, hum2; dht22_result_t result1 = dht22_read_from_pin(GPIO_NUM_4, &temp1, &hum1); vTaskDelay(pdMS_TO_TICKS(10)); // Small delay between reads dht22_result_t result2 = dht22_read_from_pin(GPIO_NUM_16, &temp2, &hum2); if (result1 == DHT22_OK) { printf("Sensor 1 - Temp: %.1f°C, Hum: %.1f%%\n", temp1, hum1); } if (result2 == DHT22_OK) { printf("Sensor 2 - Temp: %.1f°C, Hum: %.1f%%\n", temp2, hum2); } } ``` ## 🔍 Troubleshooting ### Common Issues 1. **DHT22_TIMEOUT_ERROR** - Check wiring connections - Verify GPIO pin number - Increase timeout values in configuration - Check power supply (3.3V or 5V) 2. **DHT22_CHECKSUM_ERROR** - Check for electromagnetic interference - Verify sensor is not defective - Add pull-up resistor (4.7kΩ) to data line - Reduce cable length 3. **Sensor not detected** - Verify power connections (VCC, GND) - Check data line connection - Test with `dht22_test_connection()` ### Hardware Setup ``` DHT22 Sensor ESP32 ----------- ----- VCC ---- 3.3V (or 5V) GND ---- GND DATA ---- GPIO_NUM_X ``` **Note:** A 4.7kΩ pull-up resistor between DATA and VCC may be required for reliable operation, especially with long cables. ### Reading Frequency - Minimum reading interval: **2 seconds** - Recommended interval: **2-5 seconds** - Maximum frequency: **0.5 Hz** **Important:** DHT22 sensors cannot be read faster than once every 2 seconds due to internal processing time. ## 🧪 Testing ### Connection Test ```c void test_sensor_connection(void) { if (dht22_init(GPIO_NUM_4) == ESP_OK) { if (dht22_test_connection()) { printf("✅ DHT22 sensor detected\n"); } else { printf("❌ DHT22 sensor not responding\n"); } } else { printf("❌ Failed to initialize DHT22\n"); } } ``` ### Comprehensive Test ```c void comprehensive_test(void) { printf("Starting DHT22 comprehensive test...\n"); // Initialize with default settings if (dht22_init(GPIO_NUM_4) != ESP_OK) { printf("❌ Initialization failed\n"); return; } // Test connection if (!dht22_test_connection()) { printf("❌ Connection test failed\n"); return; } printf("✅ Connection test passed\n"); // Perform multiple readings int success_count = 0; int total_readings = 10; for (int i = 0; i < total_readings; i++) { float temp, hum; dht22_result_t result = dht22_read(&temp, &hum); if (result == DHT22_OK) { success_count++; printf("Reading %d: %.1f°C, %.1f%%\n", i+1, temp, hum); } else { printf("Reading %d failed: %s\n", i+1, dht22_get_error_string(result)); } vTaskDelay(pdMS_TO_TICKS(2500)); // 2.5 second interval } printf("Test complete: %d/%d successful readings (%.1f%%)\n", success_count, total_readings, (float)success_count/total_readings*100); } ``` ## 📄 License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## 🤝 Contributing 1. Fork the repository 2. Create your 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 ## 📈 Version History See [CHANGELOG.md](CHANGELOG.md) for version history and changes. ## 🆘 Support - Create an [issue](../../issues) for bug reports or feature requests - Check existing issues for known problems and solutions ## ⚡ Performance Notes - **Memory usage**: ~200 bytes RAM - **CPU impact**: Minimal, bit-banging operations are fast - **Thread safety**: Functions are thread-safe - **Power consumption**: Sensor active only during readings (~2mA for 2ms) - **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