From 85ce092f39aef986fc07c2c10081758fb991d726 Mon Sep 17 00:00:00 2001 From: imi415 Date: Sat, 1 Jan 2022 15:57:04 +0800 Subject: [PATCH] Added DHT refresh logic. --- main/CMakeLists.txt | 8 ++- main/impl/impl_dht.c | 32 ++++++++++ main/impl/impl_dht.h | 10 ++++ main/interface/if_standby.c | 60 ++++++++++++++++--- main/interface/if_standby.h | 24 ++++++++ main/interface/if_wifi.c | 18 ++++++ main/interface/if_wifi.h | 0 main/lib/htu21d/htu21d.c | 44 ++++++++++++++ main/lib/htu21d/htu21d.h | 30 ++++++++++ main/main.c | 32 +++++++++- main/service/service_dht.c | 51 ++++++++++++++++ main/service/service_dht.h | 8 +++ .../helper_wifi.c => service/service_wifi.c} | 0 13 files changed, 305 insertions(+), 12 deletions(-) create mode 100644 main/impl/impl_dht.c create mode 100644 main/impl/impl_dht.h create mode 100644 main/interface/if_wifi.c create mode 100644 main/interface/if_wifi.h create mode 100644 main/lib/htu21d/htu21d.c create mode 100644 main/lib/htu21d/htu21d.h create mode 100644 main/service/service_dht.c create mode 100644 main/service/service_dht.h rename main/{helper/helper_wifi.c => service/service_wifi.c} (100%) diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index efaa733..7a41015 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -4,13 +4,16 @@ idf_component_register(SRCS "assets/fonts/bebas_neue/bebas_neue_120.c" "assets/fonts/material_webfont/material_webfont_32.c" "main.c" - "helper/helper_wifi.c" + "service/service_wifi.c" "impl/impl_btn.c" + "impl/impl_dht.c" "impl/impl_epd.c" "impl/impl_lvgl.c" "interface/if_standby.c" + "interface/if_wifi.c" "lib/epd-spi/src/epd_common.c" "lib/epd-spi/src/epd_panel_gdew042t2.c" + "lib/htu21d/htu21d.c" "lib/lvgl/src/core/lv_disp.c" "lib/lvgl/src/core/lv_event.c" "lib/lvgl/src/core/lv_group.c" @@ -163,11 +166,14 @@ idf_component_register(SRCS "lib/lvgl/src/widgets/lv_switch.c" "lib/lvgl/src/widgets/lv_table.c" "lib/lvgl/src/widgets/lv_textarea.c" + "service/service_dht.c" INCLUDE_DIRS "lib" "lib/epd-spi/include" + "lib/htu21d" "lib/lvgl" "impl" "interface" + "service" ) diff --git a/main/impl/impl_dht.c b/main/impl/impl_dht.c new file mode 100644 index 0000000..4492c41 --- /dev/null +++ b/main/impl/impl_dht.c @@ -0,0 +1,32 @@ +#include "esp_system.h" +#include "driver/i2c.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "impl_dht.h" + +#define IMPL_DHT_I2C_NUM 0 +#define IMPL_DHT_I2C_TIMEOUT 1000 + +htu21d_ret_t impl_dht_i2c_read(void *handle, uint8_t* data, uint8_t len) { + if(i2c_master_read_from_device(IMPL_DHT_I2C_NUM, 0x40, data, len, pdMS_TO_TICKS(IMPL_DHT_I2C_TIMEOUT)) != ESP_OK) { + return HTU21D_ERROR; + } + + return HTU21D_OK; +} + +htu21d_ret_t impl_dht_i2c_write(void *handle, uint8_t* data, uint8_t len) { + if(i2c_master_write_to_device(IMPL_DHT_I2C_NUM, 0x40, data, len, pdMS_TO_TICKS(IMPL_DHT_I2C_TIMEOUT)) != ESP_OK) { + return HTU21D_ERROR; + } + + return HTU21D_OK; +} + +htu21d_ret_t impl_dht_delay(void *handle, uint32_t msec) { + vTaskDelay(pdMS_TO_TICKS(msec)); + + return HTU21D_OK; +} \ No newline at end of file diff --git a/main/impl/impl_dht.h b/main/impl/impl_dht.h new file mode 100644 index 0000000..e98c3f4 --- /dev/null +++ b/main/impl/impl_dht.h @@ -0,0 +1,10 @@ +#ifndef IMPL_DHT_H +#define IMPL_DHT_H + +#include "htu21d.h" + +htu21d_ret_t impl_dht_i2c_read(void *handle, uint8_t* data, uint8_t len); +htu21d_ret_t impl_dht_i2c_write(void *handle, uint8_t* data, uint8_t len); +htu21d_ret_t impl_dht_delay(void *handle, uint32_t msec); + +#endif \ No newline at end of file diff --git a/main/interface/if_standby.c b/main/interface/if_standby.c index f089737..a1766b1 100644 --- a/main/interface/if_standby.c +++ b/main/interface/if_standby.c @@ -3,16 +3,35 @@ #include #include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "impl_lvgl.h" -#define LOG_TAG "IF_STANDBY" +#define LOG_TAG "IF_STANDBY" + +#define IF_EVENT_WIFI_BUTTON 0 +#define IF_EVENT_BAT_BUTTON 1 static TaskHandle_t s_if_standby_handle; -lv_obj_t *g_standby_screen; +lv_obj_t *g_standby_screen; +QueueHandle_t g_standby_screen_queue; +void if_standby_event_handler(lv_event_t *ev) { + int button_event = (int)ev->user_data; + + switch (button_event) { + case IF_EVENT_WIFI_BUTTON: + break; + case IF_EVENT_BAT_BUTTON: + break; + default: + break; + } +} +/** + * @brief Standby screen task, handles GUI element updates through a queue. + * + * @param pvParameters + */ void if_standby_task(void *pvParameters) { impl_lvgl_lock(); @@ -38,6 +57,9 @@ void if_standby_task(void *pvParameters) { lv_obj_t *date_obj = lv_obj_create(top_container); lv_obj_t *battery_obj = lv_btn_create(top_container); + lv_obj_add_event_cb(network_status_obj, if_standby_event_handler, LV_EVENT_CLICKED, (void *)IF_EVENT_WIFI_BUTTON); + lv_obj_add_event_cb(battery_obj, if_standby_event_handler, LV_EVENT_CLICKED, (void *)IF_EVENT_BAT_BUTTON); + lv_obj_set_size(network_status_obj, 50, 50); lv_obj_set_size(battery_obj, 50, 50); @@ -105,9 +127,9 @@ void if_standby_task(void *pvParameters) { lv_label_set_text(date_label, "1970/01/01"); lv_label_set_text(time_label, "23:59"); lv_label_set_text(temp_icon_label, "\U000F0599"); - lv_label_set_text(temp_label, "30.00C"); + lv_label_set_text(temp_label, "30.00"); lv_label_set_text(humid_icon_label, "\U000F058C"); - lv_label_set_text(humid_label, "100.00%"); + lv_label_set_text(humid_label, "100.00"); lv_obj_set_align(network_status_label, LV_ALIGN_CENTER); lv_obj_set_align(battery_label, LV_ALIGN_CENTER); @@ -123,9 +145,26 @@ void if_standby_task(void *pvParameters) { ESP_LOGI(LOG_TAG, "Standby screen created."); + if_standby_queue_t queue_item; + for (;;) { - // Wait for notifications. - vTaskSuspend(NULL); + // Read from queue for UI element updates. + xQueueReceive(g_standby_screen_queue, &queue_item, portMAX_DELAY); + impl_lvgl_lock(); + switch (queue_item.item) { + case IF_STANDBY_ITEM_TEMP: + lv_label_set_text(temp_label, queue_item.payload); + lv_obj_align(temp_label, LV_ALIGN_CENTER, 0, 16); + break; + case IF_STANDBY_ITEM_HUMID: + lv_label_set_text(humid_label, queue_item.payload); + lv_obj_align(humid_label, LV_ALIGN_CENTER, 0, 16); + + break; + default: + break; + } + impl_lvgl_unlock(); } } @@ -135,6 +174,11 @@ esp_err_t if_standby_init(void) { lv_disp_load_scr(g_standby_screen); impl_lvgl_unlock(); + g_standby_screen_queue = xQueueCreate(8, sizeof(if_standby_queue_t)); + if(g_standby_screen_queue == NULL) { + return ESP_FAIL; + } + if (xTaskCreate(if_standby_task, "STBY_TASK", 4096, NULL, 6, &s_if_standby_handle) != pdPASS) { return ESP_FAIL; } diff --git a/main/interface/if_standby.h b/main/interface/if_standby.h index 0bde1ab..83315a5 100644 --- a/main/interface/if_standby.h +++ b/main/interface/if_standby.h @@ -2,6 +2,30 @@ #define IF_STANDBY_H #include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +#include "lvgl.h" + +typedef enum { + IF_STANDBY_ITEM_WIFI, + IF_STANDBY_ITEM_WEEKDAY, + IF_STANDBY_ITEM_DATE, + IF_STANDBY_ITEM_BAT, + IF_STANDBY_ITEM_TIME, + IF_STANDBY_ITEM_TEMP, + IF_STANDBY_ITEM_HUMID, +} if_standby_item_t ; + +typedef struct { + if_standby_item_t item; + char payload[16]; +} if_standby_queue_t; + +extern lv_obj_t *g_standby_screen; +extern QueueHandle_t g_standby_screen_queue; + esp_err_t if_standby_init(void); #endif \ No newline at end of file diff --git a/main/interface/if_wifi.c b/main/interface/if_wifi.c new file mode 100644 index 0000000..c72f3ba --- /dev/null +++ b/main/interface/if_wifi.c @@ -0,0 +1,18 @@ +#include "lvgl.h" + +#include "esp_system.h" + +/** + * @brief Initialize WiFi status/configuration component + * + * @param parent_obj + * @return esp_err_t + */ +esp_err_t if_wifi_init(lv_obj_t *parent_obj) { + return ESP_OK; +} + +esp_err_t if_wifi_destroy(void) { + // + return ESP_OK; +} \ No newline at end of file diff --git a/main/interface/if_wifi.h b/main/interface/if_wifi.h new file mode 100644 index 0000000..e69de29 diff --git a/main/lib/htu21d/htu21d.c b/main/lib/htu21d/htu21d.c new file mode 100644 index 0000000..847ccf4 --- /dev/null +++ b/main/lib/htu21d/htu21d.c @@ -0,0 +1,44 @@ +#include "htu21d.h" + +#define HTU21D_REG_MEASURE_TEMP_HOLD 0xE3 +#define HTU21D_REG_MEASURE_TEMP_NOHOLD 0xF3 + +#define HTU21D_REG_MEASURE_HUMID_HOLD 0xE5 +#define HTU21D_REG_MEASURE_HUMID_NOHOLD 0xF5 + +#define HTU21D_REG_READ_USER_REG 0xE7 +#define HTU21D_REG_WRITE_USER_REG 0xE6 + +#define HTU21D_REG_SOFT_RESET 0xFE + +#define HTU21D_ERROR_CHECK(x) \ + if (x != HTU21D_OK) return HTU21D_ERROR + +htu21d_ret_t htu21d_init(htu21d_t *htu) { + uint8_t tx_buf = HTU21D_REG_SOFT_RESET; + HTU21D_ERROR_CHECK(htu->cb.write_cb(htu->user_data, &tx_buf, 0x01)); + return HTU21D_OK; +} + +htu21d_ret_t htu21d_measure(htu21d_t *htu, htu21d_result_t *result) { + uint8_t tx_buf = HTU21D_REG_MEASURE_TEMP_NOHOLD; + uint8_t rx_data[3]; + + HTU21D_ERROR_CHECK(htu->cb.write_cb(htu->user_data, &tx_buf, 0x01)); + HTU21D_ERROR_CHECK(htu->cb.delay_cb(htu->user_data, 50)); + HTU21D_ERROR_CHECK(htu->cb.read_cb(htu->user_data, rx_data, 0x03)); + + uint16_t raw_data = (rx_data[0] << 8U) | (rx_data[1] & 0xFC); + result->temperature = (float)raw_data / 65536.0 * 175.72 - 46.85; + + tx_buf = HTU21D_REG_MEASURE_HUMID_NOHOLD; + + HTU21D_ERROR_CHECK(htu->cb.write_cb(htu->user_data, &tx_buf, 0x01)); + HTU21D_ERROR_CHECK(htu->cb.delay_cb(htu->user_data, 50)); + HTU21D_ERROR_CHECK(htu->cb.read_cb(htu->user_data, rx_data, 0x03)); + + raw_data = (rx_data[0] << 8U) | (rx_data[1] & 0xFC); + result->humidity = (float)raw_data / 65536.0 * 125.0 - 6.0; + + return HTU21D_OK; +} \ No newline at end of file diff --git a/main/lib/htu21d/htu21d.h b/main/lib/htu21d/htu21d.h new file mode 100644 index 0000000..ff6d5c0 --- /dev/null +++ b/main/lib/htu21d/htu21d.h @@ -0,0 +1,30 @@ +#ifndef HTU21D_H +#define HTU21D_H + +#include + +typedef enum { + HTU21D_OK, + HTU21D_ERROR +} htu21d_ret_t; + +typedef struct { + htu21d_ret_t (*write_cb)(void * handle, uint8_t* data, uint8_t len); + htu21d_ret_t (*read_cb)(void *handle, uint8_t* data, uint8_t len); + htu21d_ret_t (*delay_cb)(void *handle, uint32_t msec); +} htu21d_cb_t; + +typedef struct { + float temperature; + float humidity; +} htu21d_result_t; + +typedef struct { + htu21d_cb_t cb; + void *user_data; +} htu21d_t; + +htu21d_ret_t htu21d_init(htu21d_t *htu); +htu21d_ret_t htu21d_measure(htu21d_t *htu, htu21d_result_t *result); + +#endif \ No newline at end of file diff --git a/main/main.c b/main/main.c index f7ce66d..45b3520 100644 --- a/main/main.c +++ b/main/main.c @@ -1,6 +1,7 @@ #include #include "driver/gpio.h" +#include "driver/i2c.h" #include "esp_spi_flash.h" #include "esp_system.h" #include "nvs_flash.h" @@ -9,8 +10,14 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" // -#include "impl_lvgl.h" #include "if_standby.h" +#include "impl_lvgl.h" +#include "service_dht.h" + +#define APP_I2C_MASTER_NUM 0 +#define APP_I2C_SDA_NUM GPIO_NUM_39 +#define APP_I2C_SCL_NUM GPIO_NUM_40 +#define APP_I2C_HZ 400000 static esp_err_t app_init_nvs(void) { esp_err_t ret = nvs_flash_init(); @@ -22,18 +29,37 @@ static esp_err_t app_init_nvs(void) { return ret; } -static esp_err_t app_init_gpio(void) { return gpio_install_isr_service(0); } +static esp_err_t app_init_gpio(void) { + // + return gpio_install_isr_service(0); +} -esp_err_t impl_lvgl_init(void); +static esp_err_t app_init_i2c(void) { + i2c_config_t cfg = { + .mode = I2C_MODE_MASTER, + .sda_io_num = APP_I2C_SDA_NUM, + .scl_io_num = APP_I2C_SCL_NUM, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = APP_I2C_HZ, + }; + + i2c_param_config(APP_I2C_MASTER_NUM, &cfg); + + return i2c_driver_install(APP_I2C_MASTER_NUM, cfg.mode, 0, 0, 0); +} void app_main(void) { ESP_ERROR_CHECK(app_init_nvs()); ESP_ERROR_CHECK(app_init_gpio()); + ESP_ERROR_CHECK(app_init_i2c()); ESP_ERROR_CHECK(impl_lvgl_init()); ESP_ERROR_CHECK(if_standby_init()); + ESP_ERROR_CHECK(service_dht_init()); + /* Dead loop */ for (;;) { vTaskSuspend(NULL); diff --git a/main/service/service_dht.c b/main/service/service_dht.c new file mode 100644 index 0000000..eebcdf3 --- /dev/null +++ b/main/service/service_dht.c @@ -0,0 +1,51 @@ +#include "service_dht.h" + +#include "esp_log.h" +#include "if_standby.h" +#include "impl_dht.h" + +#define LOG_TAG "SERVICE_DHT" + +static htu21d_t s_htu = { + .cb = + { + .read_cb = impl_dht_i2c_read, + .write_cb = impl_dht_i2c_write, + .delay_cb = impl_dht_delay, + }, + .user_data = NULL, +}; + +static TaskHandle_t s_dht_task_handle; + +void dht_task(void *pvParameters) { + if_standby_queue_t queue_item; + + htu21d_result_t result; + + for (;;) { + while(htu21d_measure(&s_htu, &result) != HTU21D_OK) { + vTaskDelay(pdMS_TO_TICKS(100)); + } + + queue_item.item = IF_STANDBY_ITEM_TEMP, + snprintf(queue_item.payload, 16, "%.2f", result.temperature); + xQueueSendToBack(g_standby_screen_queue, &queue_item, 0); + + queue_item.item = IF_STANDBY_ITEM_HUMID; + snprintf(queue_item.payload, 16, "%.2f", result.humidity); + xQueueSendToBack(g_standby_screen_queue, &queue_item, 0); + + vTaskDelay(pdMS_TO_TICKS(30000)); + } +} + +esp_err_t service_dht_init(void) { + htu21d_init(&s_htu); + + if (xTaskCreate(dht_task, "DHT", 2048, NULL, 6, &s_dht_task_handle) != pdTRUE) { + return ESP_FAIL; + } + + return ESP_OK; +} \ No newline at end of file diff --git a/main/service/service_dht.h b/main/service/service_dht.h new file mode 100644 index 0000000..177e73a --- /dev/null +++ b/main/service/service_dht.h @@ -0,0 +1,8 @@ +#ifndef SERVICE_DHT_H +#define SERVICE_DHT_H + +#include "esp_system.h" + +esp_err_t service_dht_init(void); + +#endif \ No newline at end of file diff --git a/main/helper/helper_wifi.c b/main/service/service_wifi.c similarity index 100% rename from main/helper/helper_wifi.c rename to main/service/service_wifi.c