#include /* ESP drivers */ #include "driver/i2c.h" #include "esp_log.h" #include "esp_system.h" /* FreeRTOS */ #include "freertos/FreeRTOS.h" #include "freertos/task.h" /* MQTT */ #include "app_mqtt.h" /* AHT10 */ #include "aht10/aht10.h" /* Log tag */ #define APP_LOG_TAG "APP_DHT" /* Configurations */ #define APP_DHT_I2C_SCL_IO CONFIG_APP_I2C_SCL_PIN #define APP_DHT_I2C_SDA_IO CONFIG_APP_I2C_SDA_PIN #define APP_DHT_I2C_INSTANCE 0 #define APP_DHT_I2C_TIMEOUT 100 #define APP_DHT_AHT10_ADDR 0x38 #define INFLUX_TOPIC "iot/metric" #define INFLUX_HOSTNAME "DHT_Temp" #define INFLUX_FORMATTED_STRING \ "dht,hostname=" INFLUX_HOSTNAME \ " " \ "temperature=%.02lf," \ "humidity=%.02lf" \ " " \ "%llu" static void app_dht_task(void *pvParameters); static uint64_t app_get_nsec_timestamp(void); static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer); static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec); esp_err_t app_dht_init(void) { i2c_config_t cfg = { .mode = I2C_MODE_MASTER, .sda_io_num = APP_DHT_I2C_SDA_IO, .scl_io_num = APP_DHT_I2C_SCL_IO, .sda_pullup_en = GPIO_PULLUP_DISABLE, .scl_pullup_en = GPIO_PULLUP_DISABLE, .master.clk_speed = 400000, }; i2c_param_config(APP_DHT_I2C_INSTANCE, &cfg); if (i2c_driver_install(APP_DHT_I2C_INSTANCE, cfg.mode, 0U, 0U, 0U) != ESP_OK) { return ESP_FAIL; } if (xTaskCreate(app_dht_task, "DHT_TASK", 2048, NULL, 1U, NULL) != pdPASS) { return ESP_FAIL; } return ESP_OK; } static void app_dht_task(void *pvParameters) { aht10_t aht = { .cb = { .xfer = app_dht_impl_xfer, .delay = app_dht_impl_delay, }, }; aht10_init(&aht); aht10_result_t result; char report_buf[256]; uint64_t ns_ts; for (;;) { aht10_measure(&aht, &result); ns_ts = app_get_nsec_timestamp(); /* Simple check to see if NTP is synchronized... */ if (ns_ts > (uint64_t)(1600000000L) * 1000000000) { snprintf(report_buf, 256, INFLUX_FORMATTED_STRING, result.temperature, result.humidity, ns_ts); app_mqtt_publish(INFLUX_TOPIC, report_buf); } vTaskDelay(pdMS_TO_TICKS(500)); } } static uint64_t app_get_nsec_timestamp(void) { struct timeval tv_now; gettimeofday(&tv_now, NULL); int64_t time_ns = (int64_t)tv_now.tv_sec * 1000000000L + (int64_t)tv_now.tv_usec * 1000; return time_ns; } static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer) { esp_err_t ret; if (xfer->rx_size == 0) { ret = i2c_master_write_to_device(APP_DHT_I2C_INSTANCE, APP_DHT_AHT10_ADDR, xfer->tx_data, xfer->tx_size, pdMS_TO_TICKS(APP_DHT_I2C_TIMEOUT)); } else if (xfer->tx_size == 0) { ret = i2c_master_read_from_device(APP_DHT_I2C_INSTANCE, APP_DHT_AHT10_ADDR, xfer->rx_data, xfer->rx_size, pdMS_TO_TICKS(APP_DHT_I2C_TIMEOUT)); } else { ret = i2c_master_write_read_device(APP_DHT_I2C_INSTANCE, APP_DHT_AHT10_ADDR, xfer->tx_data, xfer->tx_size, xfer->rx_data, xfer->rx_size, pdMS_TO_TICKS(APP_DHT_I2C_TIMEOUT)); } if (ret != ESP_OK) { return AHT10_FAIL; } return AHT10_OK; } static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec) { vTaskDelay(pdMS_TO_TICKS(delay_msec)); return AHT10_OK; }