From 47cbf007dba90cee6e4c96d242f40c20c6f986b2 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 1 Feb 2020 23:56:16 +0100 Subject: [PATCH] Add touch calibration --- src/hasp.cpp | 78 +++++++++++++++++++++++++++++++++++++++- src/hasp.h | 1 + src/hasp_config.cpp | 4 +-- src/hasp_config.h | 2 ++ src/hasp_dispatch.cpp | 10 +++--- src/hasp_gui.cpp | 83 +++++++++++++++++++++++++++++++++++++++---- src/hasp_gui.h | 1 + 7 files changed, 165 insertions(+), 14 deletions(-) diff --git a/src/hasp.cpp b/src/hasp.cpp index 557de503..a0351899 100644 --- a/src/hasp.cpp +++ b/src/hasp.cpp @@ -60,6 +60,7 @@ void hasp_background(uint16_t pageid, uint16_t imageid); * STATIC VARIABLES **********************/ static lv_style_t style_mbox_bg; /*Black bg. style with opacity*/ +static lv_obj_t * kb; #if LV_DEMO_WALLPAPER LV_IMG_DECLARE(img_bubble_pattern) @@ -663,6 +664,82 @@ void haspDisplayAP(const char * ssid, const char * pass) lv_label_set_text(password, txt.c_str()); } +static void kb_event_cb(lv_obj_t * event_kb, lv_event_t event) +{ + /* Just call the regular event handler */ + lv_kb_def_event_cb(event_kb, event); +} +static void ta_event_cb(lv_obj_t * ta, lv_event_t event) +{ + if(event == LV_EVENT_CLICKED) { + /* Focus on the clicked text area */ + if(kb != NULL) lv_kb_set_ta(kb, ta); + } + + else if(event == LV_EVENT_INSERT) { + const char * str = (const char *)lv_event_get_data(); + if(str[0] == '\n') { + printf("Ready\n"); + } else { + printf(lv_ta_get_text(ta)); + printf("\n"); + } + } +} + +void haspFirstSetup(void) +{ + /*Create styles for the keyboard*/ + static lv_style_t rel_style, pr_style; + + lv_style_copy(&rel_style, &lv_style_btn_rel); + rel_style.body.radius = 0; + rel_style.body.border.width = 1; + + lv_style_copy(&pr_style, &lv_style_btn_pr); + pr_style.body.radius = 0; + pr_style.body.border.width = 1; + + /* Create the password box */ + lv_obj_t * pwd_ta = lv_ta_create(lv_disp_get_layer_sys(NULL), NULL); + lv_ta_set_text(pwd_ta, ""); + lv_ta_set_pwd_mode(pwd_ta, true); + lv_ta_set_one_line(pwd_ta, true); + lv_obj_set_width(pwd_ta, LV_HOR_RES - 20); + lv_obj_set_pos(pwd_ta, 5, 20); + lv_obj_set_event_cb(pwd_ta, ta_event_cb); + lv_obj_align(pwd_ta, NULL, LV_ALIGN_OUT_TOP_MID, 0, 140); + + /* Create a label and position it above the text box */ + lv_obj_t * pwd_label = lv_label_create(lv_disp_get_layer_sys(NULL), NULL); + lv_label_set_text(pwd_label, "Password:"); + lv_obj_align(pwd_label, pwd_ta, LV_ALIGN_OUT_TOP_LEFT, 0, 0); + + /* Create the one-line mode text area */ + lv_obj_t * oneline_ta = lv_ta_create(lv_disp_get_layer_sys(NULL), pwd_ta); + lv_ta_set_pwd_mode(oneline_ta, false); + lv_ta_set_cursor_type(oneline_ta, LV_CURSOR_LINE | LV_CURSOR_HIDDEN); + lv_obj_align(oneline_ta, NULL, LV_ALIGN_OUT_TOP_MID, 0, 100); + + /* Create a label and position it above the text box */ + lv_obj_t * oneline_label = lv_label_create(lv_disp_get_layer_sys(NULL), NULL); + lv_label_set_text(oneline_label, "Ssid:"); + lv_obj_align(oneline_label, oneline_ta, LV_ALIGN_OUT_TOP_LEFT, 0, 0); + + /* Create a keyboard and make it fill the width of the above text areas */ + kb = lv_kb_create(lv_disp_get_layer_sys(NULL), NULL); + // lv_obj_set_pos(kb, 5, 90); + lv_obj_set_event_cb(kb, + kb_event_cb); /* Setting a custom event handler stops the keyboard from closing automatically */ + // lv_obj_set_size(kb, LV_HOR_RES, 140); + lv_kb_set_style(kb, LV_KB_STYLE_BG, &lv_style_transp_tight); + lv_kb_set_style(kb, LV_KB_STYLE_BTN_REL, &rel_style); + lv_kb_set_style(kb, LV_KB_STYLE_BTN_PR, &pr_style); + + lv_kb_set_ta(kb, pwd_ta); /* Focus it on one of the text areas to start */ + lv_kb_set_cursor_manage(kb, true); /* Automatically show/hide cursors on text areas */ +} + /** * Create a demo application */ @@ -1038,7 +1115,6 @@ static void roller_event_handler(lv_obj_t * obj, lv_event_t event) } /////////////////////////////////////////////////////////////////////////////////////////////////////////// - void haspReboot(bool write_config) { mqttStop(); // Stop the MQTT Client first diff --git a/src/hasp.h b/src/hasp.h index ae8f11c5..282f5fcf 100644 --- a/src/hasp.h +++ b/src/hasp.h @@ -70,6 +70,7 @@ typedef enum lv_hasp_obj_type_t { */ void haspSetup(JsonObject settings); void haspLoop(void); +void haspFirstSetup(void); void haspSetPage(uint16_t id); uint16_t haspGetPage(); diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index 8dd2a0bd..61445fc8 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -79,14 +79,14 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false) void configWriteConfig() { /* Read Config File */ - DynamicJsonDocument settings(1024); + DynamicJsonDocument settings(2 * 1024); debugPrintln(String(F("CONF: Config LOADING first ")) + String(FPSTR(HASP_CONFIG_FILE))); configGetConfig(settings, false); debugPrintln(String(F("CONF: Config LOADED first ")) + String(FPSTR(HASP_CONFIG_FILE))); bool changed = true; // changed |= debugGetConfig(settings[F("debug")].to()); - // changed |= guiGetConfig(settings[F("gui")].to()); + changed |= guiGetConfig(settings[F("gui")].to()); changed |= haspGetConfig(settings[F("hasp")].to()); changed |= httpGetConfig(settings[F("http")].to()); // changed |= mdnsGetConfig(settings[F("mdns")].to()); diff --git a/src/hasp_config.h b/src/hasp_config.h index f957645d..0cf1fc33 100644 --- a/src/hasp_config.h +++ b/src/hasp_config.h @@ -17,6 +17,8 @@ const char F_CONFIG_PASS[] PROGMEM = "pass"; const char F_CONFIG_SSID[] PROGMEM = "ssid"; const char F_CONFIG_GROUP[] PROGMEM = "group"; const char F_GUI_TICKPERIOD[] PROGMEM = "tickperiod"; +const char F_GUI_IDLEPERIOD[] PROGMEM = "idle"; +const char F_GUI_CALIBRATION[] PROGMEM = "calibration"; void configSetup(JsonDocument & settings); void configLoop(void); diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp index 6770ab43..03dcd0b4 100644 --- a/src/hasp_dispatch.cpp +++ b/src/hasp_dispatch.cpp @@ -52,18 +52,18 @@ void dispatchCommand(String cmnd) { debugPrintln("CMND: " + cmnd); - if(cmnd == "calibrate") { + if(cmnd == F("calibrate")) { guiCalibrate(); return; } - if(cmnd == "restart") { - haspReset(true); + if(cmnd == F("reboot") || cmnd == F("restart")) { + haspReboot(true); return; } - if(cmnd == "" || cmnd == "statusupdate") { - haspReset(true); + if(cmnd == "" || cmnd == F("statusupdate")) { + mqttStatusUpdate(); return; } diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 3dbf2c92..90abdd1c 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -16,15 +16,17 @@ #include "hasp_config.h" #include "hasp_dispatch.h" #include "hasp_gui.h" +#include "hasp.h" #define LVGL_TICK_PERIOD 30 // 30 uint16_t guiSleepTime = 150; // 0.1 second resolution bool guiSleeping = false; uint8_t guiTickPeriod = 50; -Ticker tick; /* timer for interrupt handler */ -TFT_eSPI tft = TFT_eSPI(); /* TFT instance */ -uint16_t calData[5] = {0, 0, 0, 0, 0}; +Ticker tick; /* timer for interrupt handler */ +TFT_eSPI tft = TFT_eSPI(); /* TFT instance */ +uint16_t calData[5] = {0, 65535, 0, 65535, 0}; +bool guiAutoCalibrate = true; bool IRAM_ATTR guiCheckSleep() { @@ -84,6 +86,13 @@ bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data) return false; } +void guiFirstCalibration() +{ + dispatchCommand(F("calibrate")); + guiAutoCalibrate = false; + haspFirstSetup(); +} + bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) { uint16_t touchX, touchY; @@ -91,6 +100,11 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) bool touched = tft.getTouch(&touchX, &touchY, 600); if(!touched) return false; + if(guiAutoCalibrate) { + guiFirstCalibration(); + return false; + } + bool shouldSleep = guiCheckSleep(); if(!shouldSleep && guiSleeping) { dispatchIdle(F("OFF")); @@ -124,13 +138,14 @@ void guiCalibrate() { tft.fillScreen(TFT_BLACK); tft.setCursor(20, 0); - // tft.setTextFont(2); + tft.setTextFont(1); tft.setTextSize(1); tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.println(PSTR("Touch corners as indicated")); tft.setTextFont(1); + delay(500); tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15); for(uint8_t i = 0; i < 5; i++) { @@ -139,6 +154,7 @@ void guiCalibrate() } tft.setTouch(calData); + delay(500); lv_obj_invalidate(lv_disp_get_layer_sys(NULL)); } @@ -147,6 +163,7 @@ void guiSetup(TFT_eSPI & screen, JsonObject settings) size_t buffer_size; tft = screen; + guiSetConfig(settings); tft.setTouch(calData); lv_init(); @@ -252,14 +269,68 @@ void IRAM_ATTR guiLoop() void guiStop() {} +//////////////////////////////////////////////////////////////////////////////////////////////////// bool guiGetConfig(const JsonObject & settings) { - if(!settings.isNull() && settings[F_GUI_TICKPERIOD] == guiTickPeriod) return false; + settings[FPSTR(F_GUI_TICKPERIOD)] = guiTickPeriod; + settings[FPSTR(F_GUI_IDLEPERIOD)] = guiSleepTime; - settings[F_GUI_TICKPERIOD] = guiTickPeriod; + JsonArray array = settings[FPSTR(F_GUI_CALIBRATION)].to(); + for(int i = 0; i < 5; i++) { + array.add(calData[i]); + } size_t size = serializeJson(settings, Serial); Serial.println(); return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool guiSetConfig(const JsonObject & settings) +{ + bool changed = false; + + if(!settings[FPSTR(F_GUI_TICKPERIOD)].isNull()) { + if(guiTickPeriod != settings[FPSTR(F_GUI_TICKPERIOD)].as()) { + debugPrintln(F("guiTickPeriod set")); + } + changed |= guiTickPeriod != settings[FPSTR(F_GUI_TICKPERIOD)].as(); + + guiTickPeriod = settings[FPSTR(F_GUI_TICKPERIOD)].as(); + } + + if(!settings[FPSTR(F_GUI_IDLEPERIOD)].isNull()) { + if(guiSleepTime != settings[FPSTR(F_GUI_IDLEPERIOD)].as()) { + debugPrintln(F("guiSleepTime set")); + } + changed |= guiSleepTime != settings[FPSTR(F_GUI_IDLEPERIOD)].as(); + + guiSleepTime = settings[FPSTR(F_GUI_IDLEPERIOD)].as(); + } + + if(!settings[FPSTR(F_GUI_CALIBRATION)].isNull()) { + bool status = false; + int i = 0; + + JsonArray array = settings[FPSTR(F_GUI_CALIBRATION)].as(); + for(JsonVariant v : array) { + if(calData[i] != v.as()) status = true; + calData[i] = v.as(); + i++; + } + + if(status) { + debugPrintln(F("calData set")); + guiAutoCalibrate = false; + } + + changed |= status; + } + + size_t size = serializeJson(settings, Serial); + Serial.println(); + + return changed; } \ No newline at end of file diff --git a/src/hasp_gui.h b/src/hasp_gui.h index a3f482d2..0261f804 100644 --- a/src/hasp_gui.h +++ b/src/hasp_gui.h @@ -13,6 +13,7 @@ void guiStop(void); void guiCalibrate(); bool guiGetConfig(const JsonObject & settings); +bool guiSetConfig(const JsonObject & settings); // lv_res_t guiChangeTheme(uint8_t themeid, uint16_t hue, String font, uint8_t fontsize);