#include "lvgl.h" #include "pins_config.h" #include "AXS15231B.h" #include "ui-util.h" #include "WiFi.h" #include "sntp.h" #include "time.h" #include #include #include #include "freertos/semphr.h" #include "DFRobot_mmWave_Radar.h" #include #include "Thread.h" #include "ThreadController.h" // Serial #define BAUD 115200 // Sensor pins #define RX2_PIN TOUCH_IICSCL #define TX2_PIN TOUCH_IICSDA // Sensor configuration #define PRESENCE_DISTANCE 2 // in m #define DELAY_STATUS_CHECK 1000 // delay (in ms) between two checks of the presence #define SLEEP_DELAY 30000 // delay (in ms) until sleep mode #define POWER_DELAY 100000 // delay (in ms) until turning off the screen HardwareSerial mySerial(1); DFRobot_mmWave_Radar sensor(&mySerial); SemaphoreHandle_t xSemaphore = NULL; PowersSY6970 PMU; // Sensor variables uint16_t state = 1; // 0 = presence detected, 1 = no presence detected for the past SLEEP_DELAY ms, 2 = no presence detected for the past POWER_DELAY ms unsigned long lastMotionDetected = 0; // time when the last motion was detected // Time variables static uint32_t last_tick; struct tm timeinfo; uint32_t cycleInterval = 0; // Display variables static lv_disp_draw_buf_t draw_buf; static lv_color_t *buf; static lv_color_t *buf1; // REST API Home assistant request static String BASE_URL_HA = "http://192.168.1.2:8123/api/services"; static String HA_TOKEN = "abc"; ThreadController controller; Thread thread1 = Thread(); Thread thread2 = Thread(); void setup() { xSemaphore = xSemaphoreCreateBinary(); xSemaphoreGive(xSemaphore); initSerial(); initializeWifi(); initializeTime(); initializeUI(); initializeThreading(); } void loop() { controller.run(); 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; 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(); lv_msg_send(MSG_NEW_VOLT, ""); } } } 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."); 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); // Start HMMD Sensor mySerial.begin(BAUD, SERIAL_8N1, RX2_PIN, TX2_PIN); //RX,TX Serial.println("Sensor Initialized on RX:" + String(RX2_PIN) + ", TX:" + String(TX2_PIN)); sensor.factoryReset(); //Restore to the factory settings sensor.DetRangeCfg(0, PRESENCE_DISTANCE); //The detection range is as far as 9m sensor.OutputLatency(0, 0); } void initializeWifi() { WiFi.persistent(true); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.println("Connecting to WiFi..."); int connectTime = millis(); while(WiFi.status() != WL_CONNECTED) { delay(200); Serial.print("."); if (millis() - connectTime >= WIFI_CONNECT_WAIT_MAX) { ESP.restart(); } } Serial.println(); Serial.println("Connection succesful!"); Serial.printf("SSID: %s\r\n", WiFi.SSID().c_str()); String IP = WiFi.localIP().toString(); Serial.printf("IP address: %s\r\n", IP.c_str()); } void initializeTime() { 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); } } 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); 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"); } void initializeThreading() { thread1.onRun(printLocalTime); thread1.setInterval(100); thread2.onRun(readAndProcessSensorLines); thread2.setInterval(1000); controller.add(&thread1); controller.add(&thread2); } 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); } last_tick = millis(); } } void readAndProcessSensorLines() { int currentStatus = sensor.readPresenceDetection(); if (currentStatus == 1) { lastMotionDetected = millis(); } //Serial.printf("Sensor: %d\n", currentStatus); if (currentStatus == 1 && state != 0) { state = 0; Serial.println("Motion detected, turning screen on."); lv_msg_send(MSG_NEW_VOLT, "0"); //restApiAction(0); } else if (currentStatus == 0 && state == 1 && (millis() - lastMotionDetected >= POWER_DELAY)) { state = 2; Serial.printf("No motion detected for %d ms, turning screen off.\n", POWER_DELAY); lv_msg_send(MSG_NEW_VOLT, "2"); //restApiAction(2); } else if (currentStatus == 0 && state == 0 && (millis() - lastMotionDetected >= SLEEP_DELAY)) { state = 1; Serial.printf("No motion detected for %d ms, turning screen screensaver on.\n", SLEEP_DELAY); lv_msg_send(MSG_NEW_VOLT, "1"); //restApiAction(1); } } // action: 0 => Screen on, => 1 Screen off, => 2 Power off void restApiAction(int action) { WiFiClient client; HTTPClient http; int httpResponseCode; String url; 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; 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; 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.print("HTTP Response code: "); Serial.println(httpResponseCode); http.end(); }