|
@@ -25,6 +25,7 @@
|
25
|
25
|
#include "config.h"
|
26
|
26
|
#include "DebugLog.h"
|
27
|
27
|
#include "mqtt.h"
|
|
28
|
+#include "memory.h"
|
28
|
29
|
#include "ui.h"
|
29
|
30
|
|
30
|
31
|
#ifdef FEATURE_UI
|
|
@@ -46,12 +47,6 @@
|
46
|
47
|
#define LDR_PIN 34
|
47
|
48
|
#define BTN_PIN 0
|
48
|
49
|
|
49
|
|
-#define TOUCH_LEFT 180
|
50
|
|
-#define TOUCH_RIGHT 3750
|
51
|
|
-
|
52
|
|
-#define TOUCH_TOP 230
|
53
|
|
-#define TOUCH_BOTTOM 3800
|
54
|
|
-
|
55
|
50
|
#define BTN_W 120
|
56
|
51
|
#define BTN_H 60
|
57
|
52
|
#define BTN_GAP 20
|
|
@@ -66,25 +61,34 @@
|
66
|
61
|
#define LDR_CHECK_MS 100
|
67
|
62
|
#define LDR_DARK_VALUE 1200
|
68
|
63
|
#define LDR_BRIGHT_VALUE 0
|
69
|
|
-#define LDR_LOWPASS_FACT 0.1f
|
|
64
|
+#define LDR_LOWPASS_FACT 0.025f
|
70
|
65
|
|
71
|
66
|
#define STANDBY_BRIGHTNESS 10
|
72
|
67
|
#define LCD_MIN_BRIGHTNESS (STANDBY_BRIGHTNESS * 2)
|
73
|
68
|
#define LCD_MAX_BRIGHTNESS 255
|
74
|
69
|
|
75
|
70
|
#define MIN_TOUCH_DELAY_MS 200
|
76
|
|
-#define TOUCH_PRESSURE_MIN 200
|
|
71
|
+#define TOUCH_PRESSURE_MIN 1000
|
77
|
72
|
#define FULL_BRIGHT_MS (1000 * 30)
|
78
|
73
|
#define NO_BRIGHT_MS (1000 * 2)
|
79
|
74
|
|
80
|
75
|
#define NTP_SERVER "pool.ntp.org"
|
81
|
76
|
#define STANDBY_REDRAW_MS 500
|
82
|
77
|
|
|
78
|
+#define CALIB_1_X 42
|
|
79
|
+#define CALIB_1_Y 42
|
|
80
|
+#define CALIB_2_X LCD_WIDTH - 1 - CALIB_1_X
|
|
81
|
+#define CALIB_2_Y LCD_HEIGHT - 1 - CALIB_1_Y
|
|
82
|
+
|
83
|
83
|
// TODO auto-detect?!
|
84
|
84
|
#warning hard-coded timezone and daylight savings offset
|
85
|
85
|
#define gmtOffset_sec (60 * 60)
|
86
|
86
|
#define daylightOffset_sec (60 * 60)
|
87
|
87
|
|
|
88
|
+#if (LCD_MIN_BRIGHTNESS <= STANDBY_BRIGHTNESS)
|
|
89
|
+#error STANDBY_BRIGHTNESS needs to be bigger than LCD_MIN_BRIGHTNESS
|
|
90
|
+#endif
|
|
91
|
+
|
88
|
92
|
static SPIClass mySpi = SPIClass(HSPI);
|
89
|
93
|
static XPT2046_Touchscreen ts(XPT2046_CS, XPT2046_IRQ);
|
90
|
94
|
static TFT_eSPI tft = TFT_eSPI();
|
|
@@ -110,12 +114,6 @@ static int curr_brightness = LCD_MAX_BRIGHTNESS;
|
110
|
114
|
static int set_max_brightness = LCD_MAX_BRIGHTNESS;
|
111
|
115
|
static unsigned long last_standby_draw = 0;
|
112
|
116
|
|
113
|
|
-static TS_Point touchToScreen(TS_Point p) {
|
114
|
|
- p.x = map(p.x, TOUCH_LEFT, TOUCH_RIGHT, 0, LCD_WIDTH);
|
115
|
|
- p.y = map(p.y, TOUCH_TOP, TOUCH_BOTTOM, 0, LCD_HEIGHT);
|
116
|
|
- return p;
|
117
|
|
-}
|
118
|
|
-
|
119
|
117
|
static void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
|
120
|
118
|
uint32_t duty = (4095 / valueMax) * min(value, valueMax);
|
121
|
119
|
ledcWrite(channel, duty);
|
|
@@ -352,6 +350,76 @@ static void ui_draw_menu(void) {
|
352
|
350
|
draw_button("Next...", BTNS_OFF_X + BTN_W / 2 + BTN_W + BTN_GAP, BTNS_OFF_Y + BTN_H / 2 + (BTN_H + BTN_GAP) * 2, TFT_CYAN);
|
353
|
351
|
}
|
354
|
352
|
|
|
353
|
+static void ui_draw_reticule(int x, int y, int l) {
|
|
354
|
+ tft.drawFastHLine(x - l / 2, y, l, TFT_RED);
|
|
355
|
+ tft.drawFastVLine(x, y - l / 2, l, TFT_RED);
|
|
356
|
+ tft.drawCircle(x, y, l / 4, TFT_GREEN);
|
|
357
|
+ tft.drawPixel(x, y, TFT_WHITE);
|
|
358
|
+}
|
|
359
|
+
|
|
360
|
+static TS_Point touchToScreen(TS_Point p) {
|
|
361
|
+ p.x = map(p.x, config.touch_calibrate_left, config.touch_calibrate_right, CALIB_1_X, CALIB_2_X);
|
|
362
|
+ p.y = map(p.y, config.touch_calibrate_top, config.touch_calibrate_bottom, CALIB_1_Y, CALIB_2_Y);
|
|
363
|
+ if (p.x < 0) { p.x = 0; }
|
|
364
|
+ if (p.x >= LCD_WIDTH) { p.x = LCD_WIDTH - 1; }
|
|
365
|
+ if (p.y < 0) { p.y = 0; }
|
|
366
|
+ if (p.y >= LCD_HEIGHT) { p.y = LCD_HEIGHT - 1; }
|
|
367
|
+ return p;
|
|
368
|
+}
|
|
369
|
+
|
|
370
|
+static void ui_calibrate_touchscreen(void) {
|
|
371
|
+ for (int step = 0; step < 3; step++) {
|
|
372
|
+ tft.fillScreen(TFT_BLACK);
|
|
373
|
+ tft.setTextDatum(MC_DATUM); // middle center
|
|
374
|
+ tft.drawString("Calibrate Touchscreen", LCD_WIDTH / 2, LCD_HEIGHT / 2, 2);
|
|
375
|
+
|
|
376
|
+ if (step == 0) {
|
|
377
|
+ ui_draw_reticule(CALIB_1_X, CALIB_1_Y, 20);
|
|
378
|
+ } else if (step == 1) {
|
|
379
|
+ ui_draw_reticule(CALIB_2_X, CALIB_2_Y, 20);
|
|
380
|
+ } else {
|
|
381
|
+ tft.drawString("Press button to save", LCD_WIDTH / 2, LCD_HEIGHT / 2 + 20, 2);
|
|
382
|
+ tft.drawString("Power off to re-do", LCD_WIDTH / 2, LCD_HEIGHT / 2 + 40, 2);
|
|
383
|
+ }
|
|
384
|
+
|
|
385
|
+ if (step < 2) {
|
|
386
|
+ bool touched = false;
|
|
387
|
+ while (!touched) {
|
|
388
|
+ touched = ts.tirqTouched() && ts.touched();
|
|
389
|
+ TS_Point p = ts.getPoint();
|
|
390
|
+
|
|
391
|
+ // minimum pressure
|
|
392
|
+ if (p.z < TOUCH_PRESSURE_MIN) {
|
|
393
|
+ touched = false;
|
|
394
|
+ }
|
|
395
|
+ }
|
|
396
|
+ } else {
|
|
397
|
+ while (digitalRead(BTN_PIN)) {
|
|
398
|
+ bool touched = ts.tirqTouched() && ts.touched();
|
|
399
|
+ if (touched) {
|
|
400
|
+ TS_Point p = touchToScreen(ts.getPoint());
|
|
401
|
+ tft.drawPixel(p.x, p.y, TFT_WHITE);
|
|
402
|
+ }
|
|
403
|
+ }
|
|
404
|
+ mem_write(config);
|
|
405
|
+ return;
|
|
406
|
+ }
|
|
407
|
+
|
|
408
|
+ TS_Point p = ts.getPoint();
|
|
409
|
+ if (step == 0) {
|
|
410
|
+ config.touch_calibrate_left = p.x;
|
|
411
|
+ config.touch_calibrate_top = p.y;
|
|
412
|
+ } else if (step == 1) {
|
|
413
|
+ config.touch_calibrate_right = p.x;
|
|
414
|
+ config.touch_calibrate_bottom = p.y;
|
|
415
|
+ }
|
|
416
|
+
|
|
417
|
+ // TODO ugly, wait for proper touch release?
|
|
418
|
+ tft.fillScreen(TFT_BLACK);
|
|
419
|
+ delay(500);
|
|
420
|
+ }
|
|
421
|
+}
|
|
422
|
+
|
355
|
423
|
void ui_progress(enum ui_state state) {
|
356
|
424
|
int x = LCD_WIDTH / 2;
|
357
|
425
|
int y = LCD_HEIGHT / 2;
|
|
@@ -365,6 +433,18 @@ void ui_progress(enum ui_state state) {
|
365
|
433
|
tft.drawString("xythobuz.de", x, y, fontSize);
|
366
|
434
|
} break;
|
367
|
435
|
|
|
436
|
+ case UI_MEMORY_READY: {
|
|
437
|
+ if ((!digitalRead(BTN_PIN)) // button held at boot
|
|
438
|
+ // ... or no calibration data in memory
|
|
439
|
+ || ((config.touch_calibrate_left == 0)
|
|
440
|
+ && (config.touch_calibrate_right == 0)
|
|
441
|
+ && (config.touch_calibrate_top == 0)
|
|
442
|
+ && (config.touch_calibrate_bottom == 0))
|
|
443
|
+ ) {
|
|
444
|
+ ui_calibrate_touchscreen();
|
|
445
|
+ }
|
|
446
|
+ } break;
|
|
447
|
+
|
368
|
448
|
case UI_WIFI_CONNECT: {
|
369
|
449
|
tft.setTextDatum(MC_DATUM); // middle center
|
370
|
450
|
tft.drawString("Connecting to '" WIFI_SSID "'", x, y + 32, fontSize);
|