mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-24 11:46:34 +00:00
Add touch calibration
This commit is contained in:
parent
642440414c
commit
47cbf007db
78
src/hasp.cpp
78
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
|
||||
|
@ -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();
|
||||
|
@ -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<JsonObject>());
|
||||
// changed |= guiGetConfig(settings[F("gui")].to<JsonObject>());
|
||||
changed |= guiGetConfig(settings[F("gui")].to<JsonObject>());
|
||||
changed |= haspGetConfig(settings[F("hasp")].to<JsonObject>());
|
||||
changed |= httpGetConfig(settings[F("http")].to<JsonObject>());
|
||||
// changed |= mdnsGetConfig(settings[F("mdns")].to<JsonObject>());
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<JsonArray>();
|
||||
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<uint8_t>()) {
|
||||
debugPrintln(F("guiTickPeriod set"));
|
||||
}
|
||||
changed |= guiTickPeriod != settings[FPSTR(F_GUI_TICKPERIOD)].as<uint8_t>();
|
||||
|
||||
guiTickPeriod = settings[FPSTR(F_GUI_TICKPERIOD)].as<uint8_t>();
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(F_GUI_IDLEPERIOD)].isNull()) {
|
||||
if(guiSleepTime != settings[FPSTR(F_GUI_IDLEPERIOD)].as<uint8_t>()) {
|
||||
debugPrintln(F("guiSleepTime set"));
|
||||
}
|
||||
changed |= guiSleepTime != settings[FPSTR(F_GUI_IDLEPERIOD)].as<uint8_t>();
|
||||
|
||||
guiSleepTime = settings[FPSTR(F_GUI_IDLEPERIOD)].as<uint8_t>();
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(F_GUI_CALIBRATION)].isNull()) {
|
||||
bool status = false;
|
||||
int i = 0;
|
||||
|
||||
JsonArray array = settings[FPSTR(F_GUI_CALIBRATION)].as<JsonArray>();
|
||||
for(JsonVariant v : array) {
|
||||
if(calData[i] != v.as<uint16_t>()) status = true;
|
||||
calData[i] = v.as<uint16_t>();
|
||||
i++;
|
||||
}
|
||||
|
||||
if(status) {
|
||||
debugPrintln(F("calData set"));
|
||||
guiAutoCalibrate = false;
|
||||
}
|
||||
|
||||
changed |= status;
|
||||
}
|
||||
|
||||
size_t size = serializeJson(settings, Serial);
|
||||
Serial.println();
|
||||
|
||||
return changed;
|
||||
}
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user