Browse Source

Improved internals

master
Robin Thoni 4 years ago
parent
commit
ce85b9c5d6
Signed by: Robin THONI <robin@rthoni.com> GPG Key ID: 4E09DEF46B99E61E
2 changed files with 98 additions and 68 deletions
  1. 18
    11
      Boiler.h
  2. 80
    57
      main.ino

+ 18
- 11
Boiler.h View File

6
 #define HEATER_BOILER_H
6
 #define HEATER_BOILER_H
7
 
7
 
8
 typedef char temp_t;
8
 typedef char temp_t;
9
+typedef unsigned long timestamp_t;
9
 
10
 
10
 enum UiStateEnum
11
 enum UiStateEnum
11
 {
12
 {
15
     HeaterSetting
16
     HeaterSetting
16
 };
17
 };
17
 
18
 
18
-struct UiState
19
-{
20
-    UiStateEnum state;
21
-    unsigned long lastOpMs;
22
-    unsigned modeSequenceIndex;
23
-};
24
-
25
-struct BoilerLineState
19
+struct BoilerItemState
26
 {
20
 {
27
     temp_t current;
21
     temp_t current;
28
     temp_t setting;
22
     temp_t setting;
29
     bool isActive;
23
     bool isActive;
30
 };
24
 };
31
 
25
 
32
-struct BoilerState
26
+struct AppState
27
+{
28
+    BoilerItemState water;
29
+    BoilerItemState heater;
30
+};
31
+
32
+struct UiState
33
+{
34
+    UiStateEnum state;
35
+    timestamp_t lastOpMs;
36
+    unsigned modeSequenceIndex;
37
+    bool isUpdateNeeded;
38
+};
39
+
40
+struct GlobalState
33
 {
41
 {
34
-    BoilerLineState water;
35
-    BoilerLineState heater;
42
+    AppState appState;
36
     UiState uiState;
43
     UiState uiState;
37
 };
44
 };
38
 
45
 

+ 80
- 57
main.ino View File

39
 UiStateEnum g_modeSequence[3] = {WaterSetting, HeaterSetting, Lighting};
39
 UiStateEnum g_modeSequence[3] = {WaterSetting, HeaterSetting, Lighting};
40
 #define MODE_SEQUENCE_COUNT (sizeof(g_modeSequence) / sizeof(*g_modeSequence))
40
 #define MODE_SEQUENCE_COUNT (sizeof(g_modeSequence) / sizeof(*g_modeSequence))
41
 
41
 
42
-BoilerState g_boilerState = {
43
-        .water = {
44
-              .current = 44,
45
-              .setting = 44,
46
-              .isActive = false
47
-        },
48
-        .heater = {
49
-              .current = 44,
50
-              .setting = 44,
51
-              .isActive = false
42
+GlobalState g_globalState = {
43
+        .appState = {
44
+                .water = {
45
+                        .current = 44,
46
+                        .setting = 44,
47
+                        .isActive = false
48
+                },
49
+                .heater = {
50
+                        .current = 44,
51
+                        .setting = 44,
52
+                        .isActive = false
53
+                }
52
         },
54
         },
53
         .uiState = {
55
         .uiState = {
54
                 .state = Lighting,
56
                 .state = Lighting,
55
                 .lastOpMs = 0,
57
                 .lastOpMs = 0,
56
-                .modeSequenceIndex = MODE_SEQUENCE_COUNT - 1
58
+                .modeSequenceIndex = MODE_SEQUENCE_COUNT - 1,
59
+                .isUpdateNeeded = true
57
         }
60
         }
58
 };
61
 };
59
 
62
 
60
-void printStateLine(char prefix, const BoilerLineState& boilerLineState, bool isModifying, bool isActive, LiquidCrystal lcd)
63
+void printStateLine(char prefix, const BoilerItemState& boilerItemState, bool isModifying, bool isActive, LiquidCrystal lcd)
61
 {
64
 {
62
     char curTmp[5], setTmp[5], tmp[17];
65
     char curTmp[5], setTmp[5], tmp[17];
63
-    dtostrf(boilerLineState.current / 2.0f, 2, 1, curTmp);
64
-    dtostrf(boilerLineState.setting / 2.0f, 2, 1, setTmp);
66
+    dtostrf(boilerItemState.current / 2.0f, 2, 1, curTmp);
67
+    dtostrf(boilerItemState.setting / 2.0f, 2, 1, setTmp);
65
     int count = snprintf(tmp, sizeof(tmp), "%c: %s [%s]%c%c", prefix, curTmp, setTmp, isModifying ? '<' : ' ', isActive ? LCD_CHAR_SENSOR : ' ');
68
     int count = snprintf(tmp, sizeof(tmp), "%c: %s [%s]%c%c", prefix, curTmp, setTmp, isModifying ? '<' : ' ', isActive ? LCD_CHAR_SENSOR : ' ');
66
     for (; count < 17; ++count)
69
     for (; count < 17; ++count)
67
     {
70
     {
71
     lcd.print(tmp);
74
     lcd.print(tmp);
72
 }
75
 }
73
 
76
 
74
-void printState(const BoilerState& boilerState, LiquidCrystal lcd)
77
+void printState(const GlobalState& globalState, LiquidCrystal lcd)
75
 {
78
 {
79
+    Serial.println("Updating display");
80
+
76
     lcd.setCursor(0, 0);
81
     lcd.setCursor(0, 0);
77
-    printStateLine('S', boilerState.water, boilerState.uiState.state == WaterSetting, boilerState.water.isActive, lcd);
82
+    printStateLine('S', globalState.appState.water, globalState.uiState.state == WaterSetting, globalState.appState.water.isActive, lcd);
78
     lcd.setCursor(0, 1);
83
     lcd.setCursor(0, 1);
79
-    printStateLine('C', boilerState.heater, boilerState.uiState.state == HeaterSetting, boilerState.heater.isActive, lcd);
84
+    printStateLine('C', globalState.appState.heater, globalState.uiState.state == HeaterSetting, globalState.appState.heater.isActive, lcd);
85
+}
86
+
87
+void setState(GlobalState& boilerState, UiStateEnum state)
88
+{
89
+    char tmp[50];
90
+    snprintf(tmp, sizeof(tmp), "Changing state %i => %i", g_globalState.uiState.state, state);
91
+    Serial.println(tmp);
92
+    
93
+    if (state == Lighting)
94
+    {
95
+        digitalWrite(PIN_LCD_LED, 1);
96
+    }
97
+    else if (state == Hibernate)
98
+    {
99
+        digitalWrite(PIN_LCD_LED, 0);
100
+        g_globalState.uiState.modeSequenceIndex = MODE_SEQUENCE_COUNT - 1;
101
+    }
102
+    g_globalState.uiState.state = state;
103
+    g_globalState.uiState.isUpdateNeeded = true;
104
+}
105
+
106
+void checkBoilerItem(BoilerItemState& boilerItemState, UiState uiState)
107
+{
108
+    if (!boilerItemState.isActive && (boilerItemState.current <= boilerItemState.setting - TEMP_TRIGGER))
109
+    {
110
+        boilerItemState.isActive = true;
111
+        uiState.isUpdateNeeded = true;
112
+    }
113
+    else if (boilerItemState.isActive && (boilerItemState.current >= boilerItemState.setting))
114
+    {
115
+        boilerItemState.isActive = false;
116
+        uiState.isUpdateNeeded = true;
117
+    }
80
 }
118
 }
81
 
119
 
82
 void setup()
120
 void setup()
91
 
129
 
92
     g_lcd.begin(16, 2);
130
     g_lcd.begin(16, 2);
93
     g_lcd.createChar(LCD_CHAR_SENSOR, g_sensorChar);
131
     g_lcd.createChar(LCD_CHAR_SENSOR, g_sensorChar);
94
-    printState(g_boilerState, g_lcd);
95
 
132
 
96
     Serial.begin(9600);
133
     Serial.begin(9600);
97
 }
134
 }
98
 
135
 
99
 void loop()
136
 void loop()
100
 {
137
 {
101
-    bool needLcdUpdate = false;
102
-    unsigned long currentMs = millis();
138
+    const auto& currentMs = millis();
103
 
139
 
104
     for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
140
     for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
105
     {
141
     {
106
         g_buttons[i]->read();
142
         g_buttons[i]->read();
107
         if (g_buttons[i]->isPressed())
143
         if (g_buttons[i]->isPressed())
108
         {
144
         {
109
-            g_boilerState.uiState.lastOpMs = currentMs;
145
+            g_globalState.uiState.lastOpMs = currentMs;
146
+            break;
110
         }
147
         }
111
     }
148
     }
112
 
149
 
113
 
150
 
114
-    if (g_boilerState.uiState.state == Hibernate)
151
+    if (g_globalState.uiState.state == Hibernate)
115
     {
152
     {
116
         for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
153
         for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
117
         {
154
         {
118
             if (g_buttons[i]->wasReleased())
155
             if (g_buttons[i]->wasReleased())
119
             {
156
             {
120
-                g_boilerState.uiState.state = Lighting;
121
-                digitalWrite(PIN_LCD_LED, 1);
157
+                setState(g_globalState, Lighting);
122
                 break;
158
                 break;
123
             }
159
             }
124
         }
160
         }
125
-        needLcdUpdate = true;
126
     }
161
     }
127
     else
162
     else
128
     {
163
     {
129
-        if (currentMs - g_boilerState.uiState.lastOpMs >= HIBERNATE_DELAY)
164
+        if (currentMs - g_globalState.uiState.lastOpMs >= HIBERNATE_DELAY)
130
         {
165
         {
131
-            g_boilerState.uiState.state = Hibernate;
132
-            digitalWrite(PIN_LCD_LED, 0);
133
-            g_boilerState.uiState.modeSequenceIndex = MODE_SEQUENCE_COUNT - 1;
134
-            needLcdUpdate = true;
166
+            setState(g_globalState, Hibernate);
135
         }
167
         }
136
         else
168
         else
137
         {
169
         {
138
-            if (g_btnMode.wasPressed())
170
+            if (g_btnMode.wasReleased())
139
             {
171
             {
140
-                g_boilerState.uiState.modeSequenceIndex =
141
-                        (g_boilerState.uiState.modeSequenceIndex + 1) % MODE_SEQUENCE_COUNT;
142
-                g_boilerState.uiState.state = g_modeSequence[g_boilerState.uiState.modeSequenceIndex];
143
-                needLcdUpdate = true;
172
+                g_globalState.uiState.modeSequenceIndex = (g_globalState.uiState.modeSequenceIndex + 1) % MODE_SEQUENCE_COUNT;
173
+                setState(g_globalState, g_modeSequence[g_globalState.uiState.modeSequenceIndex]);
144
             }
174
             }
145
-            else
175
+            else if (g_btnMinus.wasReleased() || g_btnPlus.wasReleased())
146
             {
176
             {
147
-                temp_t* setting = NULL;
148
-                if (g_boilerState.uiState.state == WaterSetting)
177
+                BoilerItemState* itemState = NULL;
178
+                if (g_globalState.uiState.state == WaterSetting)
149
                 {
179
                 {
150
-                    setting = &g_boilerState.water.setting;
180
+                    itemState = &g_globalState.appState.water;
151
                 }
181
                 }
152
-                else if (g_boilerState.uiState.state == HeaterSetting)
182
+                else if (g_globalState.uiState.state == HeaterSetting)
153
                 {
183
                 {
154
-                    setting = &g_boilerState.heater.setting;
184
+                    itemState = &g_globalState.appState.heater;
155
                 }
185
                 }
156
 
186
 
157
-                if (setting)
187
+                if (itemState)
158
                 {
188
                 {
159
                     if (g_btnMinus.wasReleased())
189
                     if (g_btnMinus.wasReleased())
160
                     {
190
                     {
161
-                        --(*setting);
191
+                        --itemState->setting;
162
                     }
192
                     }
163
                     else if (g_btnPlus.wasReleased())
193
                     else if (g_btnPlus.wasReleased())
164
                     {
194
                     {
165
-                        ++(*setting);
195
+                        ++itemState->setting;
166
                     }
196
                     }
167
-                    needLcdUpdate = true;
197
+                    g_globalState.uiState.isUpdateNeeded = true;
168
                 }
198
                 }
169
             }
199
             }
170
         }
200
         }
171
     }
201
     }
172
 
202
 
173
-    if (!g_boilerState.water.isActive && (g_boilerState.water.current <= g_boilerState.water.setting - TEMP_TRIGGER))
174
-    {
175
-        g_boilerState.water.isActive = true;
176
-        needLcdUpdate = true;
177
-    }
178
-    else if (g_boilerState.water.isActive && (g_boilerState.water.current >= g_boilerState.water.setting))
179
-    {
180
-        g_boilerState.water.isActive = false;
181
-        needLcdUpdate = true;
182
-    }
203
+    checkBoilerItem(g_globalState.appState.water, g_globalState.uiState);
204
+    checkBoilerItem(g_globalState.appState.heater, g_globalState.uiState);
183
 
205
 
184
-    if (needLcdUpdate)
206
+    if (g_globalState.uiState.isUpdateNeeded)
185
     {
207
     {
186
-        printState(g_boilerState, g_lcd);
208
+        printState(g_globalState, g_lcd);
209
+        g_globalState.uiState.isUpdateNeeded = false;
187
     }
210
     }
188
 }
211
 }

Loading…
Cancel
Save