Files
dht22_sensor/README.md
Andrey Aleksandrov 4f1f4c9fef readme
2025-12-30 22:07:10 +02:00

15 KiB

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

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:

lib_deps =
    git+https://home.arcoa.eu:8413/esp32libs/dht22_sensor.git

🚀 Quick Start

Basic Usage

#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

#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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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

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

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 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 for version history and changes.

🆘 Support

  • Create an issue 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 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