Browse Source

Refactored AppCore

master
Robin Thoni 4 years ago
parent
commit
14abcba639
Signed by: Robin THONI <robin@rthoni.com> GPG Key ID: 4E09DEF46B99E61E
3 changed files with 210 additions and 155 deletions
  1. 168
    155
      AppCore.cpp
  2. 41
    0
      AppCore.h
  3. 1
    0
      main.ino

+ 168
- 155
AppCore.cpp View File

@@ -1,9 +1,3 @@
1
-#include <LiquidCrystal.h>
2
-#include <JC_Button.h>
3
-#include <OneWire.h>
4
-#include <DallasTemperature.h>
5
-#include "Boiler.h"
6
-#include "Storage.h"
7 1
 #include "AppCore.h"
8 2
 
9 3
 #define HIBERNATE_DELAY 5000
@@ -24,35 +18,11 @@
24 18
 #define PIN_LCD_D2 3
25 19
 #define PIN_LCD_D3 2
26 20
 
27
-byte g_sensorChar[8] = {
28
-        B00100,
29
-        B01110,
30
-        B01110,
31
-        B01110,
32
-        B01110,
33
-        B11111,
34
-        B11111,
35
-        B01110,
36
-};
37
-
38
-Storage g_storage;
39
-
40
-OneWire g_oneWire(PIN_ONEWIRE);
41
-DallasTemperature g_sensors(&g_oneWire);
42
-DeviceAddress g_sensor1;
43
-
44
-Button g_btnMode(PIN_BTN_MODE);
45
-Button g_btnMinus(PIN_BTN_MINUS);
46
-Button g_btnPlus(PIN_BTN_PLUS);
47
-Button* g_buttons[3] = {&g_btnMode, &g_btnMinus, &g_btnPlus};
48 21
 #define BUTTONS_COUNT (sizeof(g_buttons) / sizeof(*g_buttons))
22
+#define MODE_SEQUENCE_COUNT (sizeof(m_modeSequence) / sizeof(*m_modeSequence))
49 23
 
50
-LiquidCrystal g_lcd(PIN_LCD_RS, PIN_LCD_ENABLE, PIN_LCD_D0, PIN_LCD_D1, PIN_LCD_D2, PIN_LCD_D3);
51
-
52
-UiStateEnum g_modeSequence[3] = {WaterSetting, HeaterSetting, Lighting};
53
-#define MODE_SEQUENCE_COUNT (sizeof(g_modeSequence) / sizeof(*g_modeSequence))
54
-
55
-AppCoreState g_appCoreState = {
24
+AppCore::AppCore()
25
+        : m_appCoreState{
56 26
         .appState = {
57 27
                 .lastSensorRequestMs = 0,
58 28
                 .hasReadSensors = true,
@@ -73,115 +43,60 @@ AppCoreState g_appCoreState = {
73 43
                 .modeSequenceIndex = MODE_SEQUENCE_COUNT - 1,
74 44
                 .isUpdateNeeded = true
75 45
         }
76
-};
77
-
78
-void tmpToStr(char* out, temp_t temp)
79
-{
80
-    if (temp == TEMP_T_INVALID)
81
-    {
82
-        strcpy(out, " -- ");
83
-    }
84
-    else
85
-    {
86
-        char tmp[7];
87
-        dtostrf(temp / 2.0f, 2, 1, tmp);
88
-        auto len = 4 - strlen(tmp);
89
-        for (auto i = 0; i < len; ++i)
90
-        {
91
-            out[i] = ' ';
92
-        }
93
-        strcpy(&out[len], tmp);
94
-    }
95 46
 }
96
-
97
-void printStateLine(char prefix, const BoilerItemState& boilerItemState, bool isModifying, bool isActive, LiquidCrystal lcd)
47
+          , m_modeSequence{WaterSetting, HeaterSetting, Lighting}
48
+          , m_btnMode{PIN_BTN_MODE}
49
+          , m_btnMinus{PIN_BTN_MINUS}
50
+          , m_btnPlus{PIN_BTN_PLUS}
51
+          , m_buttons{&m_btnMode, &m_btnMinus, &m_btnPlus}
52
+          , m_lcd{PIN_LCD_RS, PIN_LCD_ENABLE, PIN_LCD_D0, PIN_LCD_D1, PIN_LCD_D2, PIN_LCD_D3}
53
+          , m_oneWire{PIN_ONEWIRE}
54
+          , m_sensors{&m_oneWire}
55
+          , m_sensor1{0}
98 56
 {
99
-    char curTmp[7], setTmp[7], tmp[17];
100
-    tmpToStr(curTmp, boilerItemState.current);
101
-    tmpToStr(setTmp, boilerItemState.setting);
102
-    int count = snprintf(tmp, sizeof(tmp), "%c: %s [%s]%c%c", prefix, curTmp, setTmp, isModifying ? '<' : ' ', isActive ? LCD_CHAR_SENSOR : ' ');
103
-    for (; count < 17; ++count)
104
-    {
105
-        tmp[count] = ' ';
106
-    }
107
-    tmp[count] = 0;
108
-    lcd.print(tmp);
109
-}
110
-
111
-void printState(const AppCoreState& appCoreState, LiquidCrystal lcd)
112
-{
113
-    Serial.println("Updating display");
114
-
115
-    lcd.setCursor(0, 0);
116
-    printStateLine('S', appCoreState.appState.water, appCoreState.uiState.state == WaterSetting, appCoreState.appState.water.isActive, lcd);
117
-    lcd.setCursor(0, 1);
118
-    printStateLine('C', appCoreState.appState.heater, appCoreState.uiState.state == HeaterSetting, appCoreState.appState.heater.isActive, lcd);
119
-}
120
-
121
-void setState(AppCoreState& boilerState, UiStateEnum state)
122
-{
123
-    char tmp[50];
124
-    snprintf(tmp, sizeof(tmp), "Changing state %i => %i", g_appCoreState.uiState.state, state);
125
-    Serial.println(tmp);
126
-
127
-    if (state == Lighting)
128
-    {
129
-        digitalWrite(PIN_LCD_LED, 1);
130
-    }
131
-    else if (state == Hibernate)
132
-    {
133
-        digitalWrite(PIN_LCD_LED, 0);
134
-        g_appCoreState.uiState.modeSequenceIndex = MODE_SEQUENCE_COUNT - 1;
135
-    }
136
-    g_appCoreState.uiState.state = state;
137
-    g_appCoreState.uiState.isUpdateNeeded = true;
138
-}
139
-
140
-void checkBoilerItem(BoilerItemState& boilerItemState, UiState uiState)
141
-{
142
-    if (!boilerItemState.isActive && boilerItemState.current != TEMP_T_INVALID && boilerItemState.current <= boilerItemState.setting - TEMP_TRIGGER)
143
-    {
144
-        boilerItemState.isActive = true;
145
-        uiState.isUpdateNeeded = true;
146
-    }
147
-    else if (boilerItemState.isActive && (boilerItemState.current == TEMP_T_INVALID || boilerItemState.current >= boilerItemState.setting))
148
-    {
149
-        boilerItemState.isActive = false;
150
-        uiState.isUpdateNeeded = true;
151
-    }
152 57
 }
153 58
 
154 59
 void AppCore::setup()
155 60
 {
156
-    g_sensors.begin();
157
-    g_sensors.getAddress(g_sensor1, 0);
158
-    g_sensors.setWaitForConversion(false);
61
+    m_sensors.begin();
62
+    m_sensors.getAddress(m_sensor1, 0);
63
+    m_sensors.setWaitForConversion(false);
159 64
 
160
-    for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
65
+    for (auto& g_button : m_buttons)
161 66
     {
162
-        g_buttons[i]->begin();
67
+        g_button->begin();
163 68
     }
164 69
 
165 70
     pinMode(PIN_LCD_LED, OUTPUT);
166 71
     digitalWrite(PIN_LCD_LED, 1);
167 72
 
168
-    g_lcd.begin(16, 2);
169
-    g_lcd.createChar(LCD_CHAR_SENSOR, g_sensorChar);
73
+    m_lcd.begin(16, 2);
74
+    byte sensorChar[8] = {
75
+            B00100,
76
+            B01110,
77
+            B01110,
78
+            B01110,
79
+            B01110,
80
+            B11111,
81
+            B11111,
82
+            B01110,
83
+    };
84
+    m_lcd.createChar(LCD_CHAR_SENSOR, sensorChar);
170 85
 
171 86
     Serial.begin(9600);
172 87
 
173 88
     bool allButtonsPressed = true;
174
-    for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
89
+    for (auto& g_button : m_buttons)
175 90
     {
176
-        allButtonsPressed = allButtonsPressed && g_buttons[i]->isPressed();
91
+        allButtonsPressed = allButtonsPressed && g_button->isPressed();
177 92
     }
178 93
     if (!allButtonsPressed)
179 94
     {
180
-        g_storage.load(g_appCoreState);
95
+        m_storage.load(m_appCoreState);
181 96
     }
182 97
     else
183 98
     {
184
-        g_storage.save(g_appCoreState);
99
+        m_storage.save(m_appCoreState);
185 100
     }
186 101
 }
187 102
 
@@ -189,99 +104,197 @@ void AppCore::loop()
189 104
 {
190 105
     const auto& currentMs = millis();
191 106
 
192
-    if (currentMs - g_appCoreState.appState.lastSensorRequestMs >= SENSORS_CHECK_INTERVAL)
107
+    if (currentMs - m_appCoreState.appState.lastSensorRequestMs >= SENSORS_CHECK_INTERVAL)
193 108
     {
194
-        g_appCoreState.appState.lastSensorRequestMs = currentMs;
195
-        g_appCoreState.appState.hasReadSensors = false;
196
-        g_sensors.requestTemperaturesByAddress(g_sensor1);
109
+        m_appCoreState.appState.lastSensorRequestMs = currentMs;
110
+        m_appCoreState.appState.hasReadSensors = false;
111
+        m_sensors.requestTemperaturesByAddress(m_sensor1);
197 112
     }
198
-    if (currentMs - g_appCoreState.appState.lastSensorRequestMs >= SENSORS_REQUEST_DELAY && !g_appCoreState.appState.hasReadSensors)
113
+    if (currentMs - m_appCoreState.appState.lastSensorRequestMs >= SENSORS_REQUEST_DELAY &&
114
+        !m_appCoreState.appState.hasReadSensors)
199 115
     {
200
-        g_appCoreState.appState.hasReadSensors = true;
201
-        auto raw = g_sensors.getTempC(g_sensor1);
116
+        m_appCoreState.appState.hasReadSensors = true;
117
+        auto raw = m_sensors.getTempC(m_sensor1);
202 118
         temp_t temp = TEMP_T_INVALID;
203 119
         if (raw != DEVICE_DISCONNECTED_C)
204 120
         {
205 121
             temp = (temp_t) (raw * 2);
206 122
         }
207 123
 
208
-        if (temp != g_appCoreState.appState.water.current)
124
+        if (temp != m_appCoreState.appState.water.current)
209 125
         {
210
-            g_appCoreState.appState.water.current = temp;
211
-            g_appCoreState.uiState.isUpdateNeeded = true;
126
+            m_appCoreState.appState.water.current = temp;
127
+            m_appCoreState.uiState.isUpdateNeeded = true;
212 128
         }
213 129
     }
214 130
 
215 131
 
216
-    for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
132
+    for (auto& pButton : m_buttons)
217 133
     {
218
-        g_buttons[i]->read();
219
-        if (g_buttons[i]->isPressed())
134
+        pButton->read();
135
+        if (pButton->isPressed())
220 136
         {
221
-            g_appCoreState.uiState.lastOpMs = currentMs;
137
+            m_appCoreState.uiState.lastOpMs = currentMs;
222 138
             break;
223 139
         }
224 140
     }
225 141
 
226 142
 
227
-    if (g_appCoreState.uiState.state == Hibernate)
143
+    if (m_appCoreState.uiState.state == Hibernate)
228 144
     {
229
-        for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
145
+        for (auto& pButton : m_buttons)
230 146
         {
231
-            if (g_buttons[i]->wasReleased())
147
+            if (pButton->wasReleased())
232 148
             {
233
-                setState(g_appCoreState, Lighting);
149
+                setState(Lighting);
234 150
                 break;
235 151
             }
236 152
         }
237 153
     }
238 154
     else
239 155
     {
240
-        if (currentMs - g_appCoreState.uiState.lastOpMs >= HIBERNATE_DELAY)
156
+        if (currentMs - m_appCoreState.uiState.lastOpMs >= HIBERNATE_DELAY)
241 157
         {
242
-            setState(g_appCoreState, Hibernate);
158
+            setState(Hibernate);
243 159
         }
244 160
         else
245 161
         {
246
-            if (g_btnMode.wasReleased())
162
+            if (m_btnMode.wasReleased())
247 163
             {
248
-                g_appCoreState.uiState.modeSequenceIndex = (g_appCoreState.uiState.modeSequenceIndex + 1) % MODE_SEQUENCE_COUNT;
249
-                setState(g_appCoreState, g_modeSequence[g_appCoreState.uiState.modeSequenceIndex]);
164
+                m_appCoreState.uiState.modeSequenceIndex =
165
+                        (m_appCoreState.uiState.modeSequenceIndex + 1) % MODE_SEQUENCE_COUNT;
166
+                setState(m_modeSequence[m_appCoreState.uiState.modeSequenceIndex]);
250 167
             }
251
-            else if (g_btnMinus.wasReleased() || g_btnPlus.wasReleased())
168
+            else if (m_btnMinus.wasReleased() || m_btnPlus.wasReleased())
252 169
             {
253
-                BoilerItemState* itemState = NULL;
254
-                if (g_appCoreState.uiState.state == WaterSetting)
170
+                BoilerItemState* itemState = nullptr;
171
+                if (m_appCoreState.uiState.state == WaterSetting)
255 172
                 {
256
-                    itemState = &g_appCoreState.appState.water;
173
+                    itemState = &m_appCoreState.appState.water;
257 174
                 }
258
-                else if (g_appCoreState.uiState.state == HeaterSetting)
175
+                else if (m_appCoreState.uiState.state == HeaterSetting)
259 176
                 {
260
-                    itemState = &g_appCoreState.appState.heater;
177
+                    itemState = &m_appCoreState.appState.heater;
261 178
                 }
262 179
 
263 180
                 if (itemState)
264 181
                 {
265
-                    if (g_btnMinus.wasReleased())
182
+                    if (m_btnMinus.wasReleased())
266 183
                     {
267 184
                         --itemState->setting;
268 185
                     }
269
-                    else if (g_btnPlus.wasReleased())
186
+                    else if (m_btnPlus.wasReleased())
270 187
                     {
271 188
                         ++itemState->setting;
272 189
                     }
273
-                    g_appCoreState.uiState.isUpdateNeeded = true;
190
+                    m_appCoreState.uiState.isUpdateNeeded = true;
274 191
                 }
275 192
             }
276 193
         }
277 194
     }
278 195
 
279
-    checkBoilerItem(g_appCoreState.appState.water, g_appCoreState.uiState);
280
-    checkBoilerItem(g_appCoreState.appState.heater, g_appCoreState.uiState);
196
+    checkBoilerItem(m_appCoreState.appState.water);
197
+    checkBoilerItem(m_appCoreState.appState.heater);
281 198
 
282
-    if (g_appCoreState.uiState.isUpdateNeeded)
199
+    if (m_appCoreState.uiState.isUpdateNeeded)
283 200
     {
284
-        printState(g_appCoreState, g_lcd);
285
-        g_appCoreState.uiState.isUpdateNeeded = false;
201
+        printState();
202
+        m_appCoreState.uiState.isUpdateNeeded = false;
203
+    }
204
+}
205
+
206
+
207
+void AppCore::setState(
208
+        UiStateEnum state
209
+)
210
+{
211
+    char tmp[50];
212
+    snprintf(tmp, sizeof(tmp), "Changing state %i => %i", m_appCoreState.uiState.state, state);
213
+    Serial.println(tmp);
214
+
215
+    if (state == Lighting)
216
+    {
217
+        digitalWrite(PIN_LCD_LED, 1);
218
+    }
219
+    else if (state == Hibernate)
220
+    {
221
+        digitalWrite(PIN_LCD_LED, 0);
222
+        m_appCoreState.uiState.modeSequenceIndex = MODE_SEQUENCE_COUNT - 1;
223
+        m_storage.save(m_appCoreState);
224
+    }
225
+    m_appCoreState.uiState.state = state;
226
+    m_appCoreState.uiState.isUpdateNeeded = true;
227
+}
228
+
229
+void AppCore::checkBoilerItem(
230
+        BoilerItemState& boilerItemState
231
+)
232
+{
233
+    if (!boilerItemState.isActive && boilerItemState.current != TEMP_T_INVALID &&
234
+        boilerItemState.current <= boilerItemState.setting - TEMP_TRIGGER)
235
+    {
236
+        boilerItemState.isActive = true;
237
+        m_appCoreState.uiState.isUpdateNeeded = true;
238
+    }
239
+    else if (boilerItemState.isActive &&
240
+             (boilerItemState.current == TEMP_T_INVALID || boilerItemState.current >= boilerItemState.setting))
241
+    {
242
+        boilerItemState.isActive = false;
243
+        m_appCoreState.uiState.isUpdateNeeded = true;
244
+    }
245
+}
246
+
247
+void AppCore::printState()
248
+{
249
+    Serial.println("Updating display");
250
+
251
+    m_lcd.setCursor(0, 0);
252
+    printStateLine('S', m_appCoreState.appState.water, m_appCoreState.uiState.state == WaterSetting,
253
+                   m_appCoreState.appState.water.isActive);
254
+    m_lcd.setCursor(0, 1);
255
+    printStateLine('C', m_appCoreState.appState.heater, m_appCoreState.uiState.state == HeaterSetting,
256
+                   m_appCoreState.appState.heater.isActive);
257
+}
258
+
259
+void
260
+AppCore::printStateLine(
261
+        char prefix
262
+        , const BoilerItemState& boilerItemState
263
+        , bool isModifying
264
+        , bool isActive
265
+)
266
+{
267
+    char curTmp[7], setTmp[7], tmp[17];
268
+    tempToStr(curTmp, boilerItemState.current);
269
+    tempToStr(setTmp, boilerItemState.setting);
270
+    int count = snprintf(tmp, sizeof(tmp), "%c: %s [%s]%c%c", prefix, curTmp, setTmp, isModifying ? '<' : ' ',
271
+                         isActive ? LCD_CHAR_SENSOR : ' ');
272
+    for (; count < 17; ++count)
273
+    {
274
+        tmp[count] = ' ';
275
+    }
276
+    tmp[count] = 0;
277
+    m_lcd.print(tmp);
278
+}
279
+
280
+void AppCore::tempToStr(
281
+        char* out
282
+        , temp_t temp
283
+)
284
+{
285
+    if (temp == TEMP_T_INVALID)
286
+    {
287
+        strcpy(out, " -- ");
288
+    }
289
+    else
290
+    {
291
+        char tmp[7];
292
+        dtostrf(temp / 2.0f, 2, 1, tmp);
293
+        auto len = 4 - strlen(tmp);
294
+        for (auto i = 0; i < len; ++i)
295
+        {
296
+            out[i] = ' ';
297
+        }
298
+        strcpy(&out[len], tmp);
286 299
     }
287 300
 }

+ 41
- 0
AppCore.h View File

@@ -1,15 +1,56 @@
1 1
 #pragma once
2 2
 
3
+#include <LiquidCrystal.h>
4
+#include <JC_Button.h>
5
+#include <OneWire.h>
6
+#include <DallasTemperature.h>
7
+#include "Boiler.h"
8
+#include "Storage.h"
3 9
 
4 10
 class AppCore
5 11
 {
6 12
 public:
13
+    AppCore();
14
+
7 15
     void setup();
8 16
 
9 17
     void loop();
10 18
 
19
+protected:
20
+    void setState(UiStateEnum state);
21
+
22
+    void checkBoilerItem(BoilerItemState& boilerItemState);
23
+
24
+    void printState();
25
+
26
+    void printStateLine(
27
+            char prefix
28
+            , const BoilerItemState& boilerItemState
29
+            , bool isModifying
30
+            , bool isActive
31
+    );
32
+
33
+    void tempToStr(
34
+            char* out
35
+            , temp_t temp
36
+    );
37
+
11 38
 private:
39
+    AppCoreState m_appCoreState;
40
+    Storage m_storage;
41
+
42
+    UiStateEnum m_modeSequence[3];
43
+
44
+    Button m_btnMode;
45
+    Button m_btnMinus;
46
+    Button m_btnPlus;
47
+    Button* m_buttons[3];
48
+
49
+    LiquidCrystal m_lcd;
12 50
 
51
+    OneWire m_oneWire;
52
+    DallasTemperature m_sensors;
53
+    DeviceAddress m_sensor1;
13 54
 };
14 55
 
15 56
 

+ 1
- 0
main.ino View File

@@ -1,4 +1,5 @@
1 1
 #include "AppCore.h"
2
+#include <OneWire.h>
2 3
 
3 4
 AppCore g_appCore;
4 5
 

Loading…
Cancel
Save