Add touch calibration

This commit is contained in:
fvanroie 2020-02-01 23:56:16 +01:00
parent 642440414c
commit 47cbf007db
7 changed files with 165 additions and 14 deletions

View File

@ -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

View File

@ -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();

View File

@ -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>());

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);