From 5d46030fc1fd17d6411ed75230abcdc810a329f3 Mon Sep 17 00:00:00 2001 From: chriswin Date: Sat, 18 Oct 2025 17:18:21 +0200 Subject: [PATCH] clean up --- lilygo-sensor-clock.ino | 366 +++++++++++++++++++--------------------- ui-util.cpp | 76 +++++---- ui-util.h | 3 +- 3 files changed, 222 insertions(+), 223 deletions(-) diff --git a/lilygo-sensor-clock.ino b/lilygo-sensor-clock.ino index 7ea19fb..1c81a26 100644 --- a/lilygo-sensor-clock.ino +++ b/lilygo-sensor-clock.ino @@ -11,19 +11,25 @@ #include "freertos/semphr.h" // Serial -#define BAUD 115200 +#define BAUD 921600 // Sensor pins #define RX2_PIN TOUCH_IICSCL #define TX2_PIN TOUCH_IICSDA // Sensor configuration -#define COMMAND "FDFCFBFA0800120000006400000004030201" //Normal mode command, see documentation waveshare sensor +#define COMMAND "FDFCFBFA0800120000000200000004030203" //Normal mode command, see documentation waveshare sensor #define PRESENCE_DISTANCE 200 // in cm #define DELAY_STATUS_CHECK 1000 // delay (in ms) between two checks of the presence #define SLEEP_DELAY 10000 // delay (in ms) until sleep mode #define POWER_DELAY 30000 // delay (in ms) until turning off the screen +byte configCommand[] = { + 0xFD, 0xFC, 0xFB, 0xFA, 0x08, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x03, + 0x02, 0x03 +}; + SemaphoreHandle_t xSemaphore = NULL; PowersSY6970 PMU; @@ -47,108 +53,80 @@ static String BASE_URL_HA = "http://192.168.1.2:8123/api/services"; static String HA_TOKEN = "abc"; void setup() { + xSemaphore = xSemaphoreCreateBinary(); + xSemaphoreGive(xSemaphore); - xSemaphore = xSemaphoreCreateBinary(); - xSemaphoreGive(xSemaphore); - - initSerial(); - initializeWifi(); - initializeTime(); - sendCommandAsHex(COMMAND); - initializeUI(); + initSerial(); + initializeWifi(); + initializeTime(); + initializeUI(); } void loop() { - delay(1); - if (transfer_num <= 0 && lcd_PushColors_len <= 0) - lv_timer_handler(); + delay(1); + if (transfer_num <= 0 && lcd_PushColors_len <= 0) + lv_timer_handler(); - if (transfer_num <= 1 && lcd_PushColors_len > 0) { - lcd_PushColors(0, 0, 0, 0, NULL); - } - - static int flag_bl = 0; - static unsigned long cnt = 0; - - printLocalTime(); - readAndProcessSensorLines(); - - cnt++; - if (cnt >= 100) { - if (flag_bl == 0) { - pinMode(TFT_BL, OUTPUT); - digitalWrite(TFT_BL, HIGH); - flag_bl = 1; - lv_delay_ms(500); - ui_begin(); + if (transfer_num <= 1 && lcd_PushColors_len > 0) { + lcd_PushColors(0, 0, 0, 0, NULL); + } + + static int flag_bl = 0; + static unsigned long cnt = 0; + + printLocalTime(); + readAndProcessSensorLines(); + + cnt++; + if (cnt >= 100) { + if (flag_bl == 0) { + pinMode(TFT_BL, OUTPUT); + digitalWrite(TFT_BL, HIGH); + flag_bl = 1; + lv_delay_ms(500); + ui_begin(); + } } - } } void initSerial() { - // Start the primary serial communication (USB Monitor) - Serial.begin(BAUD); - unsigned long startAttemptTime = millis(); - while (!Serial && millis() - startAttemptTime < 2000) { - delay(100); - } - Serial.println("Serial Monitor Initialized."); + // Start the primary serial communication (USB Monitor) + Serial.begin(BAUD); + unsigned long startAttemptTime = millis(); + while (!Serial && millis() - startAttemptTime < 2000) { + delay(100); + } + Serial.println("Serial Monitor Initialized."); - pinMode(PIN_BAT_VOLT, ANALOG); + pinMode(PIN_BAT_VOLT, ANALOG); - // Screen - pinMode(TOUCH_RES, OUTPUT); - digitalWrite(TOUCH_RES, HIGH); - delay(2); - digitalWrite(TOUCH_RES, LOW); - delay(10); - digitalWrite(TOUCH_RES, HIGH); - delay(2); + // Screen + pinMode(TOUCH_RES, OUTPUT); + digitalWrite(TOUCH_RES, HIGH); + delay(2); + digitalWrite(TOUCH_RES, LOW); + delay(10); + digitalWrite(TOUCH_RES, HIGH); + delay(2); - // Start Serial2 for the HMMD Sensor - Serial2.begin(BAUD, SERIAL_8N1, RX2_PIN, TX2_PIN); - Serial.println("Serial2 Initialized on RX:" + String(RX2_PIN) + ", TX:" + String(TX2_PIN)); -} - -void sendCommandAsHex(String hexString) { - int hexStringLength = hexString.length(); - if (hexStringLength % 2 != 0) { - Serial.println("Error: Hex string must have an even number of characters."); - return; - } - int byteCount = hexStringLength / 2; - byte hexBytes[byteCount]; - for (int i = 0; i < hexStringLength; i += 2) { - String byteString = hexString.substring(i, i + 2); - byte hexByte = (byte)strtoul(byteString.c_str(), NULL, 16); - hexBytes[i / 2] = hexByte; - } - // Print confirmation of what's being sent - Serial.print("Sending "); - Serial.print(byteCount); - Serial.print(" bytes: "); - for(int i=0; i= WIFI_CONNECT_WAIT_MAX) { - ESP.restart(); - } + delay(200); + Serial.print("."); + if (millis() - connectTime >= WIFI_CONNECT_WAIT_MAX) { + ESP.restart(); + } } Serial.println(); @@ -159,147 +137,151 @@ void initializeWifi() { } void initializeTime() { - Serial.println("Initializing time..."); - configTime(GMT_OFFSET_SEC, DAY_LIGHT_OFFSET_SEC, NTP_SERVER1, NTP_SERVER2); + Serial.println("Initializing time..."); + configTime(GMT_OFFSET_SEC, DAY_LIGHT_OFFSET_SEC, NTP_SERVER1, NTP_SERVER2); } void initializeUI() { + Serial.println("Initializing UI...."); + axs15231_init(); + lv_init(); + size_t buffer_size = + sizeof(lv_color_t) * EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES; + buf = (lv_color_t *)ps_malloc(buffer_size); + if (buf == NULL) { + while (1) { + Serial.println("buf NULL"); + delay(500); + } + } - Serial.println("Initializing UI...."); - axs15231_init(); - lv_init(); - size_t buffer_size = - sizeof(lv_color_t) * EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES; - buf = (lv_color_t *)ps_malloc(buffer_size); - if (buf == NULL) { - while (1) { - Serial.println("buf NULL"); - delay(500); - } - } + buf1 = (lv_color_t *)ps_malloc(buffer_size); + if (buf1 == NULL) { + while (1) { + Serial.println("buf NULL"); + delay(500); + } + } - buf1 = (lv_color_t *)ps_malloc(buffer_size); - if (buf1 == NULL) { - while (1) { - Serial.println("buf NULL"); - delay(500); - } - } + lv_disp_draw_buf_init(&draw_buf, buf, buf1, buffer_size); + /*Initialize the display*/ + static lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + /*Change the following line to your display resolution*/ + disp_drv.hor_res = EXAMPLE_LCD_H_RES; + disp_drv.ver_res = EXAMPLE_LCD_V_RES; + disp_drv.flush_cb = my_disp_flush; + disp_drv.draw_buf = &draw_buf; + disp_drv.sw_rotate = 1; // If you turn on software rotation, Do not update or replace LVGL + disp_drv.rotated = LV_DISP_ROT_90; + disp_drv.full_refresh = 1; // full_refresh must be 1 + lv_disp_drv_register(&disp_drv); - lv_disp_draw_buf_init(&draw_buf, buf, buf1, buffer_size); - /*Initialize the display*/ - static lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); - /*Change the following line to your display resolution*/ - disp_drv.hor_res = EXAMPLE_LCD_H_RES; - disp_drv.ver_res = EXAMPLE_LCD_V_RES; - disp_drv.flush_cb = my_disp_flush; - disp_drv.draw_buf = &draw_buf; - disp_drv.sw_rotate = 1; // If you turn on software rotation, Do not update or replace LVGL - disp_drv.rotated = LV_DISP_ROT_90; - disp_drv.full_refresh = 1; // full_refresh must be 1 - lv_disp_drv_register(&disp_drv); + static lv_indev_drv_t indev_drv; + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_POINTER; + lv_indev_drv_register(&indev_drv); - static lv_indev_drv_t indev_drv; - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - lv_indev_drv_register(&indev_drv); - - Serial.println("UI initialized"); + Serial.println("UI initialized"); } void printLocalTime() { - if (millis() - last_tick > 100) { - struct tm timeInfo; - if(!getLocalTime(&timeInfo)){ - Serial.println("Failed to obtain time"); - } else { - lv_msg_send(MSG_NEW_HOUR, &timeInfo.tm_hour); - lv_msg_send(MSG_NEW_MIN, &timeInfo.tm_min); - lv_msg_send(MSG_NEW_SEC, &timeInfo.tm_sec); + if (millis() - last_tick > 100) { + struct tm timeInfo; + if(!getLocalTime(&timeInfo)){ + Serial.println("Failed to obtain time"); + } else { + lv_msg_send(MSG_NEW_HOUR, &timeInfo.tm_hour); + lv_msg_send(MSG_NEW_MIN, &timeInfo.tm_min); + lv_msg_send(MSG_NEW_SEC, &timeInfo.tm_sec); + } + last_tick = millis(); } - last_tick = millis(); - } } void readAndProcessSensorLines() { + if (millis() - lastMotionCheckTime >= DELAY_STATUS_CHECK) { + lastMotionCheckTime = millis(); + // Check if data is available on Serial2 + while (Serial2.available() > 0) { + // Read a line of text until a newline character (\n) is received + // The timeout helps prevent blocking forever if a line ending is missed + String line = Serial2.readStringUntil('\n'); + + // Clean up the line: remove potential carriage return (\r) and leading/trailing whitespace + line.trim(); + + // Check if the line contains the "Range" information + if (line.startsWith("Range ")) { + // Extract the substring after "Range " + String distanceStr = line.substring(6); + int distance = distanceStr.toInt(); + bool currentStatus = distance <= PRESENCE_DISTANCE; - if (millis() - lastMotionCheckTime >= DELAY_STATUS_CHECK) { - lastMotionCheckTime = millis(); - // Check if data is available on Serial2 - while (Serial2.available() > 0) { - // Read a line of text until a newline character (\n) is received - // The timeout helps prevent blocking forever if a line ending is missed - String line = Serial2.readStringUntil('\n'); - - // Clean up the line: remove potential carriage return (\r) and leading/trailing whitespace - line.trim(); - - // Check if the line contains the "Range" information - if (line.startsWith("Range ")) { - // Extract the substring after "Range " - String distanceStr = line.substring(6); - int distance = distanceStr.toInt(); - bool currentStatus = distance <= PRESENCE_DISTANCE; + if (currentStatus) { + lastMotionDetected = millis(); + } - if (currentStatus) { - lastMotionDetected = millis(); + //Serial.print("Radar: "); + //Serial.println(distance); + + if (currentStatus && state != 0) { + state = 0; + Serial.println("Motion detected, turning screen on."); + update_display_state(state); + //restApiAction(0); + } else if (!currentStatus && state == 1 && (millis() - lastMotionDetected >= POWER_DELAY)) { + state = 2; + Serial.printf("No motion detected for %d seconds, turning screen off.\n", POWER_DELAY); + update_display_state(state); + //restApiAction(2); + } else if (!currentStatus && state == 0 && (millis() - lastMotionDetected >= SLEEP_DELAY)) { + state = 1; + Serial.printf("No motion detected for %d seconds, turning screen screensaver on.\n", SLEEP_DELAY); + update_display_state(state); + //restApiAction(1); + } + } } - - if (currentStatus && state != 0) { - state = 0; - Serial.println("Motion detected, turning screen on."); - //rest_api_action(0); - } else if (!currentStatus && state == 1 && (millis() - lastMotionDetected >= POWER_DELAY)) { - state = 2; - Serial.printf("No motion detected for %d seconds, turning screen off.\n", POWER_DELAY); - //rest_api_action(2); - } else if (!currentStatus && state == 0 && (millis() - lastMotionDetected >= SLEEP_DELAY)) { - state = 1; - Serial.printf("No motion detected for %d seconds, turning screen screensaver on.\n", SLEEP_DELAY); - //rest_api_action(1); - } - } } - } } // action: 0 => Screen on, => 1 Screen off, => 2 Power off -void rest_api_action(int action) { +void restApiAction(int action) { WiFiClient client; HTTPClient http; int httpResponseCode; String url; - if(WiFi.status() != WL_CONNECTED){ - Serial.println("WiFi Disconnected. No request sent"); + if (WiFi.status() != WL_CONNECTED){ + Serial.println("WiFi Disconnected. No request sent"); } switch (action) { case 0: // Screen on - Serial.println("Sending Screen ON Request"); - url = BASE_URL_HA + "/webostv/command"; - http.begin(client, url); - http.addHeader("Authorization", "Bearer " + HA_TOKEN); - http.addHeader("Content-Type", "application/json"); - httpResponseCode = http.POST("{\"entity_id\":\"media_player.lg_webos_smart_tv\",\"command\":\"com.webos.service.tvpower/power/turnOnScreen\"}"); - break; + Serial.println("Sending Screen ON Request"); + url = BASE_URL_HA + "/webostv/command"; + http.begin(client, url); + http.addHeader("Authorization", "Bearer " + HA_TOKEN); + http.addHeader("Content-Type", "application/json"); + httpResponseCode = http.POST("{\"entity_id\":\"media_player.lg_webos_smart_tv\",\"command\":\"com.webos.service.tvpower/power/turnOnScreen\"}"); + break; case 1: // Screen off - Serial.println("Sending Screen OFF Request"); - url = BASE_URL_HA + "/webostv/command"; - http.begin(client, url); - http.addHeader("Authorization", "Bearer " + HA_TOKEN); - http.addHeader("Content-Type", "application/json"); - httpResponseCode = http.POST("{\"entity_id\":\"media_player.lg_webos_smart_tv\",\"command\":\"com.webos.service.tvpower/power/turnOffScreen\"}"); - break; + Serial.println("Sending Screen OFF Request"); + url = BASE_URL_HA + "/webostv/command"; + http.begin(client, url); + http.addHeader("Authorization", "Bearer " + HA_TOKEN); + http.addHeader("Content-Type", "application/json"); + httpResponseCode = http.POST("{\"entity_id\":\"media_player.lg_webos_smart_tv\",\"command\":\"com.webos.service.tvpower/power/turnOffScreen\"}"); + break; case 2: // Power off - Serial.println("Sending Power Off Request"); - url = BASE_URL_HA + "/webostv/command"; - http.begin(client, url); - http.addHeader("Authorization", "Bearer " + HA_TOKEN); - http.addHeader("Content-Type", "application/json"); - httpResponseCode = http.POST("{\"entity_id\":\"media_player.lg_webos_smart_tv\",\"command\":\"com.webos.service.tvpower/power/powerOffScreen\"}"); - break; + Serial.println("Sending Power Off Request"); + url = BASE_URL_HA + "/webostv/command"; + http.begin(client, url); + http.addHeader("Authorization", "Bearer " + HA_TOKEN); + http.addHeader("Content-Type", "application/json"); + httpResponseCode = http.POST("{\"entity_id\":\"media_player.lg_webos_smart_tv\",\"command\":\"com.webos.service.tvpower/power/powerOffScreen\"}"); + break; } Serial.print("HTTP Response code: "); diff --git a/ui-util.cpp b/ui-util.cpp index 2771a9b..973faaf 100644 --- a/ui-util.cpp +++ b/ui-util.cpp @@ -37,6 +37,7 @@ static lv_obj_t *img3; static lv_obj_t *img4; static lv_obj_t *img5; static lv_obj_t *img6; +static lv_obj_t *img7; // Transition animation static const void *trans_ainm_buf[] = { @@ -48,41 +49,56 @@ static void update_text_subscriber_cb_demo1(void *s, lv_msg_t *msg); void set_flip_time_anim(int hour, int minute, int second); void ui_begin() { - dis = lv_tileview_create(lv_scr_act()); - lv_obj_align(dis, LV_ALIGN_TOP_RIGHT, 0, 0); - lv_obj_set_size(dis, LV_PCT(100), LV_PCT(100)); - // lv_obj_remove_style(dis, 0, LV_PART_SCROLLBAR); - lv_obj_set_style_bg_color(dis, lv_color_black(), LV_PART_MAIN | LV_STATE_DEFAULT); + dis = lv_tileview_create(lv_scr_act()); + lv_obj_align(dis, LV_ALIGN_TOP_RIGHT, 0, 0); + lv_obj_set_size(dis, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_bg_color(dis, lv_color_black(), LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_t *tv1 = lv_tileview_add_tile(dis, 0, 0, LV_DIR_VER); - lv_obj_t *tv2 = lv_tileview_add_tile(dis, 0, 1, LV_DIR_VER); - lv_obj_t *tv3 = lv_tileview_add_tile(dis, 0, 2, LV_DIR_VER); - lv_obj_t *tv4 = lv_tileview_add_tile(dis, 0, 3, LV_DIR_VER); + lv_obj_t *tv1 = lv_tileview_add_tile(dis, 0, 0, LV_DIR_VER); - img1 = lv_gif_create(tv1); - img2 = lv_gif_create(tv1); - img3 = lv_gif_create(tv1); - img4 = lv_gif_create(tv1); - img5 = lv_gif_create(tv1); - img6 = lv_gif_create(tv1); + img1 = lv_gif_create(tv1); + img2 = lv_gif_create(tv1); + img3 = lv_gif_create(tv1); + img4 = lv_gif_create(tv1); + img5 = lv_gif_create(tv1); + img6 = lv_gif_create(tv1); - lv_gif_set_src(img1, set_anim_src(9)); - lv_gif_set_src(img2, set_anim_src(9)); - lv_gif_set_src(img3, set_anim_src(9)); - lv_gif_set_src(img4, set_anim_src(9)); - lv_gif_set_src(img5, set_anim_src(9)); - lv_gif_set_src(img6, set_anim_src(9)); + lv_gif_set_src(img1, set_anim_src(9)); + lv_gif_set_src(img2, set_anim_src(9)); + lv_gif_set_src(img3, set_anim_src(9)); + lv_gif_set_src(img4, set_anim_src(9)); + lv_gif_set_src(img5, set_anim_src(9)); + lv_gif_set_src(img6, set_anim_src(9)); - lv_obj_align(img1, LV_ALIGN_LEFT_MID, 20, 0); - lv_obj_align_to(img2, img1, LV_ALIGN_OUT_RIGHT_MID, 0, 0); - lv_obj_align(img3, LV_ALIGN_LEFT_MID, 225, 0); - lv_obj_align_to(img4, img3, LV_ALIGN_OUT_RIGHT_MID, 0, 0); - lv_obj_align(img5, LV_ALIGN_LEFT_MID, 430, 0); - lv_obj_align_to(img6, img5, LV_ALIGN_OUT_RIGHT_MID, 0, 0); + lv_obj_align(img1, LV_ALIGN_LEFT_MID, 20, 0); + lv_obj_align_to(img2, img1, LV_ALIGN_OUT_RIGHT_MID, 0, 0); + lv_obj_align(img3, LV_ALIGN_LEFT_MID, 225, 0); + lv_obj_align_to(img4, img3, LV_ALIGN_OUT_RIGHT_MID, 0, 0); + lv_obj_align(img5, LV_ALIGN_LEFT_MID, 430, 0); + lv_obj_align_to(img6, img5, LV_ALIGN_OUT_RIGHT_MID, 0, 0); - lv_msg_subsribe(MSG_NEW_HOUR, update_text_subscriber_cb_demo1, NULL); - lv_msg_subsribe(MSG_NEW_MIN, update_text_subscriber_cb_demo1, NULL); - lv_msg_subsribe(MSG_NEW_SEC, update_text_subscriber_cb_demo1, NULL); + lv_msg_subsribe(MSG_NEW_HOUR, update_text_subscriber_cb_demo1, NULL); + lv_msg_subsribe(MSG_NEW_MIN, update_text_subscriber_cb_demo1, NULL); + lv_msg_subsribe(MSG_NEW_SEC, update_text_subscriber_cb_demo1, NULL); +} + +void update_display_state(uint16_t state) { + lv_obj_t *state_symbol = lv_label_create(lv_scr_act()); + lv_obj_align(state_symbol, LV_ALIGN_TOP_LEFT, 20, 5); + lv_obj_set_width(state_symbol, LV_PCT(80)); + lv_label_set_long_mode(state_symbol, LV_LABEL_LONG_SCROLL); + lv_label_set_recolor(state_symbol, true); + + if (state == 0) { + lv_label_set_text(state_symbol, "#00FF00 " LV_SYMBOL_OK " ON #"); + } else if (state == 1) { + lv_label_set_text(state_symbol, "#FFA500 " LV_SYMBOL_PAUSE " IDLE #"); + } else { + lv_label_set_text(state_symbol, "#FFA500 " LV_SYMBOL_PAUSE " OFF #"); + } + + lv_delay_ms(5000); + lv_label_set_text(state_symbol, ""); } static void update_text_subscriber_cb_demo1(void *s, lv_msg_t *msg) { diff --git a/ui-util.h b/ui-util.h index d9c197e..2a29159 100644 --- a/ui-util.h +++ b/ui-util.h @@ -30,4 +30,5 @@ extern size_t lcd_PushColors_len; void ui_begin(); void lv_delay_ms(int x); -void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p); \ No newline at end of file +void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p); +void update_display_state(uint16_t state); \ No newline at end of file