
01Introduction:
Let’s get straight to the point.
02Content
1. C Language Implementation
#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define DHT11_GPIO 4 // Use GPIO4
#define DHT_TIMEOUT 10000 // 10μs timeout
// Data storage structure
typedef struct {
int humidity;
int temperature;
bool checksum_ok;
} dht11_data;
// Initialize GPIO
void dht11_init() {
gpio_set_direction(DHT11_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(DHT11_GPIO, 1);
}
// Read a single bit of data
static bool read_bit() {
int count = 0;
// Wait for 50μs low level
while (gpio_get_level(DHT11_GPIO) == 0) {
if (count++ > DHT_TIMEOUT) return false;
}
// Measure high level duration
count = 0;
while (gpio_get_level(DHT11_GPIO) == 1) {
if (count++ > DHT_TIMEOUT) return false;
}
return (count > 40); // More than 40μs is 1, otherwise 0
}
// Read complete data packet
bool dht11_read(dht11_data *data) {
uint8_t buffer[5] = {0};
// Send start signal
gpio_set_direction(DHT11_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(DHT11_GPIO, 0);
ets_delay_us(18000); // Hold for at least 18ms
gpio_set_level(DHT11_GPIO, 1);
ets_delay_us(40);
// Switch to input mode
gpio_set_direction(DHT11_GPIO, GPIO_MODE_INPUT);
// Wait for sensor response
int count = 0;
while (gpio_get_level(DHT11_GPIO) == 1) {
if (count++ > DHT_TIMEOUT) return false;
}
// Read 40 bits of data
for (int i=0; i<40; i++) {
buffer[i/8] <<= 1;
if (read_bit()) buffer[i/8] |= 1;
}
// Validate data
data->humidity = buffer[0];
data->temperature = buffer[2];
data->checksum_ok = (buffer[4] == (buffer[0] + buffer[1] + buffer[2] + buffer[3]));
return data->checksum_ok;
}
void app_main() {
dht11_init();
dht11_data sensor_data;
while(1) {
if(dht11_read(&sensor_data)) {
printf("Humidity: %d%%, Temperature: %d℃\n",
sensor_data.humidity,
sensor_data.temperature);
} else {
printf("Sensor read failed\n");
}
vTaskDelay(2000 / portTICK_PERIOD_MS); // 2 seconds interval
}
}
2. C++ Implementation
#include <driver/gpio.h>
#include <esp_log.h>
#include <esp_timer.h>
class DHT11 {
private:
gpio_num_t gpio_pin;
static constexpr const char* TAG = "DHT11";
// Microsecond precision delay
void delay_us(uint64_t us) {
uint64_t start = esp_timer_get_time();
while (esp_timer_get_time() - start < us);
}
// Read a single bit
bool readBit() {
uint32_t count = 0;
// Wait for low level to end (max 80μs)
while (gpio_get_level(gpio_pin) == 0) {
if (count++ > 100) return false; // Timeout protection
}
// Measure high level duration
count = 0;
uint64_t start = esp_timer_get_time();
while (gpio_get_level(gpio_pin) == 1) {
if (esp_timer_get_time() - start > 100) break; // Timeout protection
}
return (esp_timer_get_time() - start) > 40; // >40μs is 1
}
public:
struct SensorData {
float temperature;
float humidity;
bool valid;
};
// Constructor initializes GPIO
DHT11(gpio_num_t pin) : gpio_pin(pin) {
gpio_reset_pin(gpio_pin);
gpio_set_direction(gpio_pin, GPIO_MODE_OUTPUT);
gpio_set_level(gpio_pin, 1);
ESP_LOGI(TAG, "DHT11 initialized on GPIO%d", gpio_pin);
}
// Read sensor data
SensorData readData() {
uint8_t data[5] = {0};
SensorData result = {.valid = false};
// Send start signal
gpio_set_direction(gpio_pin, GPIO_MODE_OUTPUT);
gpio_set_level(gpio_pin, 0);
delay_us(18000); // 18ms low level
gpio_set_level(gpio_pin, 1);
delay_us(40);
// Switch to input mode and wait for response
gpio_set_direction(gpio_pin, GPIO_MODE_INPUT);
delay_us(10);
// Detect DHT response signal
if (gpio_get_level(gpio_pin) != 0) {
ESP_LOGE(TAG, "No response from sensor");
return result;
}
// Read 40 bits of data
for (int i = 0; i < 40; i++) {
data[i/8] <<= 1;
if (readBit()) data[i/8] |= 1;
}
// Validate data
if (data[4] == (data[0] + data[1] + data[2] + data[3])) {
result.humidity = data[0] + data[1] * 0.1f;
result.temperature = data[2] + data[3] * 0.1f;
result.valid = true;
}
return result;
}
};
// Usage example
extern "C" void app_main() {
DHT11 sensor(GPIO_NUM_4);
while (1) {
auto data = sensor.readData();
if (data.valid) {
ESP_LOGI("MAIN", "Humidity: %.1f%%, Temperature: %.1f℃",
data.humidity, data.temperature);
} else {
ESP_LOGW("MAIN", "Invalid data");
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
03Conclusion