From cd6c42f90355a36924530ab5d71de9bad467d0f3 Mon Sep 17 00:00:00 2001 From: imi415 Date: Thu, 7 Jul 2022 01:29:53 +0800 Subject: [PATCH] Added DHT task. --- main/CMakeLists.txt | 1 + main/Kconfig.projbuild | 17 ++++++ main/app_dht.c | 124 ++++++++++++++++++++++++++++++++++++++++ main/app_mqtt.c | 52 ++++++++++++++++- main/include/app_dht.h | 8 +++ main/include/app_mqtt.h | 1 + main/main.c | 17 ++++-- 7 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 main/app_dht.c create mode 100644 main/include/app_dht.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 6cfedf0..fd2ed3f 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,5 +1,6 @@ idf_component_register( SRCS + "app_dht.c" "app_mqtt.c" "app_wifi.c" "main.c" diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 592cd1e..edf77bf 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -1,4 +1,21 @@ menu "Application Configuration" + config APP_I2C_SCL_PIN + int "I2C SCL IO number" + default 22 + help + I2C pins connected to the sensor + + config APP_I2C_SDA_PIN + int "I2C SDA IO number" + default 21 + help + I2C pins connected to the sensor + + config APP_SNTP_POOL_ADDR + string "SNTP Pool Address" + default "cn.pool.ntp.org" + help + NTP pool address. config APP_WIFI_SSID string "WiFi SSID" diff --git a/main/app_dht.c b/main/app_dht.c new file mode 100644 index 0000000..4cf537e --- /dev/null +++ b/main/app_dht.c @@ -0,0 +1,124 @@ +#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; +} \ No newline at end of file diff --git a/main/app_mqtt.c b/main/app_mqtt.c index 69459c5..b40f96b 100644 --- a/main/app_mqtt.c +++ b/main/app_mqtt.c @@ -3,12 +3,24 @@ #include "esp_system.h" #include "esp_tls.h" +/* FreeRTOS */ +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" + /* Cert bundle */ #include "esp_crt_bundle.h" /* MQTT client */ #include "mqtt_client.h" +#define APP_LOG_TAG "APP_MQTT" + +typedef struct { + char *topic; + char *payload; +} app_mqtt_queue_item_t; + extern const char mqtt_client_cert_start[] asm("_binary_client_crt_start"); extern const char mqtt_client_cert_end[] asm("_binary_client_crt_end"); extern const char mqtt_client_key_start[] asm("_binary_client_key_start"); @@ -17,7 +29,14 @@ extern const char mqtt_client_key_end[] asm("_binary_client_key_end"); static void app_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void app_mqtt_task(void *pvParameters); +static QueueHandle_t s_app_mqtt_publish_queue; + esp_err_t app_mqtt_init(void) { + s_app_mqtt_publish_queue = xQueueCreate(4, sizeof(app_mqtt_queue_item_t)); + if(s_app_mqtt_publish_queue == NULL) { + return ESP_FAIL; + } + if (xTaskCreate(app_mqtt_task, "MQ_TASK", 2048, NULL, 2U, NULL) != pdPASS) { return ESP_FAIL; } @@ -25,6 +44,29 @@ esp_err_t app_mqtt_init(void) { return ESP_OK; } +esp_err_t app_mqtt_publish(char *topic, char *payload) { + app_mqtt_queue_item_t item; + item.topic = malloc(strlen(topic) + 1); + if(item.topic == NULL) return ESP_FAIL; + + item.payload = malloc(strlen(payload) + 1); + if(item.payload == NULL) { + free(item.topic); + return ESP_FAIL; + } + + strcpy(item.topic, topic); + strcpy(item.payload, payload); + + if(xQueueSend(s_app_mqtt_publish_queue, &item, portMAX_DELAY) != pdPASS) { + free(item.topic); + free(item.payload); + return ESP_FAIL; + } + + return ESP_OK; +} + static void app_mqtt_task(void *pvParameters) { const esp_mqtt_client_config_t mqtt_cfg = { .uri = CONFIG_APP_MQTT_BROKER_ADDR, @@ -40,8 +82,16 @@ static void app_mqtt_task(void *pvParameters) { esp_mqtt_client_start(client); + app_mqtt_queue_item_t item; + for (;;) { - vTaskSuspend(NULL); + if(xQueueReceive(s_app_mqtt_publish_queue, &item, portMAX_DELAY) == pdPASS) { + esp_mqtt_client_publish(client, item.topic, item.payload, strlen(item.payload), 0, 0); + + /* This is alloc'ed by us. */ + free(item.topic); + free(item.payload); + } } } diff --git a/main/include/app_dht.h b/main/include/app_dht.h new file mode 100644 index 0000000..092a58d --- /dev/null +++ b/main/include/app_dht.h @@ -0,0 +1,8 @@ +#ifndef APP_DHT_H +#define APP_DHT_H + +#include "esp_system.h" + +esp_err_t app_dht_init(void); + +#endif \ No newline at end of file diff --git a/main/include/app_mqtt.h b/main/include/app_mqtt.h index 4adf7ae..bdfa5a1 100644 --- a/main/include/app_mqtt.h +++ b/main/include/app_mqtt.h @@ -4,5 +4,6 @@ #include "esp_system.h" esp_err_t app_mqtt_init(void); +esp_err_t app_mqtt_publish(char *topic, char *payload); #endif \ No newline at end of file diff --git a/main/main.c b/main/main.c index f1e493d..42ad371 100644 --- a/main/main.c +++ b/main/main.c @@ -8,6 +8,7 @@ /* ESP drivers */ #include "esp_log.h" +#include "esp_sntp.h" /* FreeRTOS */ #include "freertos/FreeRTOS.h" @@ -17,11 +18,12 @@ #include "nvs_flash.h" /* Config */ -#include "app_wifi.h" +#include "app_dht.h" #include "app_mqtt.h" +#include "app_wifi.h" #include "sdkconfig.h" -#define APP_LOG_TAG "MAIN" +#define APP_LOG_TAG "APP_MAIN" void app_main(void) { printf("Hello world!\n"); @@ -44,10 +46,15 @@ void app_main(void) { pdFALSE, pdFALSE, portMAX_DELAY); if (bits & APP_WIFI_EVENT_GROUP_EVENT_FAILED) { - /* ?? */ + return; } - ESP_ERROR_CHECK(app_mqtt_init()); + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_setservername(0, CONFIG_APP_SNTP_POOL_ADDR); + sntp_init(); - vTaskSuspend(NULL); + ESP_ERROR_CHECK(app_mqtt_init()); + ESP_ERROR_CHECK(app_dht_init()); + + /* This task will be deleted if this function returns. */ }