/* * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ #include #include #include #include #include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_chip_info.h" #include "esp_flash.h" #include "esp_system.h" #include "esp_timer.h" #include "driver/gpio.h" // Define the GPIO pin for the DHT11 data line #define DHT11_GPIO 0 void read_dht11(uint8_t *humidity_int, uint8_t *humidity_dec, int8_t *temperature_int, uint8_t *temperature_dec, uint8_t *checksum) { uint8_t data[5] = {0}; // Send start signal: pull the line low for 20ms gpio_set_direction(DHT11_GPIO, GPIO_MODE_OUTPUT); gpio_set_level(DHT11_GPIO, 0); vTaskDelay(pdMS_TO_TICKS(20)); // Release the line and wait for sensor response gpio_set_level(DHT11_GPIO, 1); gpio_set_direction(DHT11_GPIO, GPIO_MODE_INPUT); // Wait for the sensor to pull the line low (~20-40us) while (gpio_get_level(DHT11_GPIO) == 1) { vTaskDelay(pdMS_TO_TICKS(0.1)); } // Wait for the sensor to pull the line high (~80us) while (gpio_get_level(DHT11_GPIO) == 0) { vTaskDelay(pdMS_TO_TICKS(0.1)); } // Read 40 bits of data for (int i = 0; i < 40; i++) { // Wait for the start of the bit (low for ~50us) while (gpio_get_level(DHT11_GPIO) == 1) { vTaskDelay(pdMS_TO_TICKS(0.1)); } while (gpio_get_level(DHT11_GPIO) == 0) { vTaskDelay(pdMS_TO_TICKS(0.1)); } // Measure the length of the high pulse uint32_t pulse_start = esp_timer_get_time(); while (gpio_get_level(DHT11_GPIO) == 1) { vTaskDelay(pdMS_TO_TICKS(0.1)); } uint32_t pulse_end = esp_timer_get_time(); // Determine if the bit is 0 or 1 uint8_t bit = (pulse_end - pulse_start) > 50 ? 1 : 0; data[i / 8] <<= 1; data[i / 8] |= bit; } // Parse the data *humidity_int = data[0]; *humidity_dec = data[1]; // Decimal part (0–9) *temperature_int = (data[2] & 0x7F); // Remove sign bit (0–50) *temperature_dec = data[3]; // Decimal part (0–9) *checksum = data[4]; // Validate checksum uint8_t sum = *humidity_int + *humidity_dec + *temperature_int + *temperature_dec; if (sum != *checksum) { printf("Checksum failed! Retrying...\n"); vTaskDelay(pdMS_TO_TICKS(1000)); read_dht11(humidity_int, humidity_dec, temperature_int, temperature_dec, checksum); } } void set_system_time_from_compiler() { // Parse __DATE__: "Mmm dd yyyy" char date[] = __DATE__; char time[] = __TIME__; struct tm tm = {0}; char month[4]; int day, year; int hour, min, sec; // Parse date sscanf(date, "%3s %d %d", month, &day, &year); // Parse time sscanf(time, "%d:%d:%d", &hour, &min, &sec); // Convert month abbreviation to number const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; for (int i = 0; i < 12; i++) { if (strcmp(month, months[i]) == 0) { tm.tm_mon = i; break; } } tm.tm_mday = day; tm.tm_year = year - 1900; // Years since 1900 tm.tm_hour = hour; tm.tm_min = min; tm.tm_sec = sec; tm.tm_isdst = -1; // Let system determine daylight saving time // Set system time struct timeval tv = { .tv_sec = mktime(&tm), .tv_usec = 0 }; settimeofday(&tv, NULL); } void print_current_time() { time_t now; struct tm timeinfo; char strftime_buf[64]; time(&now); localtime_r(&now, &timeinfo); strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d %H:%M:%S", &timeinfo); printf("Time: %s\n", strftime_buf); } void print_chip_info(){ /* Print chip information */ esp_chip_info_t chip_info; uint32_t flash_size; esp_chip_info(&chip_info); printf("This is %s chip with %d CPU core(s), %s%s%s%s, ", CONFIG_IDF_TARGET, chip_info.cores, (chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "", (chip_info.features & CHIP_FEATURE_BT) ? "BT" : "", (chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "", (chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : ""); unsigned major_rev = chip_info.revision / 100; unsigned minor_rev = chip_info.revision % 100; printf("silicon revision v%d.%d, ", major_rev, minor_rev); if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) { printf("Get flash size failed"); return; } printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024), (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size()); } void app_main(void) { set_system_time_from_compiler(); printf("DHT11 temperature and humidity sensor read and send out\n"); print_chip_info(); while (1) { uint8_t humidity_int, humidity_dec, checksum; int8_t temperature_int; uint8_t temperature_dec; read_dht11(&humidity_int, &humidity_dec, &temperature_int, &temperature_dec, &checksum); // Calculate humidity and temperature float humidity = (float)humidity_int + (float)humidity_dec / 10.0f; float temperature = (float)temperature_int + (float)temperature_dec / 10.0f; // Print results print_current_time(); printf("Humidity: %.1f%%\n", humidity); printf("Temperature: %.1f°C\n", temperature); printf("Checksum valid: %s\n", (checksum == (humidity_int + humidity_dec + temperature_int + temperature_dec)) ? "Yes" : "No"); // Wait 1 minute before next read vTaskDelay(pdMS_TO_TICKS(5000)); } }