From 033d2f4c27a103ce6a1ba2c0844cb4580cb3207c Mon Sep 17 00:00:00 2001 From: rljonesau Date: Sat, 19 Jan 2019 07:15:02 +1100 Subject: [PATCH] Adding CPasswordScreen class --- .../src/OLED/FuelMixtureScreen.cpp | 133 +++++++------ .../src/OLED/FuelMixtureScreen.h | 1 + .../src/OLED/HeaterSettingsScreen.cpp | 138 +++++++++++++ .../src/OLED/HeaterSettingsScreen.h | 40 ++++ .../src/OLED/PasswordScreen.cpp | 183 ++++++++++++++++++ .../BTCDieselHeater/src/OLED/PasswordScreen.h | 46 +++++ .../src/OLED/ScreenManager.cpp | 14 +- .../src/OLED/SetClockScreen.cpp | 77 +++++--- .../BTCDieselHeater/src/OLED/SetClockScreen.h | 1 + .../src/OLED/SetTimerScreen.cpp | 86 +++++--- .../BTCDieselHeater/src/OLED/SetTimerScreen.h | 1 + .../BTCDieselHeater/src/Utility/NVStorage.cpp | 40 +++- .../BTCDieselHeater/src/Utility/NVStorage.h | 5 +- 13 files changed, 632 insertions(+), 133 deletions(-) create mode 100644 Arduino/BTCDieselHeater/src/OLED/HeaterSettingsScreen.cpp create mode 100644 Arduino/BTCDieselHeater/src/OLED/HeaterSettingsScreen.h create mode 100644 Arduino/BTCDieselHeater/src/OLED/PasswordScreen.cpp create mode 100644 Arduino/BTCDieselHeater/src/OLED/PasswordScreen.h diff --git a/Arduino/BTCDieselHeater/src/OLED/FuelMixtureScreen.cpp b/Arduino/BTCDieselHeater/src/OLED/FuelMixtureScreen.cpp index 4e8761d..2b37dd4 100644 --- a/Arduino/BTCDieselHeater/src/OLED/FuelMixtureScreen.cpp +++ b/Arduino/BTCDieselHeater/src/OLED/FuelMixtureScreen.cpp @@ -39,6 +39,7 @@ CFuelMixtureScreen::CFuelMixtureScreen(C128x64_OLED& display, CScreenManager& mg { _rowSel = 0; _colSel = 0; + _SaveTime = 0; for(int i= 0; i < 4; i++) _PWdig[i] = -1; } @@ -53,71 +54,81 @@ CFuelMixtureScreen::show() int xPos, yPos; const int col2 = 90; const int col3 = _display.width() - border; - _printInverted(0, 16, " Fuel Settings ", true); - switch(_rowSel) { - case 0: - // show settings overview (initial screen entry) - // pump max/min - yPos = 28; - _printMenuText(0, yPos, "Pump (Hz)"); - sprintf(str, "%.1f", getHeaterInfo().getPump_Min()); - _printMenuText(col2, yPos, str, false, eRightJustify); - sprintf(str, "%.1f", getHeaterInfo().getPump_Max()); - _printMenuText(col3, yPos, str, false, eRightJustify); - // fan max/min - yPos = 40; - _printMenuText(0, yPos, "Fan (RPM)"); - sprintf(str, "%d", getHeaterInfo().getFan_Min()); - _printMenuText(col2, yPos, str, false, eRightJustify); - sprintf(str, "%d", getHeaterInfo().getFan_Max()); - _printMenuText(col3, yPos, str, false, eRightJustify); - // navigation line - yPos = 53; - xPos = _display.xCentre(); - _printMenuText(xPos, yPos, "<- ->", true, eCentreJustify); - break; + if(_SaveTime) { + long tDelta = millis() - _SaveTime; + if(tDelta > 0) + _SaveTime = 0; + _printInverted(_display.xCentre(), 28, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 39, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 34, " STORING ", true, eCentreJustify); + } + else { - case 1: - _printMenuText(_display.xCentre(), 34, "Enter password...", false, eCentreJustify); - _showPassword(); - break; + switch(_rowSel) { + case 0: + // show settings overview (initial screen entry) + // pump max/min + yPos = 28; + _printMenuText(0, yPos, "Pump (Hz)"); + sprintf(str, "%.1f", getHeaterInfo().getPump_Min()); + _printMenuText(col2, yPos, str, false, eRightJustify); + sprintf(str, "%.1f", getHeaterInfo().getPump_Max()); + _printMenuText(col3, yPos, str, false, eRightJustify); + // fan max/min + yPos = 40; + _printMenuText(0, yPos, "Fan (RPM)"); + sprintf(str, "%d", getHeaterInfo().getFan_Min()); + _printMenuText(col2, yPos, str, false, eRightJustify); + sprintf(str, "%d", getHeaterInfo().getFan_Max()); + _printMenuText(col3, yPos, str, false, eRightJustify); + // navigation line + yPos = 53; + xPos = _display.xCentre(); + _printMenuText(xPos, yPos, "<- ->", true, eCentreJustify); + break; - case 2: - case 3: - case 4: - case 5: - _display.clearDisplay(); - // Pump Minimum adjustment - yPos = border + 36; - _printMenuText(80, yPos, "Min", false, eRightJustify); - sprintf(str, "%.1f", adjPump[0]); - _printMenuText(col3, yPos, str, _rowSel == 2, eRightJustify); - // Pump Maximum adjustment - yPos = border + 24; - _printMenuText(80, yPos, "Pump Hz Max", false, eRightJustify); - sprintf(str, "%.1f", adjPump[1]); - _printMenuText(col3, yPos, str, _rowSel == 3, eRightJustify); - // Fan Minimum adjustment - yPos = border + 12; - _printMenuText(80, yPos, "Min", false, eRightJustify); - sprintf(str, "%d", adjFan[0]); - _printMenuText(col3, yPos, str, _rowSel == 4, eRightJustify); - // Fan Maximum adjustment - yPos = border; - _printMenuText(80, yPos, "Fan RPM Max", false, eRightJustify); - sprintf(str, "%d", adjFan[1]); - _printMenuText(col3, yPos, str, _rowSel == 5, eRightJustify); - // navigation line - yPos = 53; - _printMenuText(_display.xCentre(), yPos, "<- ->", false, eCentreJustify); - break; + case 1: + _printMenuText(_display.xCentre(), 34, "Enter password...", false, eCentreJustify); + _showPassword(); + break; - case 6: - _printMenuText(_display.xCentre(), 35, "Press UP to", false, eCentreJustify); - _printMenuText(_display.xCentre(), 43, "confirm save", false, eCentreJustify); - break; + case 2: + case 3: + case 4: + case 5: + _display.clearDisplay(); + // Pump Minimum adjustment + yPos = border + 36; + _printMenuText(80, yPos, "Min", false, eRightJustify); + sprintf(str, "%.1f", adjPump[0]); + _printMenuText(col3, yPos, str, _rowSel == 2, eRightJustify); + // Pump Maximum adjustment + yPos = border + 24; + _printMenuText(80, yPos, "Pump Hz Max", false, eRightJustify); + sprintf(str, "%.1f", adjPump[1]); + _printMenuText(col3, yPos, str, _rowSel == 3, eRightJustify); + // Fan Minimum adjustment + yPos = border + 12; + _printMenuText(80, yPos, "Min", false, eRightJustify); + sprintf(str, "%d", adjFan[0]); + _printMenuText(col3, yPos, str, _rowSel == 4, eRightJustify); + // Fan Maximum adjustment + yPos = border; + _printMenuText(80, yPos, "Fan RPM Max", false, eRightJustify); + sprintf(str, "%d", adjFan[1]); + _printMenuText(col3, yPos, str, _rowSel == 5, eRightJustify); + // navigation line + yPos = 53; + _printMenuText(_display.xCentre(), yPos, "<- ->", false, eCentreJustify); + break; + + case 6: + _printMenuText(_display.xCentre(), 35, "Press UP to", false, eCentreJustify); + _printMenuText(_display.xCentre(), 43, "confirm save", false, eCentreJustify); + break; + } } // _display.display(); @@ -223,12 +234,14 @@ CFuelMixtureScreen::keyHandler(uint8_t event) ROLLUPPERLIMIT(_PWdig[_colSel], 9, 0); break; case 6: + _SaveTime = millis() + 1500; setPumpMin(adjPump[0]); setPumpMax(adjPump[1]); setFanMin(adjFan[0]); setFanMax(adjFan[1]); saveNV(); _rowSel = 0; + _ScreenManager.reqUpdate(); break; } } diff --git a/Arduino/BTCDieselHeater/src/OLED/FuelMixtureScreen.h b/Arduino/BTCDieselHeater/src/OLED/FuelMixtureScreen.h index 2a925af..159f7aa 100644 --- a/Arduino/BTCDieselHeater/src/OLED/FuelMixtureScreen.h +++ b/Arduino/BTCDieselHeater/src/OLED/FuelMixtureScreen.h @@ -32,6 +32,7 @@ class CFuelMixtureScreen : public CScreenHeader { short adjFan[2]; int _rowSel; int _colSel; + unsigned long _SaveTime; void _showPassword(); void _adjustSetting(int dir); diff --git a/Arduino/BTCDieselHeater/src/OLED/HeaterSettingsScreen.cpp b/Arduino/BTCDieselHeater/src/OLED/HeaterSettingsScreen.cpp new file mode 100644 index 0000000..292df8b --- /dev/null +++ b/Arduino/BTCDieselHeater/src/OLED/HeaterSettingsScreen.cpp @@ -0,0 +1,138 @@ +/* + * This file is part of the "bluetoothheater" distribution + * (https://gitlab.com/mrjones.id.au/bluetoothheater) + * + * Copyright (C) 2018 Ray Jones + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "128x64OLED.h" +#include "HeaterSettingsScreen.h" +#include "KeyPad.h" +#include "../Protocol/helpers.h" +#include "../Utility/UtilClasses.h" + + +/////////////////////////////////////////////////////////////////////////// +// +// CHeaterSettingsScreen +// +// This screen provides a basic control function +// +/////////////////////////////////////////////////////////////////////////// + +CHeaterSettingsScreen::CHeaterSettingsScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreenHeader(display, mgr) +{ + _rowSel = 0; + _SaveTime = 0; + _fanSensor = 1; + _glowPower = 5; + _sysVoltage = 12; +} + +void +CHeaterSettingsScreen::show() +{ + char msg[20]; + int xPos, yPos; + _display.clearDisplay(); + + _printInverted(0, 0, " Heater Settings ", true); + + if(_SaveTime) { + long tDelta = millis() - _SaveTime; + if(tDelta > 0) + _SaveTime = 0; + _printInverted(_display.xCentre(), 28, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 39, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 34, " STORING ", true, eCentreJustify); + } + else { + yPos = 14; + _printMenuText(98, yPos, "Glow plug power:", false, eRightJustify); + sprintf(msg, "PF-%d", _glowPower); + _printMenuText(100, yPos, msg, _rowSel == 3); + yPos = 27; + _printMenuText(98, yPos, "Fan sensor:", false, eRightJustify); + sprintf(msg, "SN-%d", _fanSensor); + _printMenuText(100, yPos, msg, _rowSel == 2); + yPos = 40; + _printMenuText(98, yPos, "System voltage:", false, eRightJustify); + sprintf(msg, "%dV", _sysVoltage); + _printMenuText(100, yPos, msg, _rowSel == 1); + // navigation line + yPos = 53; + xPos = _display.xCentre(); + _printMenuText(xPos, yPos, "<- ->", _rowSel == 0, eCentreJustify); + } +} + + +void +CHeaterSettingsScreen::keyHandler(uint8_t event) +{ + if(event & keyPressed) { + // press LEFT to select previous screen, or Fixed Hz mode when in mode select + if(event & key_Left) { + if(_rowSel == 0) + _ScreenManager.prevScreen(); + else { + _adjust(-1); + } + } + // press RIGHT to selecxt next screen, or Thermostat mode when in mode select + if(event & key_Right) { + if(_rowSel == 0) + _ScreenManager.nextScreen(); + else { + _adjust(+1); + } + } + if(event & key_Down) { + _rowSel--; + LOWERLIMIT(_rowSel, 1); + } + if(event & key_Up) { + _rowSel++; + UPPERLIMIT(_rowSel, 3); + } + if(event & key_Centre) { + if(_rowSel) { + _SaveTime = millis() + 1500; + _ScreenManager.reqUpdate(); + _rowSel = 0; + } + } + } +} + +void +CHeaterSettingsScreen::_adjust(int dir) +{ + switch(_rowSel) { + case 1: // system voltage + _sysVoltage = (_sysVoltage == 12) ? 24 : 12; + break; + case 2: // fan sensor + _fanSensor = (_fanSensor == 1) ? 2 : 1; + break; + case 3: // glow power + _glowPower += dir; + UPPERLIMIT(_glowPower, 6); + LOWERLIMIT(_glowPower, 1); + break; + } +} diff --git a/Arduino/BTCDieselHeater/src/OLED/HeaterSettingsScreen.h b/Arduino/BTCDieselHeater/src/OLED/HeaterSettingsScreen.h new file mode 100644 index 0000000..c0a2193 --- /dev/null +++ b/Arduino/BTCDieselHeater/src/OLED/HeaterSettingsScreen.h @@ -0,0 +1,40 @@ +/* + * This file is part of the "bluetoothheater" distribution + * (https://gitlab.com/mrjones.id.au/bluetoothheater) + * + * Copyright (C) 2018 Ray Jones + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include "ScreenHeader.h" + +class C128x64_OLED; +class CScreenManager; + +class CHeaterSettingsScreen : public CScreenHeader +{ + int _rowSel; + unsigned long _SaveTime; + void _adjust(int dir); + int _sysVoltage; + int _fanSensor; + int _glowPower; +public: + CHeaterSettingsScreen(C128x64_OLED& display, CScreenManager& mgr); + void show(); + void keyHandler(uint8_t event); +}; diff --git a/Arduino/BTCDieselHeater/src/OLED/PasswordScreen.cpp b/Arduino/BTCDieselHeater/src/OLED/PasswordScreen.cpp new file mode 100644 index 0000000..56c7ee1 --- /dev/null +++ b/Arduino/BTCDieselHeater/src/OLED/PasswordScreen.cpp @@ -0,0 +1,183 @@ +/* + * This file is part of the "bluetoothheater" distribution + * (https://gitlab.com/mrjones.id.au/bluetoothheater) + * + * Copyright (C) 2018 Ray Jones + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +/////////////////////////////////////////////////////////////////////////// +// +// CPasswordScreen +// +// This class allows a password entry page to pop up +// +/////////////////////////////////////////////////////////////////////////// + +#include "PasswordScreen.h" +#include "KeyPad.h" +#include "../Protocol/helpers.h" +#include "../Wifi/BTCWifi.h" +#include "fonts/Arial.h" + + +CPasswordScreen::CPasswordScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreenHeader(display, mgr) +{ + _bGetPassword = false; + _bPasswordOK = false; + _PWcol = 0; + for(int i= 0; i < 4; i++) + _PWdig[i] = -1; + _SaveTime = 0; +} + + +void +CPasswordScreen::show() +{ + CScreenHeader::show(); + + char str[16]; + int xPos, yPos; + const int col2 = 90; + const int col3 = _display.width() - border; + _printInverted(0, 16, _Title, true); + + if(_SaveTime) { + long tDelta = millis() - _SaveTime; + if(tDelta > 0) + _SaveTime = 0; + _printInverted(_display.xCentre(), 28, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 39, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 34, " STORING ", true, eCentreJustify); + } + else { + + if(_bGetPassword) { + _printMenuText(_display.xCentre(), 34, "Enter password...", false, eCentreJustify); + _showPassword(); + } + } +} + + +void +CPasswordScreen::keyHandler(uint8_t event) +{ + if(_bGetPassword) { + if(event & keyPressed) { + + // press CENTRE + if(event & key_Centre) { + // match "1688" + if((_PWdig[0] == 1) && + (_PWdig[1] == 6) && + (_PWdig[2] == 8) && + (_PWdig[3] == 8)) { + _bPasswordOK = true; + } + // reset PW digits + for(int i= 0; i < 4; i++) + _PWdig[i] = -1; + + return; + } + + // press LEFT + if(event & key_Left) { + _PWcol--; + LOWERLIMIT(_PWcol, 0); + } + + // press RIGHT + if(event & key_Right) { + _PWcol++; + UPPERLIMIT(_PWcol, 5); + } + + // press UP + if(event & key_Up) { + _PWdig[_PWcol]++; + ROLLUPPERLIMIT(_PWdig[_PWcol], 9, 0); + } + + // press DOWN + if(event & key_Down) { + _PWdig[_PWcol]--; + ROLLLOWERLIMIT(_PWdig[_PWcol], 0, 9); + } + _ScreenManager.reqUpdate(); + } + } +} + +bool +CPasswordScreen::_showPassword() +{ + if(_bGetPassword) { + _printMenuText(_display.xCentre(), 34, "Enter password...", false, eCentreJustify); + + // determine metrics of character sizing + CRect extents; + _display.getTextExtents("X", extents); + int charWidth = extents.width; + _display.getTextExtents(" ", extents); + int spaceWidth = extents.width; + + for(int idx =0 ; idx < 4; idx++) { + + extents.xPos = _display.xCentre() - (2 - idx) * (charWidth * 1.5); + extents.yPos = 50; + + char str[8]; + + if(_PWdig[idx] < 0) { + strcpy(str, "-"); + } + else { + sprintf(str, "%d", _PWdig[idx]); + } + _printMenuText(extents.xPos, extents.yPos, str, _PWcol == idx); + } + } + return _bGetPassword; +} + +void +CPasswordScreen::_setGetPassword(bool state) +{ + _bGetPassword = state; + if(state) { + _bPasswordOK = false; + _PWcol = 0; + // reset PW digits + for(int i= 0; i < 4; i++) + _PWdig[i] = -1; + } +} + +void +CPasswordScreen::_setTitle(const char* title) +{ + strcpy(_Title, title); +} + +bool +CPasswordScreen::_isPasswordOK() +{ + return _bPasswordOK; +} diff --git a/Arduino/BTCDieselHeater/src/OLED/PasswordScreen.h b/Arduino/BTCDieselHeater/src/OLED/PasswordScreen.h new file mode 100644 index 0000000..c6dadce --- /dev/null +++ b/Arduino/BTCDieselHeater/src/OLED/PasswordScreen.h @@ -0,0 +1,46 @@ +/* + * This file is part of the "bluetoothheater" distribution + * (https://gitlab.com/mrjones.id.au/bluetoothheater) + * + * Copyright (C) 2018 Ray Jones + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include "ScreenHeader.h" + +class C128x64_OLED; +class CScreenManager; +class CProtocol; + +class CPasswordScreen : public CScreenHeader { + int _PWdig[4]; + bool _bGetPassword; + bool _bPasswordOK; + int _PWcol; + unsigned long _SaveTime; + char _Title[20]; +protected: + bool _showPassword(); + void _setGetPassword(bool state); + void _setTitle(const char* title); + bool _isPasswordOK(); +public: + CPasswordScreen(C128x64_OLED& display, CScreenManager& mgr); + void show(); + void keyHandler(uint8_t event); + bool animate() { return CScreen::animate(); }; +}; diff --git a/Arduino/BTCDieselHeater/src/OLED/ScreenManager.cpp b/Arduino/BTCDieselHeater/src/OLED/ScreenManager.cpp index dc3bc14..bbc068d 100644 --- a/Arduino/BTCDieselHeater/src/OLED/ScreenManager.cpp +++ b/Arduino/BTCDieselHeater/src/OLED/ScreenManager.cpp @@ -8,6 +8,7 @@ #include "SetTimerScreen.h" #include "ClockScreen.h" #include "RebootScreen.h" +#include "HeaterSettingsScreen.h" #include #include "../cfg/pins.h" #include "../cfg/BTCConfig.h" @@ -149,12 +150,13 @@ CScreenManager::begin() _pDisplay->display(); DebugPort.println("Creating Screens"); - _Screens.push_back(new CDetailedScreen(*_pDisplay, *this)); // 0: detail control - _Screens.push_back(new CBasicScreen(*_pDisplay, *this)); // 1: basic control - _Screens.push_back(new CClockScreen(*_pDisplay, *this)); // 2: clock - _Screens.push_back(new CPrimingScreen(*_pDisplay, *this)); // 3: mode / priming - _Screens.push_back(new CWiFiScreen(*_pDisplay, *this)); // 4: comms info - _Screens.push_back(new CFuelMixtureScreen(*_pDisplay, *this)); // 5: tuning + _Screens.push_back(new CDetailedScreen(*_pDisplay, *this)); // detail control + _Screens.push_back(new CBasicScreen(*_pDisplay, *this)); // basic control + _Screens.push_back(new CClockScreen(*_pDisplay, *this)); // clock + _Screens.push_back(new CPrimingScreen(*_pDisplay, *this)); // mode / priming + _Screens.push_back(new CWiFiScreen(*_pDisplay, *this)); // comms info + _Screens.push_back(new CFuelMixtureScreen(*_pDisplay, *this)); // tuning + _Screens.push_back(new CHeaterSettingsScreen(*_pDisplay, *this)); // tuning _SetTimeScreen = new CSetClockScreen(*_pDisplay, *this); // clock set _TimerScreens.push_back(new CSetTimerScreen(*_pDisplay, *this, 0)); // set timer 1 _TimerScreens.push_back(new CSetTimerScreen(*_pDisplay, *this, 1)); // set timer 2 diff --git a/Arduino/BTCDieselHeater/src/OLED/SetClockScreen.cpp b/Arduino/BTCDieselHeater/src/OLED/SetClockScreen.cpp index 27cd503..e030890 100644 --- a/Arduino/BTCDieselHeater/src/OLED/SetClockScreen.cpp +++ b/Arduino/BTCDieselHeater/src/OLED/SetClockScreen.cpp @@ -39,6 +39,7 @@ CSetClockScreen::CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr) : C { _rowSel = 0; _nextT = millis(); + _SaveTime = 0; } void @@ -69,39 +70,50 @@ CSetClockScreen::show() working = now; // DELIBERATE DROP THROUGH HERE } - yPos = 28; - xPos = 6; - // date - if(_rowSel==0) { - xPos = 20; - _printMenuText(xPos, yPos, working.dowStr()); - } - sprintf(str, "%d", working.day()); - xPos += 20 + 12; - _printMenuText(xPos, yPos, str, _rowSel==1, eRightJustify); - xPos += 4; - _printMenuText(xPos, yPos, working.monthStr(), _rowSel==2); - xPos += 22; - sprintf(str, "%d", working.year()); - _printMenuText(xPos, yPos, str, _rowSel==3); - // time - yPos = 40; - xPos = 26; - sprintf(str, "%02d", working.hour()); - _printMenuText(xPos, yPos, str, _rowSel==4); - xPos += 16; - _printMenuText(xPos, yPos, ":"); - xPos += 8; - sprintf(str, "%02d", working.minute()); - _printMenuText(xPos, yPos, str, _rowSel==5); - xPos += 16; - _printMenuText(xPos, yPos, ":"); - sprintf(str, "%02d", working.second()); - xPos += 8; - _printMenuText(xPos, yPos, str, _rowSel==6); - if(_rowSel>=1) - _printMenuText(_display.width()-border, yPos, "SET", _rowSel==7, eRightJustify); + if(_SaveTime) { + long tDelta = millis() - _SaveTime; + if(tDelta > 0) + _SaveTime = 0; + _printInverted(_display.xCentre(), 28, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 39, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 34, " STORING ", true, eCentreJustify); + } + else { + yPos = 28; + xPos = 6; + // date + if(_rowSel==0) { + xPos = 20; + _printMenuText(xPos, yPos, working.dowStr()); + } + + sprintf(str, "%d", working.day()); + xPos += 20 + 12; + _printMenuText(xPos, yPos, str, _rowSel==1, eRightJustify); + xPos += 4; + _printMenuText(xPos, yPos, working.monthStr(), _rowSel==2); + xPos += 22; + sprintf(str, "%d", working.year()); + _printMenuText(xPos, yPos, str, _rowSel==3); + // time + yPos = 40; + xPos = 26; + sprintf(str, "%02d", working.hour()); + _printMenuText(xPos, yPos, str, _rowSel==4); + xPos += 16; + _printMenuText(xPos, yPos, ":"); + xPos += 8; + sprintf(str, "%02d", working.minute()); + _printMenuText(xPos, yPos, str, _rowSel==5); + xPos += 16; + _printMenuText(xPos, yPos, ":"); + sprintf(str, "%02d", working.second()); + xPos += 8; + _printMenuText(xPos, yPos, str, _rowSel==6); + if(_rowSel>=1) + _printMenuText(_display.width()-border, yPos, "SET", _rowSel==7, eRightJustify); + } // navigation line yPos = 53; xPos = _display.xCentre(); @@ -124,6 +136,7 @@ CSetClockScreen::keyHandler(uint8_t event) else { if(_rowSel == 7) { // set the RTC! Clock.set(working); + _SaveTime = millis() + 1500; } _rowSel = 0; } diff --git a/Arduino/BTCDieselHeater/src/OLED/SetClockScreen.h b/Arduino/BTCDieselHeater/src/OLED/SetClockScreen.h index beb4aaf..9ab2870 100644 --- a/Arduino/BTCDieselHeater/src/OLED/SetClockScreen.h +++ b/Arduino/BTCDieselHeater/src/OLED/SetClockScreen.h @@ -31,6 +31,7 @@ class CSetClockScreen : public CScreenHeader { int _rowSel; unsigned long _nextT; BTCDateTime working; + unsigned long _SaveTime; void adjTimeDate(int dir); diff --git a/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.cpp b/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.cpp index 761ce08..2aa2829 100644 --- a/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.cpp +++ b/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.cpp @@ -40,6 +40,7 @@ CSetTimerScreen::CSetTimerScreen(C128x64_OLED& display, CScreenManager& mgr, int { _rowSel = 0; _colSel = 0; + _SaveTime = 0; _instance = instance; } @@ -60,9 +61,18 @@ CSetTimerScreen::show() if(_rowSel == 0) { NVstore.getTimerInfo(_instance, _timer); } - sprintf(str, " Timer %d ", _instance + 1); + sprintf(str, " Set Timer %d ", _instance + 1); _printInverted(0, 16, str, true); + if(_SaveTime) { + long tDelta = millis() - _SaveTime; + if(tDelta > 0) + _SaveTime = 0; + _printInverted(_display.xCentre(), 28, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 39, " ", true, eCentreJustify); + _printInverted(_display.xCentre(), 34, " STORING ", true, eCentreJustify); + } + else { // start xPos = 18; yPos = 28; @@ -101,7 +111,7 @@ CSetTimerScreen::show() _printMenuText(xPos, yPos, msg, _colSel==5, eRightJustify); else _printInverted(xPos, yPos, msg, _timer.repeat, eRightJustify); - + } // navigation line yPos = 53; xPos = _display.xCentre(); @@ -122,10 +132,15 @@ CSetTimerScreen::keyHandler(uint8_t event) if(_rowSel == 0) { _ScreenManager.selectTimerScreen(false); // exit: return to clock screen } - else { + else if(_rowSel == 2) { // exit from per day settings + _rowSel = 1; + } + else { // in config fields, save new settings + _SaveTime = millis() + 1500; NVstore.setTimerInfo(_instance, _timer); NVstore.save(); _rowSel = 0; + _ScreenManager.reqUpdate(); } return; } @@ -135,10 +150,6 @@ CSetTimerScreen::keyHandler(uint8_t event) case 0: _ScreenManager.prevScreen(); break; - case 1: - _colSel--; - ROLLLOWERLIMIT(_colSel, 0, 5); - break; case 2: _colSel--; ROLLLOWERLIMIT(_colSel, 0, 6); @@ -151,20 +162,28 @@ CSetTimerScreen::keyHandler(uint8_t event) case 0: _ScreenManager.nextScreen(); break; - case 1: - _colSel++; - ROLLUPPERLIMIT(_colSel, 5, 0); - break; + // case 1: + // _colSel++; + // ROLLUPPERLIMIT(_colSel, 5, 0); + // break; case 2: _colSel++; ROLLUPPERLIMIT(_colSel, 6, 0); break; } } - // press DOWN - return - only on row 0 + // press UP + if(event & key_Up) { + if(_rowSel == 1) { + _colSel++; + ROLLUPPERLIMIT(_colSel, 5, 0); + } + } + // press DOWN if(event & key_Down) { - if(_rowSel == 0) { - _ScreenManager.selectTimerScreen(false); // exit: return to clock screen + if(_rowSel == 1) { + _colSel--; + ROLLLOWERLIMIT(_colSel, 0, 5); } } } @@ -174,11 +193,11 @@ CSetTimerScreen::keyHandler(uint8_t event) bHeld = true; if(_rowSel == 1) { if(_colSel < 4) { - if(event & key_Down) adjust(-1); - if(event & key_Up) adjust(+1); + if(event & key_Left) adjust(-1); + if(event & key_Right) adjust(+1); } else if(_colSel == 4) { - if(event & key_Up) { + if(event & key_Right) { _timer.enabled &= 0x7f; // strip next day flag _rowSel = 2; _colSel = 0; @@ -195,14 +214,23 @@ CSetTimerScreen::keyHandler(uint8_t event) if(event & keyReleased) { if(!bHeld) { - // released DOWN - can only leave adjustment by using OK (centre button) int maskDOW = 0x01 << _colSel; - if(event & key_Down) { - // adjust selected item + + if(event & key_Left) { switch(_rowSel) { case 1: adjust(-1); break; + } + } + + // released DOWN - can only leave adjustment by using OK (centre button) + if(event & key_Down) { + // adjust selected item + switch(_rowSel) { + // case 1: + // adjust(-1); + // break; case 2: // adjust selected item _timer.enabled ^= maskDOW; @@ -210,6 +238,14 @@ CSetTimerScreen::keyHandler(uint8_t event) break; } } + if(event & key_Right) { + switch(_rowSel) { + case 1: + // adjust selected item + adjust(+1); + break; + } + } // released UP if(event & key_Up) { switch(_rowSel) { @@ -218,10 +254,10 @@ CSetTimerScreen::keyHandler(uint8_t event) _rowSel = 1; _colSel = 0; break; - case 1: - // adjust selected item - adjust(+1); - break; + // case 1: + // // adjust selected item + // adjust(+1); + // break; case 2: // adjust selected item _timer.enabled ^= maskDOW; @@ -297,7 +333,7 @@ CSetTimerScreen::_printEnabledTimers() } else { if(_rowSel==1 && _colSel==4) { - _printMenuText(xPos, yPos, "Hold UP", true, eRightJustify); + _printMenuText(xPos, yPos, "Hold RIGHT", true, eRightJustify); } else { xPos -= 7 * dayWidth; // back step 7 day entries diff --git a/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.h b/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.h index f40cc01..bc39dbd 100644 --- a/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.h +++ b/Arduino/BTCDieselHeater/src/OLED/SetTimerScreen.h @@ -31,6 +31,7 @@ class CSetTimerScreen : public CScreenHeader { int _rowSel; int _colSel; int _instance; + unsigned long _SaveTime; sTimer _timer; void adjust(int dir); void _printEnabledTimers(); diff --git a/Arduino/BTCDieselHeater/src/Utility/NVStorage.cpp b/Arduino/BTCDieselHeater/src/Utility/NVStorage.cpp index 5e1c41d..ac14c16 100644 --- a/Arduino/BTCDieselHeater/src/Utility/NVStorage.cpp +++ b/Arduino/BTCDieselHeater/src/Utility/NVStorage.cpp @@ -24,6 +24,7 @@ #include "DebugPort.h" bool u8inBounds(uint8_t test, uint8_t minLim, uint8_t maxLim); +bool s8inBounds(int8_t test, int8_t minLim, int8_t maxLim); bool u8Match2(uint8_t test, uint8_t test1, uint8_t test2); bool u16inBounds(uint16_t test, uint16_t minLim, uint16_t maxLim); bool s32inBounds(long test, long minLim, long maxLim); @@ -268,10 +269,10 @@ CESP32HeaterStorage::loadTimer(int idx) char SectionName[16]; sprintf(SectionName, "timer%d", idx+1); preferences.begin(SectionName, false); - validatedLoad("startHour", timer.start.hour, 0, u8inBounds, 0, 23); - validatedLoad("startMin", timer.start.min, 0, u8inBounds, 0, 59); - validatedLoad("stopHour", timer.stop.hour, 0, u8inBounds, 0, 23); - validatedLoad("stopMin", timer.stop.min, 0, u8inBounds, 0, 59); + validatedLoad("startHour", timer.start.hour, 0, s8inBounds, 0, 23); + validatedLoad("startMin", timer.start.min, 0, s8inBounds, 0, 59); + validatedLoad("stopHour", timer.stop.hour, 0, s8inBounds, 0, 23); + validatedLoad("stopMin", timer.stop.min, 0, s8inBounds, 0, 59); validatedLoad("enabled", timer.enabled, 0, u8inBounds, 0, 255); // all 8 bits used! validatedLoad("repeat", timer.repeat, 0, u8inBounds, 0, 1); preferences.end(); @@ -284,10 +285,10 @@ CESP32HeaterStorage::saveTimer(int idx) char SectionName[16]; sprintf(SectionName, "timer%d", idx+1); preferences.begin(SectionName, false); - preferences.putUChar("startHour", timer.start.hour); - preferences.putUChar("startMin", timer.start.min); - preferences.putUChar("stopHour", timer.stop.hour); - preferences.putUChar("stopMin", timer.stop.min); + preferences.putChar("startHour", timer.start.hour); + preferences.putChar("startMin", timer.start.min); + preferences.putChar("stopHour", timer.stop.hour); + preferences.putChar("stopMin", timer.stop.min); preferences.putUChar("enabled", timer.enabled); preferences.putUChar("repeat", timer.repeat); preferences.end(); @@ -327,6 +328,24 @@ CESP32HeaterStorage::validatedLoad(const char* key, uint8_t& val, int defVal, st return true; } +bool +CESP32HeaterStorage::validatedLoad(const char* key, int8_t& val, int defVal, std::function validator, int min, int max) +{ + val = preferences.getChar(key, defVal); + if(!validator(val, min, max)) { + + DebugPort.print("CESP32HeaterStorage::validatedLoad invalid read "); + DebugPort.print(key); DebugPort.print("="); DebugPort.print(val); + DebugPort.print(" validator("); DebugPort.print(min); DebugPort.print(","); DebugPort.print(max); DebugPort.print(") reset to "); + DebugPort.println(defVal); + + val = defVal; + preferences.putChar(key, val); + return false; + } + return true; +} + bool CESP32HeaterStorage::validatedLoad(const char* key, uint16_t& val, int defVal, std::function validator, int min, int max) { @@ -368,6 +387,11 @@ bool u8inBounds(uint8_t test, uint8_t minLim, uint8_t maxLim) return (test >= minLim) && (test <= maxLim); } +bool s8inBounds(int8_t test, int8_t minLim, int8_t maxLim) +{ + return (test >= minLim) && (test <= maxLim); +} + bool u8Match2(uint8_t test, uint8_t test1, uint8_t test2) { return (test == test1) || (test == test2); diff --git a/Arduino/BTCDieselHeater/src/Utility/NVStorage.h b/Arduino/BTCDieselHeater/src/Utility/NVStorage.h index 6c654e9..681ac34 100644 --- a/Arduino/BTCDieselHeater/src/Utility/NVStorage.h +++ b/Arduino/BTCDieselHeater/src/Utility/NVStorage.h @@ -60,8 +60,8 @@ struct sHeater { }; struct sHourMin { - uint8_t hour; - uint8_t min; + int8_t hour; + int8_t min; sHourMin() { hour = 0; min = 0; @@ -184,6 +184,7 @@ public: void saveTimer(int idx); void loadUI(); void saveUI(); + bool validatedLoad(const char* key, int8_t& val, int defVal, std::function validator, int min, int max); bool validatedLoad(const char* key, uint8_t& val, int defVal, std::function validator, int min, int max); bool validatedLoad(const char* key, uint16_t& val, int defVal, std::function validator, int min, int max); bool validatedLoad(const char* key, long& val, long defVal, std::function validator, long min, long max);