Browse Source

add touchscreen calibration ui and eeprom

Thomas Buck 5 months ago
parent
commit
008da59e34
10 changed files with 133 additions and 26 deletions
  1. 14
    0
      include/memory.h
  2. 1
    0
      include/ui.h
  3. 1
    0
      src/DebugLog.cpp
  4. 2
    0
      src/SimpleInflux.cpp
  5. 9
    8
      src/SimpleUpdater.cpp
  6. 4
    0
      src/main.cpp
  7. 1
    0
      src/memory.cpp
  8. 5
    3
      src/moisture.cpp
  9. 2
    1
      src/relais.cpp
  10. 94
    14
      src/ui.cpp

+ 14
- 0
include/memory.h View File

19
     double bme1_temp_off;
19
     double bme1_temp_off;
20
     double bme2_temp_off;
20
     double bme2_temp_off;
21
 
21
 
22
+#ifdef FEATURE_UI
23
+    int touch_calibrate_left;
24
+    int touch_calibrate_right;
25
+    int touch_calibrate_top;
26
+    int touch_calibrate_bottom;
27
+#endif // FEATURE_UI
28
+
22
     ConfigMemory() {
29
     ConfigMemory() {
23
         sht_temp_off = 0.0;
30
         sht_temp_off = 0.0;
24
         bme1_temp_off = 0.0;
31
         bme1_temp_off = 0.0;
25
         bme2_temp_off = 0.0;
32
         bme2_temp_off = 0.0;
33
+
34
+#ifdef FEATURE_UI
35
+        touch_calibrate_left = 0;
36
+        touch_calibrate_right = 0;
37
+        touch_calibrate_top = 0;
38
+        touch_calibrate_bottom = 0;
39
+#endif // FEATURE_UI
26
     }
40
     }
27
 };
41
 };
28
 
42
 

+ 1
- 0
include/ui.h View File

38
 
38
 
39
 enum ui_state {
39
 enum ui_state {
40
     UI_INIT = 0,
40
     UI_INIT = 0,
41
+    UI_MEMORY_READY,
41
     UI_WIFI_CONNECT,
42
     UI_WIFI_CONNECT,
42
     UI_WIFI_CONNECTING,
43
     UI_WIFI_CONNECTING,
43
     UI_WIFI_CONNECTED,
44
     UI_WIFI_CONNECTED,

+ 1
- 0
src/DebugLog.cpp View File

13
 
13
 
14
 #include <Arduino.h>
14
 #include <Arduino.h>
15
 
15
 
16
+#include "config.h"
16
 #include "servers.h"
17
 #include "servers.h"
17
 #include "DebugLog.h"
18
 #include "DebugLog.h"
18
 
19
 

+ 2
- 0
src/SimpleInflux.cpp View File

12
  */
12
  */
13
 
13
 
14
 #include <Arduino.h>
14
 #include <Arduino.h>
15
+
16
+#include "config.h"
15
 #include "DebugLog.h"
17
 #include "DebugLog.h"
16
 #include "SimpleInflux.h"
18
 #include "SimpleInflux.h"
17
 
19
 

+ 9
- 8
src/SimpleUpdater.cpp View File

17
 #include <Update.h>
17
 #include <Update.h>
18
 #endif
18
 #endif
19
 
19
 
20
+#include "config.h"
20
 #include "SimpleUpdater.h"
21
 #include "SimpleUpdater.h"
21
 
22
 
22
 #if defined(ARDUINO_ARCH_ESP32)
23
 #if defined(ARDUINO_ARCH_ESP32)
87
         "</script>\n"
88
         "</script>\n"
88
         "</body></html>"
89
         "</body></html>"
89
     );
90
     );
90
-    
91
+
91
     server->send(200, "text/html", uploadPage);
92
     server->send(200, "text/html", uploadPage);
92
 }
93
 }
93
 
94
 
128
     if (_server == NULL) {
129
     if (_server == NULL) {
129
         return;
130
         return;
130
     }
131
     }
131
-    
132
+
132
     server = _server;
133
     server = _server;
133
-    
134
+
134
 #if defined(ARDUINO_ARCH_ESP8266)
135
 #if defined(ARDUINO_ARCH_ESP8266)
135
-    
136
+
136
     updateServer.setup(server);
137
     updateServer.setup(server);
137
-    
138
+
138
 #elif defined(ARDUINO_ARCH_ESP32)
139
 #elif defined(ARDUINO_ARCH_ESP32)
139
-    
140
+
140
     server->on(uri.c_str(), HTTP_POST, [this]() {
141
     server->on(uri.c_str(), HTTP_POST, [this]() {
141
         postResult();
142
         postResult();
142
     }, [this]() {
143
     }, [this]() {
143
         postUpload();
144
         postUpload();
144
     });
145
     });
145
-    
146
+
146
     server->on(uri.c_str(), HTTP_GET, [this]() {
147
     server->on(uri.c_str(), HTTP_GET, [this]() {
147
         get();
148
         get();
148
     });
149
     });
149
-    
150
+
150
 #endif
151
 #endif
151
 }
152
 }
152
 
153
 

+ 4
- 0
src/main.cpp View File

74
 
74
 
75
     config = mem_read();
75
     config = mem_read();
76
 
76
 
77
+#ifdef FEATURE_UI
78
+    ui_progress(UI_MEMORY_READY);
79
+#endif // FEATURE_UI
80
+
77
 #ifdef FEATURE_RELAIS
81
 #ifdef FEATURE_RELAIS
78
     debug.println(F("Relais"));
82
     debug.println(F("Relais"));
79
     relais_init();
83
     relais_init();

+ 1
- 0
src/memory.cpp View File

14
 #include <Arduino.h>
14
 #include <Arduino.h>
15
 #include <EEPROM.h>
15
 #include <EEPROM.h>
16
 
16
 
17
+#include "config.h"
17
 #include "DebugLog.h"
18
 #include "DebugLog.h"
18
 #include "memory.h"
19
 #include "memory.h"
19
 
20
 

+ 5
- 3
src/moisture.cpp View File

12
  */
12
  */
13
 
13
 
14
 #include <Arduino.h>
14
 #include <Arduino.h>
15
+
16
+#include "config.h"
15
 #include "moisture.h"
17
 #include "moisture.h"
16
 
18
 
17
 #if defined(MOISTURE_ADC_ESP32)
19
 #if defined(MOISTURE_ADC_ESP32)
32
 
34
 
33
 static int adc_read_oversampled(adc1_channel_t pin) {
35
 static int adc_read_oversampled(adc1_channel_t pin) {
34
     uint32_t sample_sum = 0;
36
     uint32_t sample_sum = 0;
35
-    
37
+
36
     for (int i = 0; i < ADC_OVERSAMPLE; i++) {
38
     for (int i = 0; i < ADC_OVERSAMPLE; i++) {
37
         sample_sum += adc1_get_raw(pin);
39
         sample_sum += adc1_get_raw(pin);
38
     }
40
     }
39
-    
41
+
40
     return sample_sum / ADC_OVERSAMPLE;
42
     return sample_sum / ADC_OVERSAMPLE;
41
 }
43
 }
42
 
44
 
55
     if ((sensor < 0) || (sensor > SENSOR_COUNT)) {
57
     if ((sensor < 0) || (sensor > SENSOR_COUNT)) {
56
         return -1;
58
         return -1;
57
     }
59
     }
58
-    
60
+
59
     return adc_read_oversampled(sensor_pin[sensor]);
61
     return adc_read_oversampled(sensor_pin[sensor]);
60
 }
62
 }
61
 
63
 

+ 2
- 1
src/relais.cpp View File

12
  */
12
  */
13
 
13
 
14
 #include <Arduino.h>
14
 #include <Arduino.h>
15
-#include "relais.h"
15
+
16
 #include "config.h"
16
 #include "config.h"
17
+#include "relais.h"
17
 
18
 
18
 #if defined(RELAIS_SERIAL)
19
 #if defined(RELAIS_SERIAL)
19
 
20
 

+ 94
- 14
src/ui.cpp View File

25
 #include "config.h"
25
 #include "config.h"
26
 #include "DebugLog.h"
26
 #include "DebugLog.h"
27
 #include "mqtt.h"
27
 #include "mqtt.h"
28
+#include "memory.h"
28
 #include "ui.h"
29
 #include "ui.h"
29
 
30
 
30
 #ifdef FEATURE_UI
31
 #ifdef FEATURE_UI
46
 #define LDR_PIN 34
47
 #define LDR_PIN 34
47
 #define BTN_PIN 0
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
 #define BTN_W 120
50
 #define BTN_W 120
56
 #define BTN_H 60
51
 #define BTN_H 60
57
 #define BTN_GAP 20
52
 #define BTN_GAP 20
66
 #define LDR_CHECK_MS 100
61
 #define LDR_CHECK_MS 100
67
 #define LDR_DARK_VALUE 1200
62
 #define LDR_DARK_VALUE 1200
68
 #define LDR_BRIGHT_VALUE 0
63
 #define LDR_BRIGHT_VALUE 0
69
-#define LDR_LOWPASS_FACT 0.1f
64
+#define LDR_LOWPASS_FACT 0.025f
70
 
65
 
71
 #define STANDBY_BRIGHTNESS 10
66
 #define STANDBY_BRIGHTNESS 10
72
 #define LCD_MIN_BRIGHTNESS (STANDBY_BRIGHTNESS * 2)
67
 #define LCD_MIN_BRIGHTNESS (STANDBY_BRIGHTNESS * 2)
73
 #define LCD_MAX_BRIGHTNESS 255
68
 #define LCD_MAX_BRIGHTNESS 255
74
 
69
 
75
 #define MIN_TOUCH_DELAY_MS 200
70
 #define MIN_TOUCH_DELAY_MS 200
76
-#define TOUCH_PRESSURE_MIN 200
71
+#define TOUCH_PRESSURE_MIN 1000
77
 #define FULL_BRIGHT_MS (1000 * 30)
72
 #define FULL_BRIGHT_MS (1000 * 30)
78
 #define NO_BRIGHT_MS (1000 * 2)
73
 #define NO_BRIGHT_MS (1000 * 2)
79
 
74
 
80
 #define NTP_SERVER "pool.ntp.org"
75
 #define NTP_SERVER "pool.ntp.org"
81
 #define STANDBY_REDRAW_MS 500
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
 // TODO auto-detect?!
83
 // TODO auto-detect?!
84
 #warning hard-coded timezone and daylight savings offset
84
 #warning hard-coded timezone and daylight savings offset
85
 #define gmtOffset_sec (60 * 60)
85
 #define gmtOffset_sec (60 * 60)
86
 #define daylightOffset_sec (60 * 60)
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
 static SPIClass mySpi = SPIClass(HSPI);
92
 static SPIClass mySpi = SPIClass(HSPI);
89
 static XPT2046_Touchscreen ts(XPT2046_CS, XPT2046_IRQ);
93
 static XPT2046_Touchscreen ts(XPT2046_CS, XPT2046_IRQ);
90
 static TFT_eSPI tft = TFT_eSPI();
94
 static TFT_eSPI tft = TFT_eSPI();
110
 static int set_max_brightness = LCD_MAX_BRIGHTNESS;
114
 static int set_max_brightness = LCD_MAX_BRIGHTNESS;
111
 static unsigned long last_standby_draw = 0;
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
 static void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
117
 static void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
120
     uint32_t duty = (4095 / valueMax) * min(value, valueMax);
118
     uint32_t duty = (4095 / valueMax) * min(value, valueMax);
121
     ledcWrite(channel, duty);
119
     ledcWrite(channel, duty);
352
     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);
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
 void ui_progress(enum ui_state state) {
423
 void ui_progress(enum ui_state state) {
356
     int x = LCD_WIDTH / 2;
424
     int x = LCD_WIDTH / 2;
357
     int y = LCD_HEIGHT / 2;
425
     int y = LCD_HEIGHT / 2;
365
             tft.drawString("xythobuz.de", x, y, fontSize);
433
             tft.drawString("xythobuz.de", x, y, fontSize);
366
         } break;
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
         case UI_WIFI_CONNECT: {
448
         case UI_WIFI_CONNECT: {
369
             tft.setTextDatum(MC_DATUM); // middle center
449
             tft.setTextDatum(MC_DATUM); // middle center
370
             tft.drawString("Connecting to '" WIFI_SSID "'", x, y + 32, fontSize);
450
             tft.drawString("Connecting to '" WIFI_SSID "'", x, y + 32, fontSize);

Loading…
Cancel
Save