#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include <esp_timer.h>
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "esp_log.h"
#include "driver/gpio.h"
#include "DHT.h"
int DHTgpio = GPIO_NUM_4;
float humidity = 0.;
float temperature = 0.;
unsigned long lastReadTime;
static const char *TAG = "DHT";
float getHumidity() { return humidity; }
float getTemperature() { return temperature; }
void DHT_task(void *pvParameter)
{
//setDHTgpio(GPIO_NUM_4);
//ESP_LOGI(TAG, "Starting DHT Task\n\n");
printf("Starting DHT Task\n");
while (1)
{
printf("=== Reading DHT ===\n");
int ret = readDHT();
errorHandler(ret);
printf("Hum: %.1f Tmp: %.1f\n", getHumidity(), getTemperature());
// -- wait at least 3 sec before reading again ------------
// The interval of whole process must be beyond 2 seconds !!
vTaskDelay(3000 / portTICK_PERIOD_MS);
}
}
void app_main() {
//xTaskCreate(&DHT_task, "DHT_task", 2048, NULL, 5, NULL);
while (true) {
printf("=== Reading DHT ===\n");
int ret = readDHT();
errorHandler(ret);
printf("Hum: %.1f Tmp: %.1f\n", getHumidity(), getTemperature());
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
void errorHandler(int response)
{
printf("errorHandler\n");
switch (response)
{
case DHT_TIMEOUT_ERROR:
printf("Sensor Timeout\n");
ESP_LOGE(TAG, "Sensor Timeout\n");
break;
case DHT_CHECKSUM_ERROR:
printf("CheckSum error\n");
ESP_LOGE(TAG, "CheckSum error\n");
break;
case DHT_OK:
printf("DHT_OK\n");
break;
default:
printf("Unknown error\n");
ESP_LOGE(TAG, "Unknown error\n");
}
}
int getSignalLevel(int usTimeOut, bool state)
{
int uSec = 0;
while (gpio_get_level(DHTgpio) == state)
{
if (uSec > usTimeOut)
return -1;
++uSec;
esp_rom_delay_us(1); // uSec delay
}
return uSec;
}
#define MAXdhtData 5 // to complete 40 = 5*8 Bits
int readDHT()
{
int64_t startTime = esp_timer_get_time();
if (lastReadTime && (unsigned long)(startTime - lastReadTime) < 2000000)
{
printf("Too fast\n");
return DHT_CHECKSUM_ERROR;
}
lastReadTime = startTime;
int uSec = 0;
uint8_t dhtData[MAXdhtData];
uint8_t byteInx = 0;
uint8_t bitInx = 7;
uint16_t rawHumidity = 0;
uint16_t rawTemperature = 0;
uint16_t data = 0;
for (int k = 0; k < MAXdhtData; k++)
dhtData[k] = 0;
// == Send start signal to DHT sensor ===========
gpio_set_direction(DHTgpio, GPIO_MODE_OUTPUT);
// pull down for 3 ms for a smooth and nice wake up
gpio_set_level(DHTgpio, 0);
esp_rom_delay_us(18000);
// pull up for 25 us for a gentile asking for data
gpio_set_direction(DHTgpio, GPIO_MODE_INPUT); // change to input mode
gpio_set_level(DHTgpio, 1);
esp_rom_delay_us(25);
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&mux);
for (int8_t i = -3; i < 2 * 40; i++)
{
//byte age;
uint8_t age = 0;
startTime = esp_timer_get_time();
do
{
age = (unsigned long)(esp_timer_get_time() - startTime);
if (age > 90)
{
//error = ERROR_TIMEOUT;
portEXIT_CRITICAL(&mux);
printf("sad\n");
return DHT_TIMEOUT_ERROR;
}
} while (gpio_get_level(DHTgpio) == (i & 1) ? 1 : 0);
if (i >= 0 && (i & 1))
{
// Now we are being fed our 40 bits
data <<= 1;
// A zero max 30 usecs, a one at least 68 usecs.
if (age > 30)
{
data |= 1; // we got a one
}
}
switch (i)
{
case 31:
rawHumidity = data;
break;
case 63:
rawTemperature = data;
data = 0;
break;
}
}
portEXIT_CRITICAL(&mux);
if ((uint8_t)((uint16_t)(rawHumidity + (rawHumidity >> 8) + rawTemperature + (rawTemperature >> 8))) != data) {
return DHT_CHECKSUM_ERROR;
}
humidity = rawHumidity * 0.1;
if (rawTemperature & 0x8000)
{
rawTemperature = -(int16_t)(rawTemperature & 0x7FFF);
}
temperature = ((int16_t)rawTemperature) * 0.1;
return DHT_OK;
}
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
dht1:VCC
dht1:SDA
dht1:NC
dht1:GND