diff --git a/components/dht22/CMakeLists.txt b/components/dht22/CMakeLists.txt index 9efdacd..657b67a 100644 --- a/components/dht22/CMakeLists.txt +++ b/components/dht22/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "dht22.c" INCLUDE_DIRS "." - REQUIRES driver) + REQUIRES driver esp_timer) diff --git a/components/dht22/dht22.c b/components/dht22/dht22.c index 7c64386..90d994f 100644 --- a/components/dht22/dht22.c +++ b/components/dht22/dht22.c @@ -1,6 +1,11 @@ #include "dht22.h" #include "esp_log.h" +#include "hal/gpio_types.h" #include "sdkconfig.h" +#include "driver/gpio.h" +#include +#include "esp_timer.h" +#include "freertos/portmacro.h" #define DATA_GPIO CONFIG_DHT22_DATA_GPIO @@ -24,8 +29,65 @@ void dht22_handle_error(dht22_error e) { dht22_error dht22_read() { uint8_t data[5] = {0}; + uint32_t tick_total = 0; - // TODO: Actually figure out how to read the data from the chip. + /* + * From datasheet: + * - Host pulls low "beyond at least 1ms" + * - Host pulls up 20us to 40us + */ + gpio_set_direction(CONFIG_DHT22_DATA_GPIO, GPIO_MODE_OUTPUT); + + gpio_set_level(CONFIG_DHT22_DATA_GPIO, 0); + ets_delay_us(5000); + + gpio_set_level(CONFIG_DHT22_DATA_GPIO, 1); + ets_delay_us(25); + + /* + * From datasheet: + * - DHT pulls low 80us + * - DHT pulls high 80us + */ + gpio_set_direction(CONFIG_DHT22_DATA_GPIO, GPIO_MODE_INPUT); + + // Maybe wait here until it goes high? + while (gpio_get_level(CONFIG_DHT22_DATA_GPIO) == 1) { + // wait for a while - should only be 20 uS + } + + + uint64_t start_time = esp_timer_get_time(); + + while (gpio_get_level(CONFIG_DHT22_DATA_GPIO) == 0) { + tick_total += 1; + if (tick_total == UINT32_MAX - 1) { + return DHT22_TIMING_ERROR; + } + } + uint64_t next_time = esp_timer_get_time(); + uint32_t elapsed_time = next_time - start_time; + if (elapsed_time < 75 || elapsed_time > 85) { + return DHT22_TIMING_ERROR; + } + + tick_total = 0; + start_time = esp_timer_get_time(); + while (gpio_get_level(CONFIG_DHT22_DATA_GPIO) == 0) { + tick_total += 1; + if (tick_total == UINT32_MAX - 1) { + return DHT22_TIMING_ERROR; + } + } + next_time = esp_timer_get_time(); + elapsed_time = next_time - start_time; + + portENABLE_INTERRUPTS(); + ESP_LOGW(TAG, "etime: %lu", elapsed_time); + + if (elapsed_time < 70 || elapsed_time > 90) { + return DHT22_TIMING_ERROR; + } // TODO test that data[x] << 8 will be promoted to 16bits otherwise I'm // shifting them to just zeros diff --git a/main/main.c b/main/main.c index 1c99702..d1a7681 100644 --- a/main/main.c +++ b/main/main.c @@ -70,6 +70,7 @@ void read_from_dht22() { portDISABLE_INTERRUPTS(); int ret = dht22_read(); portENABLE_INTERRUPTS(); + ESP_LOGE(TAG, "dht_ret: %i", ret); if (ret != DHT22_OK) { dht22_handle_error(ret); } else { @@ -79,8 +80,8 @@ void read_from_dht22() { if (has_ntp_time_obtained_once()) { // I _think_ I only want to be doing that rolling average and saving // if/when we've got an actual time to do that with. I think that'd - // avoid some weird bugs (time changing from 1970 -> current time within - // a 10 min period) + // avoid some weird bugs (e.g. time changing from 1970 -> current time within + // a 10 min period or just saving data saying it's from the 70s) if (num_samples_last_ten_mins == 0) { ten_minute_rolling_average.rh = latest_datapoint.rh; @@ -100,7 +101,7 @@ void read_from_dht22() { // samples per 10 minutes than can be stored in a uint32 - I'll // calculate what that is and perhaps raise a compile error if too high. if (num_samples_last_ten_mins >= - (CONFIG_DHT22_PERIOD_POLL * 1000 * 60 * 10)) { + ((uint32_t) CONFIG_DHT22_PERIOD_POLL * 1000 * 60 * 10)) { num_samples_last_ten_mins = 0; time_t epoch; @@ -158,5 +159,5 @@ void app_main(void) { #endif /* CONFIG_PMS5003_ENABLED */ - start_wifi(); + //start_wifi(); }