Browse Source

add basic visual indicator

Thomas Buck 6 months ago
parent
commit
c3c79fe73b
11 changed files with 156 additions and 60 deletions
  1. 1
    0
      CMakeLists.txt
  2. 5
    0
      include/lcd.h
  3. 5
    1
      include/menu.h
  4. 0
    8
      include/text.h
  5. 28
    0
      include/textbox.h
  6. 5
    2
      src/menu.c
  7. 2
    1
      src/state_about.c
  8. 9
    4
      src/state_value.c
  9. 39
    3
      src/state_volcano_run.c
  10. 0
    41
      src/text.c
  11. 62
    0
      src/textbox.c

+ 1
- 0
CMakeLists.txt View File

93
     src/state_settings.c
93
     src/state_settings.c
94
     src/state_about.c
94
     src/state_about.c
95
     src/state_value.c
95
     src/state_value.c
96
+    src/textbox.c
96
 
97
 
97
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
98
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
98
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c
99
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c

+ 5
- 0
include/lcd.h View File

29
     | (((g) >> 2) << 5)    \
29
     | (((g) >> 2) << 5)    \
30
     |  ((b) >> 3)          \
30
     |  ((b) >> 3)          \
31
 )
31
 )
32
+
32
 #define RGB_565_REV(c)            \
33
 #define RGB_565_REV(c)            \
33
     ((c & 0xF800) >> 8) / 255.0f, \
34
     ((c & 0xF800) >> 8) / 255.0f, \
34
     ((c & 0x07E0) >> 3) / 255.0f, \
35
     ((c & 0x07E0) >> 3) / 255.0f, \
35
     ((c & 0x001F) << 3) / 255.0f
36
     ((c & 0x001F) << 3) / 255.0f
37
+
38
+#define LCD_BLACK RGB_565(0x00, 0x00, 0x00)
39
+#define LCD_WHITE RGB_565(0xFF, 0xFF, 0xFF)
40
+
36
 uint32_t from_hsv(float h, float s, float v);
41
 uint32_t from_hsv(float h, float s, float v);
37
 
42
 
38
 void lcd_init(void);
43
 void lcd_init(void);

+ 5
- 1
include/menu.h View File

24
 #define MENU_MAX_LINES 5
24
 #define MENU_MAX_LINES 5
25
 #define MENU_MAX_LEN (MENU_MAX_LINES * 32)
25
 #define MENU_MAX_LEN (MENU_MAX_LINES * 32)
26
 
26
 
27
+#define MENU_BOX_HEIGHT(lines, font, space) ((lines * font) + ((lines - 1) * space))
28
+
27
 struct menu_state {
29
 struct menu_state {
28
     int off;
30
     int off;
29
     int selection;
31
     int selection;
30
     int length;
32
     int length;
31
     char buff[MENU_MAX_LEN];
33
     char buff[MENU_MAX_LEN];
34
+    int lines;
35
+    int y_off;
32
 };
36
 };
33
 
37
 
34
 void menu_init(void (*enter)(int),
38
 void menu_init(void (*enter)(int),
44
 #define ADD_STATIC_ELEMENT(name) {\
48
 #define ADD_STATIC_ELEMENT(name) {\
45
     menu->length += 1; \
49
     menu->length += 1; \
46
     if (((menu->length - 1) >= menu->off) \
50
     if (((menu->length - 1) >= menu->off) \
47
-        && ((menu->length - 1 - menu->off) < MENU_MAX_LINES)) { \
51
+        && ((menu->length - 1 - menu->off) < menu->lines)) { \
48
         if ((menu->length - 1) == menu->selection) { \
52
         if ((menu->length - 1) == menu->selection) { \
49
             pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos, "> "); \
53
             pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos, "> "); \
50
         } else { \
54
         } else { \

+ 0
- 8
include/text.h View File

20
 #define __TEXT_H__
20
 #define __TEXT_H__
21
 
21
 
22
 #include "mcufont.h"
22
 #include "mcufont.h"
23
-#include "menu.h"
24
 
23
 
25
 #define TEXT_BG_NONE -1
24
 #define TEXT_BG_NONE -1
26
-#define TEXT_BOX_HEIGHT(font, space) ((MENU_MAX_LINES * font) + ((MENU_MAX_LINES - 1) * space))
27
 
25
 
28
 struct text_font {
26
 struct text_font {
29
     const char *fontname;
27
     const char *fontname;
51
 void text_prepare_font(struct text_font *tf);
49
 void text_prepare_font(struct text_font *tf);
52
 int16_t text_draw(struct text_conf *tc);
50
 int16_t text_draw(struct text_conf *tc);
53
 
51
 
54
-int16_t text_box(const char *s, bool centered,
55
-                 const char *fontname,
56
-                 uint16_t x_off, uint16_t width,
57
-                 uint16_t y_off, uint16_t height,
58
-                 int16_t y_text_off);
59
-
60
 #endif // __TEXT_H__
52
 #endif // __TEXT_H__

+ 28
- 0
include/textbox.h View File

1
+/*
2
+ * textbox.h
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef __TEXTBOX_H__
20
+#define __TEXTBOX_H__
21
+
22
+int16_t text_box(const char *s, bool centered,
23
+                 const char *fontname,
24
+                 uint16_t x_off, uint16_t width,
25
+                 uint16_t y_off, uint16_t height,
26
+                 int16_t y_text_off);
27
+
28
+#endif // __TEXTBOX_H__

+ 5
- 2
src/menu.c View File

21
 #include "config.h"
21
 #include "config.h"
22
 #include "buttons.h"
22
 #include "buttons.h"
23
 #include "text.h"
23
 #include "text.h"
24
+#include "textbox.h"
24
 #include "lcd.h"
25
 #include "lcd.h"
25
 #include "menu.h"
26
 #include "menu.h"
26
 
27
 
83
         while (menu.selection < menu.off) {
84
         while (menu.selection < menu.off) {
84
             menu.off -= 1;
85
             menu.off -= 1;
85
         }
86
         }
86
-        while (menu.selection >= (menu.off + MENU_MAX_LINES)) {
87
+        while (menu.selection >= (menu.off + menu.lines)) {
87
             menu.off += 1;
88
             menu.off += 1;
88
         }
89
         }
89
     }
90
     }
96
     menu.off = 0;
97
     menu.off = 0;
97
     menu.selection = -1;
98
     menu.selection = -1;
98
     menu.length = 0;
99
     menu.length = 0;
100
+    menu.lines = MENU_MAX_LINES;
101
+    menu.y_off = 0;
99
 
102
 
100
     enter_callback = enter;
103
     enter_callback = enter;
101
     up_callback = up;
104
     up_callback = up;
118
         text_box(menu.buff, centered,
121
         text_box(menu.buff, centered,
119
                  "fixed_10x20",
122
                  "fixed_10x20",
120
                  0, LCD_WIDTH,
123
                  0, LCD_WIDTH,
121
-                 50, TEXT_BOX_HEIGHT(20, 2),
124
+                 50 + menu.y_off, MENU_BOX_HEIGHT(menu.lines, 20, 2),
122
                  0);
125
                  0);
123
     }
126
     }
124
 }
127
 }

+ 2
- 1
src/state_about.c View File

24
 #include "log.h"
24
 #include "log.h"
25
 #include "lcd.h"
25
 #include "lcd.h"
26
 #include "text.h"
26
 #include "text.h"
27
+#include "textbox.h"
27
 #include "menu.h"
28
 #include "menu.h"
28
 #include "state.h"
29
 #include "state.h"
29
 #include "state_about.h"
30
 #include "state_about.h"
68
 ;
69
 ;
69
 
70
 
70
 static const uint16_t step_size = 10;
71
 static const uint16_t step_size = 10;
71
-static const uint16_t max_height = TEXT_BOX_HEIGHT(20, 2);
72
+static const uint16_t max_height = MENU_BOX_HEIGHT(MENU_MAX_LINES, 20, 2);
72
 
73
 
73
 static uint16_t off = 0;
74
 static uint16_t off = 0;
74
 static bool held_up = false;
75
 static bool held_up = false;

+ 9
- 4
src/state_value.c View File

22
 #include "buttons.h"
22
 #include "buttons.h"
23
 #include "log.h"
23
 #include "log.h"
24
 #include "lcd.h"
24
 #include "lcd.h"
25
+#include "menu.h"
25
 #include "text.h"
26
 #include "text.h"
27
+#include "textbox.h"
26
 #include "state_value.h"
28
 #include "state_value.h"
27
 
29
 
28
 static void *val_p = NULL;
30
 static void *val_p = NULL;
64
     } else {
66
     } else {
65
         if (val_mode == VAL_STEP_INCREMENT) {
67
         if (val_mode == VAL_STEP_INCREMENT) {
66
             pos += snprintf(buff, sizeof(buff),
68
             pos += snprintf(buff, sizeof(buff),
67
-                            "%s:\n%d -> %d -> %d",
69
+                            "%s:\n\n%d -> %d -> %d",
68
                             val_name, val_min / val_step, val / val_step, val_max / val_step);
70
                             val_name, val_min / val_step, val / val_step, val_max / val_step);
69
         } else {
71
         } else {
70
             pos += snprintf(buff, sizeof(buff),
72
             pos += snprintf(buff, sizeof(buff),
71
-                            "%s:\n%04X -> %04X -> %04X",
72
-                            val_name, val_min, val, val_max);
73
+                            "%s:\n\n%d -> %d -> %d",
74
+                            val_name,
75
+                            __builtin_ffs(val_min),
76
+                            __builtin_ffs(val),
77
+                            __builtin_ffs(val_max));
73
         }
78
         }
74
     }
79
     }
75
 
80
 
76
     text_box(buff, true,
81
     text_box(buff, true,
77
              "fixed_10x20",
82
              "fixed_10x20",
78
              0, LCD_WIDTH,
83
              0, LCD_WIDTH,
79
-             50, TEXT_BOX_HEIGHT(20, 2),
84
+             50, MENU_BOX_HEIGHT(MENU_MAX_LINES, 20, 2),
80
              0);
85
              0);
81
 }
86
 }
82
 
87
 

+ 39
- 3
src/state_volcano_run.c View File

22
 #include "config.h"
22
 #include "config.h"
23
 #include "buttons.h"
23
 #include "buttons.h"
24
 #include "log.h"
24
 #include "log.h"
25
+#include "lcd.h"
25
 #include "volcano.h"
26
 #include "volcano.h"
26
 #include "workflow.h"
27
 #include "workflow.h"
28
+#include "util.h"
27
 #include "state.h"
29
 #include "state.h"
28
 #include "state_volcano_run.h"
30
 #include "state_volcano_run.h"
29
 
31
 
73
     wf_reset();
75
     wf_reset();
74
 }
76
 }
75
 
77
 
78
+static void bar_graph(int y_off, int h, int val_min, int val, int val_max) {
79
+    float v = map(val, val_min, val_max, 0.0f, 1.0f);
80
+    uint16_t width = v * (LCD_WIDTH - 1);
81
+    uint32_t c = from_hsv(v * 0.333, 1.0, 1.0);
82
+    lcd_write_rect(0, y_off, width, y_off + h - 1, c);
83
+}
84
+
76
 static void draw(struct menu_state *menu) {
85
 static void draw(struct menu_state *menu) {
86
+    static struct wf_state prev_state = {0};
77
     struct wf_state state = wf_status();
87
     struct wf_state state = wf_status();
78
 
88
 
89
+    if ((state.step == prev_state.step)
90
+        && ((((state.step->op == OP_SET_TEMPERATURE) || (state.step->op == OP_WAIT_TEMPERATURE))
91
+               && ((state.curr_val / 10) == (prev_state.curr_val / 10)))
92
+            || (((state.step->op == OP_PUMP_TIME) || (state.step->op == OP_WAIT_TIME))
93
+               && ((state.curr_val / 500) == (prev_state.curr_val / 500))))) {
94
+        return;
95
+    }
96
+    prev_state = state;
97
+
98
+    menu->lines = 3;
99
+    menu->y_off = 20 + 2;
100
+
101
+    lcd_write_rect(0, 50,
102
+                   LCD_WIDTH - 1,
103
+                   50 + menu->y_off - 1,
104
+                   LCD_BLACK);
105
+    lcd_write_rect(0, 50 + MENU_BOX_HEIGHT(3, 20, 2) + menu->y_off,
106
+                   LCD_WIDTH - 1,
107
+                   50 + MENU_BOX_HEIGHT(3, 20, 2) + (menu->y_off * 2) - 1,
108
+                   LCD_BLACK);
109
+
79
     if (state.status == WF_IDLE) {
110
     if (state.status == WF_IDLE) {
80
         if (wait_for_connect) {
111
         if (wait_for_connect) {
81
             snprintf(menu->buff, MENU_MAX_LEN,
112
             snprintf(menu->buff, MENU_MAX_LEN,
82
                      "Connecting\nand\nDiscovering");
113
                      "Connecting\nand\nDiscovering");
83
         } else if (wait_for_disconnect) {
114
         } else if (wait_for_disconnect) {
84
             snprintf(menu->buff, MENU_MAX_LEN,
115
             snprintf(menu->buff, MENU_MAX_LEN,
85
-                     "Disconnecting");
116
+                     "\nDisconnecting");
117
+        } else {
118
+            snprintf(menu->buff, MENU_MAX_LEN,
119
+                     "\nDone");
86
         }
120
         }
87
         return;
121
         return;
88
     }
122
     }
89
 
123
 
124
+    bar_graph(50, menu->y_off, 0, state.index, state.count);
125
+    bar_graph(50 + MENU_BOX_HEIGHT(3, 20, 2) + menu->y_off, menu->y_off,
126
+              state.start_val, state.curr_val, state.step->val);
127
+
90
     int pos = 0;
128
     int pos = 0;
91
     pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
129
     pos += snprintf(menu->buff + pos, MENU_MAX_LEN - pos,
92
                     "step %d / %d\n", state.index, state.count);
130
                     "step %d / %d\n", state.index, state.count);
118
                         state.step->val / 1000.0f);
156
                         state.step->val / 1000.0f);
119
         break;
157
         break;
120
     }
158
     }
121
-
122
-    // TODO visualize
123
 }
159
 }
124
 
160
 
125
 void state_volcano_run_run(void) {
161
 void state_volcano_run_run(void) {

+ 0
- 41
src/text.c View File

16
  * See <http://www.gnu.org/licenses/>.
16
  * See <http://www.gnu.org/licenses/>.
17
  */
17
  */
18
 
18
 
19
-#include <string.h>
20
-
21
 #include "config.h"
19
 #include "config.h"
22
 #include "log.h"
20
 #include "log.h"
23
 #include "lcd.h"
21
 #include "lcd.h"
24
-#include "menu.h"
25
 #include "text.h"
22
 #include "text.h"
26
 
23
 
27
 typedef struct {
24
 typedef struct {
170
 
167
 
171
     return state.y;
168
     return state.y;
172
 }
169
 }
173
-
174
-int16_t text_box(const char *s, bool centered,
175
-                 const char *fontname,
176
-                 uint16_t x_off, uint16_t width,
177
-                 uint16_t y_off, uint16_t height,
178
-                 int16_t y_text_off) {
179
-    static struct text_font font = {
180
-        .fontname = "",
181
-        .font = NULL,
182
-    };
183
-
184
-    if ((font.font == NULL) || (strcmp(font.fontname, fontname) != 0)) {
185
-        font.fontname = fontname;
186
-        text_prepare_font(&font);
187
-    }
188
-
189
-    struct text_conf text = {
190
-        .text = s,
191
-        .x = x_off,
192
-        .y = y_off,
193
-        .y_text_off = y_text_off,
194
-        .justify = false,
195
-        .alignment = centered ? MF_ALIGN_CENTER : MF_ALIGN_LEFT,
196
-        .width = width,
197
-        .height = height,
198
-        .margin = 2,
199
-        .fg = RGB_565(0xFF, 0xFF, 0xFF),
200
-        .bg = TEXT_BG_NONE,
201
-        .font = &font,
202
-    };
203
-
204
-    lcd_write_rect(x_off, y_off,
205
-                   x_off + width - 1,
206
-                   y_off + height - 1,
207
-                   RGB_565(0x00, 0x00, 0x00));
208
-
209
-    return text_draw(&text);
210
-}

+ 62
- 0
src/textbox.c View File

1
+/*
2
+ * textbox.c
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include <string.h>
20
+
21
+#include "config.h"
22
+#include "lcd.h"
23
+#include "text.h"
24
+#include "textbox.h"
25
+
26
+int16_t text_box(const char *s, bool centered,
27
+                 const char *fontname,
28
+                 uint16_t x_off, uint16_t width,
29
+                 uint16_t y_off, uint16_t height,
30
+                 int16_t y_text_off) {
31
+    static struct text_font font = {
32
+        .fontname = "",
33
+        .font = NULL,
34
+    };
35
+
36
+    if ((font.font == NULL) || (strcmp(font.fontname, fontname) != 0)) {
37
+        font.fontname = fontname;
38
+        text_prepare_font(&font);
39
+    }
40
+
41
+    struct text_conf text = {
42
+        .text = s,
43
+        .x = x_off,
44
+        .y = y_off,
45
+        .y_text_off = y_text_off,
46
+        .justify = false,
47
+        .alignment = centered ? MF_ALIGN_CENTER : MF_ALIGN_LEFT,
48
+        .width = width,
49
+        .height = height,
50
+        .margin = 2,
51
+        .fg = LCD_WHITE,
52
+        .bg = TEXT_BG_NONE,
53
+        .font = &font,
54
+    };
55
+
56
+    lcd_write_rect(x_off, y_off,
57
+                   x_off + width - 1,
58
+                   y_off + height - 1,
59
+                   LCD_BLACK);
60
+
61
+    return text_draw(&text);
62
+}

Loading…
Cancel
Save