#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#define DHT_GPIO 4
// Fungsi pembantu untuk menunggu perubahan level pin
static int wait_level(int level, uint32_t timeout_us) {
uint32_t start = esp_timer_get_time();
while (gpio_get_level(DHT_GPIO) != level) {
if (esp_timer_get_time() - start > timeout_us) return -1;
}
return esp_timer_get_time() - start;
}
void detect_and_read_dht() {
uint8_t data[5] = {0,0,0,0,0};
// --- 1. Sinyal Start ---
gpio_set_direction(DHT_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(DHT_GPIO, 0);
vTaskDelay(pdMS_TO_TICKS(20));
gpio_set_level(DHT_GPIO, 1);
esp_rom_delay_us(30);
gpio_set_direction(DHT_GPIO, GPIO_MODE_INPUT);
// --- 2. Respon Sensor ---
if (wait_level(0, 100) < 0 || wait_level(1, 100) < 0 || wait_level(0, 100) < 0) {
printf("[ERROR] Sensor tidak merespon!\n");
return;
}
// --- 3. Baca 40 Bit Data ---
for (int i = 0; i < 40; i++) {
if (wait_level(1, 100) < 0) return;
uint32_t duration = wait_level(0, 100);
if (duration > 40) {
data[i / 8] |= (1 << (7 - (i % 8)));
}
}
// --- 4. Cek Checksum ---
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
float temp, hum;
const char* sensor_type;
/* LOGIKA DETEKSI:
DHT11: Mengirim nilai desimal (byte 1 & 3) yang biasanya 0.
DHT22: Mengirim nilai 16-bit utuh.
SIMULASI: Kita bisa memaksa logika mendeteksi DHT11 jika nilai
byte 1 dan 3 sangat kecil (khas simulasi Wokwi untuk DHT11).
*/
if (data[1] == 0 && data[3] == 0) {
// TERDETEKSI SEBAGAI DHT11
sensor_type = "DHT11 (Blue)";
hum = (float)data[0];
temp = (float)data[2];
} else {
// TERDETEKSI SEBAGAI DHT22
sensor_type = "DHT22 (White)";
hum = ((data[0] << 8) | data[1]) / 10.0;
temp = (((data[2] & 0x7F) << 8) | data[3]) / 10.0;
if (data[2] & 0x80) temp *= -1;
}
printf("------------------------------------------\n");
printf("SENSOR TYPE : %s\n", sensor_type);
printf("DATA RAW : [%02X %02X %02X %02X %02X]\n", data[0], data[1], data[2], data[3], data[4]);
printf("RESULT : %.1f°C | %.1f%%\n", temp, hum);
printf("------------------------------------------\n");
} else {
printf("[CHECKSUM ERROR] Data rusak!\n");
}
}
void app_main(void) {
vTaskDelay(pdMS_TO_TICKS(1000));
while(1) {
detect_and_read_dht();
vTaskDelay(pdMS_TO_TICKS(3000)); // Delay lebih lama agar stabil
}
}