123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #include <LiquidCrystal.h>
- #include <JC_Button.h>
- #include "Boiler.h"
-
- #define HIBERNATE_DELAY 5000
- #define TEMP_TRIGGER 10
- #define LCD_CHAR_SENSOR 1
-
- #define PIN_BTN_MODE 11
- #define PIN_BTN_MINUS 10
- #define PIN_BTN_PLUS 9
- #define PIN_LCD_LED 8
- #define PIN_LCD_RS 7
- #define PIN_LCD_ENABLE 6
- #define PIN_LCD_D0 5
- #define PIN_LCD_D1 4
- #define PIN_LCD_D2 3
- #define PIN_LCD_D3 2
-
- byte g_sensorChar[8] = {
- B00100,
- B01110,
- B01110,
- B01110,
- B01110,
- B11111,
- B11111,
- B01110,
- };
-
- Button g_btnMode(PIN_BTN_MODE);
- Button g_btnMinus(PIN_BTN_MINUS);
- Button g_btnPlus(PIN_BTN_PLUS);
- Button* g_buttons[3] = {&g_btnMode, &g_btnMinus, &g_btnPlus};
- #define BUTTONS_COUNT (sizeof(g_buttons) / sizeof(*g_buttons))
-
- LiquidCrystal g_lcd(PIN_LCD_RS, PIN_LCD_ENABLE, PIN_LCD_D0, PIN_LCD_D1, PIN_LCD_D2, PIN_LCD_D3);
-
- UiStateEnum g_modeSequence[3] = {WaterSetting, HeaterSetting, Lighting};
- #define MODE_SEQUENCE_COUNT (sizeof(g_modeSequence) / sizeof(*g_modeSequence))
-
- BoilerState g_boilerState = {
- .water = {
- .current = 44,
- .setting = 44,
- .isActive = false
- },
- .heater = {
- .current = 44,
- .setting = 44,
- .isActive = false
- },
- .uiState = {
- .state = Lighting,
- .lastOpMs = 0,
- .modeSequenceIndex = MODE_SEQUENCE_COUNT - 1
- }
- };
-
- void printStateLine(char prefix, const BoilerLineState& boilerLineState, bool isModifying, bool isActive, LiquidCrystal lcd)
- {
- char curTmp[5], setTmp[5], tmp[17];
- dtostrf(boilerLineState.current / 2.0f, 2, 1, curTmp);
- dtostrf(boilerLineState.setting / 2.0f, 2, 1, setTmp);
- int count = snprintf(tmp, sizeof(tmp), "%c: %s [%s]%c%c", prefix, curTmp, setTmp, isModifying ? '<' : ' ', isActive ? LCD_CHAR_SENSOR : ' ');
- for (; count < 17; ++count)
- {
- tmp[count] = ' ';
- }
- tmp[count] = 0;
- lcd.print(tmp);
- }
-
- void printState(const BoilerState& boilerState, LiquidCrystal lcd)
- {
- lcd.setCursor(0, 0);
- printStateLine('S', boilerState.water, boilerState.uiState.state == WaterSetting, boilerState.water.isActive, lcd);
- lcd.setCursor(0, 1);
- printStateLine('C', boilerState.heater, boilerState.uiState.state == HeaterSetting, boilerState.heater.isActive, lcd);
- }
-
- void setup()
- {
- for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
- {
- g_buttons[i]->begin();
- }
-
- pinMode(PIN_LCD_LED, OUTPUT);
- digitalWrite(PIN_LCD_LED, 1);
-
- g_lcd.begin(16, 2);
- g_lcd.createChar(LCD_CHAR_SENSOR, g_sensorChar);
- printState(g_boilerState, g_lcd);
-
- Serial.begin(9600);
- }
-
- void loop()
- {
- bool needLcdUpdate = false;
- unsigned long currentMs = millis();
-
- for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
- {
- g_buttons[i]->read();
- if (g_buttons[i]->isPressed())
- {
- g_boilerState.uiState.lastOpMs = currentMs;
- }
- }
-
-
- if (g_boilerState.uiState.state == Hibernate)
- {
- for (unsigned i = 0; i < BUTTONS_COUNT; ++i)
- {
- if (g_buttons[i]->wasReleased())
- {
- g_boilerState.uiState.state = Lighting;
- digitalWrite(PIN_LCD_LED, 1);
- break;
- }
- }
- needLcdUpdate = true;
- }
- else
- {
- if (currentMs - g_boilerState.uiState.lastOpMs >= HIBERNATE_DELAY)
- {
- g_boilerState.uiState.state = Hibernate;
- digitalWrite(PIN_LCD_LED, 0);
- g_boilerState.uiState.modeSequenceIndex = MODE_SEQUENCE_COUNT - 1;
- needLcdUpdate = true;
- }
- else
- {
- if (g_btnMode.wasPressed())
- {
- g_boilerState.uiState.modeSequenceIndex =
- (g_boilerState.uiState.modeSequenceIndex + 1) % MODE_SEQUENCE_COUNT;
- g_boilerState.uiState.state = g_modeSequence[g_boilerState.uiState.modeSequenceIndex];
- needLcdUpdate = true;
- }
- else
- {
- temp_t* setting = NULL;
- if (g_boilerState.uiState.state == WaterSetting)
- {
- setting = &g_boilerState.water.setting;
- }
- else if (g_boilerState.uiState.state == HeaterSetting)
- {
- setting = &g_boilerState.heater.setting;
- }
-
- if (setting)
- {
- if (g_btnMinus.wasReleased())
- {
- --(*setting);
- }
- else if (g_btnPlus.wasReleased())
- {
- ++(*setting);
- }
- needLcdUpdate = true;
- }
- }
- }
- }
-
- if (!g_boilerState.water.isActive && (g_boilerState.water.current <= g_boilerState.water.setting - TEMP_TRIGGER))
- {
- g_boilerState.water.isActive = true;
- needLcdUpdate = true;
- }
- else if (g_boilerState.water.isActive && (g_boilerState.water.current >= g_boilerState.water.setting))
- {
- g_boilerState.water.isActive = false;
- needLcdUpdate = true;
- }
-
- if (needLcdUpdate)
- {
- printState(g_boilerState, g_lcd);
- }
- }
|