ソースを参照

add touchscreen calibration ui and eeprom

Thomas Buck 5ヶ月前
コミット
008da59e34
10個のファイルの変更133行の追加26行の削除
  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 ファイルの表示

@@ -19,10 +19,24 @@ struct ConfigMemory {
19 19
     double bme1_temp_off;
20 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 29
     ConfigMemory() {
23 30
         sht_temp_off = 0.0;
24 31
         bme1_temp_off = 0.0;
25 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 ファイルの表示

@@ -38,6 +38,7 @@ extern struct ui_status ui_status;
38 38
 
39 39
 enum ui_state {
40 40
     UI_INIT = 0,
41
+    UI_MEMORY_READY,
41 42
     UI_WIFI_CONNECT,
42 43
     UI_WIFI_CONNECTING,
43 44
     UI_WIFI_CONNECTED,

+ 1
- 0
src/DebugLog.cpp ファイルの表示

@@ -13,6 +13,7 @@
13 13
 
14 14
 #include <Arduino.h>
15 15
 
16
+#include "config.h"
16 17
 #include "servers.h"
17 18
 #include "DebugLog.h"
18 19
 

+ 2
- 0
src/SimpleInflux.cpp ファイルの表示

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

+ 9
- 8
src/SimpleUpdater.cpp ファイルの表示

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

+ 4
- 0
src/main.cpp ファイルの表示

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

+ 1
- 0
src/memory.cpp ファイルの表示

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

+ 5
- 3
src/moisture.cpp ファイルの表示

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

+ 2
- 1
src/relais.cpp ファイルの表示

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

+ 94
- 14
src/ui.cpp ファイルの表示

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

読み込み中…
キャンセル
保存