diff --git a/Arduino/BTCDieselHeater/src/OLED/Screen4.cpp b/Arduino/BTCDieselHeater/src/OLED/Screen4.cpp index 57163b3..f850230 100644 --- a/Arduino/BTCDieselHeater/src/OLED/Screen4.cpp +++ b/Arduino/BTCDieselHeater/src/OLED/Screen4.cpp @@ -37,9 +37,11 @@ // /////////////////////////////////////////////////////////////////////////// +#define STA_HOLD_TIME 10 CScreen4::CScreen4(C128x64_OLED& display, CScreenManager& mgr) : CScreenHeader(display, mgr) { + _rowSel = 0; } @@ -50,31 +52,39 @@ CScreen4::show() int yPos = 16; if(isWifiConnected() || isWifiAP()) { - if(isWifiAP()) { - _printInverted(0, yPos, " WiFi: AP only ", true); - } - else { - _printInverted(0, yPos, " WiFi: STA+AP ", true); - } - // only show STA IP address if available! - if(isWifiSTA()) { - yPos += _display.textHeight() + 2; - _printMenuText(0, yPos, "STA:"); - _printMenuText(25, yPos, getWifiSTAAddrStr()); - } + + const char* pTitle = NULL; + if(isWifiAP()) + pTitle = isWifiConfigPortal() ? " WiFi: CFG AP only " : " WiFi: AP only "; + else + pTitle = isWifiConfigPortal() ? " WiFi: CFG STA+AP " : " WiFi: STA+AP "; + + if(_rowSel == 1) + _printMenuText(3, yPos, pTitle, true); // selection box + else + _printInverted(3, yPos, pTitle, true); // inverted title bar + yPos += 3; + // show AP IP address yPos += _display.textHeight() + 2; _printMenuText(0, yPos, " AP:"); _printMenuText(25, yPos, getWifiAPAddrStr()); + // only show STA IP address if available! + if(isWifiSTA() && _repeatCount <= STA_HOLD_TIME) { + yPos += _display.textHeight() + 2; + _printMenuText(0, yPos, "STA:"); + _printMenuText(25, yPos, getWifiSTAAddrStr()); + } } else { _printInverted(0, yPos, " WiFi Inactive ", true); } - yPos += _display.textHeight() + 2; + +/* yPos += _display.textHeight() + 2; char msg[32]; int mins = NVstore.getDimTime() / 60000; sprintf(msg, "Display Dim: %d min%c", mins, (mins > 1) ? 's' : ' '); - _printMenuText(0, yPos, msg); + _printMenuText(0, yPos, msg);*/ } @@ -82,18 +92,57 @@ void CScreen4::keyHandler(uint8_t event) { if(event & keyPressed) { + _repeatCount = 0; // press CENTRE if(event & key_Centre) { - return; } // press LEFT if(event & key_Left) { _ScreenManager.prevScreen(); + _rowSel = 0; } // press RIGHT if(event & key_Right) { _ScreenManager.nextScreen(); + _rowSel = 0; } + // press UP + if(event & key_Up) { + _rowSel = 1; + // _rowSel++; + // UPPERLIMIT(_rowSel, (isWifiConfigPortal() ? 2 : 1)); + } + // press DOWN + if(event & key_Down) { + _rowSel = 0; + // _rowSel--; + // UPPERLIMIT(_rowSel, 0); + } + _ScreenManager.reqUpdate(); + } + + if(event & keyRepeat) { // track key hold time + _repeatCount++; + } + + if(event & keyReleased) { + if(event & key_Centre) { + if(_rowSel) { + + if(_repeatCount > STA_HOLD_TIME) { + wifiEnterConfigPortal(true, _repeatCount > STA_HOLD_TIME, 5000); // press - reboot into portal, long press - erase credentials + } + else { + if(isWifiConfigPortal()) { + wifiEnterConfigPortal(false, false, 5000); // stop config portal, reboot + } + else { + wifiEnterConfigPortal(true, false, 5000); // stop config portal, reboot + } + } + } + } + _repeatCount = 0; } } diff --git a/Arduino/BTCDieselHeater/src/OLED/Screen4.h b/Arduino/BTCDieselHeater/src/OLED/Screen4.h index 8577bd7..5380356 100644 --- a/Arduino/BTCDieselHeater/src/OLED/Screen4.h +++ b/Arduino/BTCDieselHeater/src/OLED/Screen4.h @@ -30,4 +30,7 @@ public: CScreen4(C128x64_OLED& display, CScreenManager& mgr); void show(); void keyHandler(uint8_t event); +private: + int _rowSel; + int _repeatCount; }; diff --git a/Arduino/BTCDieselHeater/src/OLED/ScreenHeader.cpp b/Arduino/BTCDieselHeater/src/OLED/ScreenHeader.cpp index 44673e2..e600851 100644 --- a/Arduino/BTCDieselHeater/src/OLED/ScreenHeader.cpp +++ b/Arduino/BTCDieselHeater/src/OLED/ScreenHeader.cpp @@ -128,7 +128,7 @@ CScreenHeader::showWifiIcon() { if(isWifiConnected() || isWifiAP()) { _display.drawBitmap(X_WIFI_ICON, Y_WIFI_ICON, wifiIcon, W_WIFI_ICON, H_WIFI_ICON, WHITE); - if(isConfigPortal()) { + if(isWifiConfigPortal()) { _display.fillRect(X_WIFI_ICON + 8, Y_WIFI_ICON + 5, 15, 7, BLACK); CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font _display.setCursor(X_WIFI_ICON+9, Y_WIFI_ICON+6); diff --git a/Arduino/BTCDieselHeater/src/OLED/ScreenManager.cpp b/Arduino/BTCDieselHeater/src/OLED/ScreenManager.cpp index b8e77cc..968642c 100644 --- a/Arduino/BTCDieselHeater/src/OLED/ScreenManager.cpp +++ b/Arduino/BTCDieselHeater/src/OLED/ScreenManager.cpp @@ -7,6 +7,7 @@ #include "Screen6.h" #include "Screen7.h" #include "Screen8.h" +#include "RebootScreen.h" #include #include "../cfg/pins.h" #include "../cfg/BTCConfig.h" @@ -96,6 +97,7 @@ CScreenManager::CScreenManager() _currentScreen = -1; _bReqUpdate = false; _DimTime = millis() + 60000; + _pRebootScreen = NULL; } CScreenManager::~CScreenManager() @@ -167,10 +169,17 @@ CScreenManager::checkUpdate() } if(_bReqUpdate) { - if(_currentScreen >= 0) { - _Screens[_currentScreen]->show(); + if(_pRebootScreen) { + _pRebootScreen->show(); _bReqUpdate = false; - return true; + return true; + } + else { + if(_currentScreen >= 0) { + _Screens[_currentScreen]->show(); + _bReqUpdate = false; + return true; + } } } return false; @@ -235,11 +244,18 @@ CScreenManager::keyHandler(uint8_t event) if(_DimTime == 0) _pDisplay->dim(false); -// _DimTime = millis() + NVstore.getDimTime(); - _DimTime = millis() + 60000; - if(_DimTime == 0) - _DimTime = 1; + _DimTime = (millis() + NVstore.getDimTime()) | 1; +// _DimTime = (millis() + 60000) | 1; } - \ No newline at end of file +void +CScreenManager::showRebootMsg(const char* content[2], long delayTime) +{ + if(_pRebootScreen == NULL) + _pRebootScreen = new CRebootScreen(*_pDisplay, *this); + + _pRebootScreen->setMessage(content, delayTime); + _bReqUpdate = true; + _pDisplay->dim(false); +} diff --git a/Arduino/BTCDieselHeater/src/OLED/ScreenManager.h b/Arduino/BTCDieselHeater/src/OLED/ScreenManager.h index c776b82..e200eef 100644 --- a/Arduino/BTCDieselHeater/src/OLED/ScreenManager.h +++ b/Arduino/BTCDieselHeater/src/OLED/ScreenManager.h @@ -28,6 +28,7 @@ class CProtocol; class C128x64_OLED; class CScreen; +class CRebootScreen; class CScreenManager { std::vector _Screens; @@ -36,6 +37,7 @@ class CScreenManager { unsigned long _DimTime; bool _bReqUpdate; void _switchScreen(); + CRebootScreen* _pRebootScreen; public: CScreenManager(); ~CScreenManager(); @@ -47,6 +49,7 @@ public: void prevScreen(); void keyHandler(uint8_t event); void reqUpdate(); + void showRebootMsg(const char* content[2], long delayTime); }; #endif // __SCREEN_MANAGER_H__ diff --git a/Arduino/BTCDieselHeater/src/WiFi/BTCWebServer.cpp b/Arduino/BTCDieselHeater/src/WiFi/BTCWebServer.cpp index a5663cd..c3149ec 100644 --- a/Arduino/BTCDieselHeater/src/WiFi/BTCWebServer.cpp +++ b/Arduino/BTCDieselHeater/src/WiFi/BTCWebServer.cpp @@ -47,24 +47,22 @@ void handleBTCRoot() { } void handleWMConfig() { + server.send(200, "text/plain", "Start Config Portal - Retaining credential"); DebugPort.println("Starting web portal for wifi config"); - wm.startWebPortal(); + delay(500); +// wm.startWebPortal(); + wifiEnterConfigPortal(true, false, 3000); } void handleReset() { - server.send(200, "text/plain", "Resetting Wifi Settings!"); + server.send(200, "text/plain", "Start Config Portal - Resetting Wifi credentials!"); DebugPort.println("diconnecting client and wifi, then rebooting"); + delay(500); //client.disconnect(); // wifi_station_disconnect(); - wm.disconnect(); - wm.resetSettings(); - - delay(1000); - - ESP.restart(); - - - +// wm.disconnect(); +// wm.resetSettings(); + wifiEnterConfigPortal(true, true, 3000); } void handleBTCNotFound() { diff --git a/Arduino/BTCDieselHeater/src/WiFi/BTCWifi.cpp b/Arduino/BTCDieselHeater/src/WiFi/BTCWifi.cpp index 3c58027..c44e7b3 100644 --- a/Arduino/BTCDieselHeater/src/WiFi/BTCWifi.cpp +++ b/Arduino/BTCDieselHeater/src/WiFi/BTCWifi.cpp @@ -24,6 +24,7 @@ #include "BTCWifi.h" #include "../Utility/DebugPort.h" #include +#include "../OLED/ScreenManager.h" #include "esp_system.h" #include @@ -45,6 +46,7 @@ bool isSTA = false; // true if connected to an access point int TRIG_PIN; // pin that triggers the configuration portal when set to LOW unsigned restartServer = 0; // set to time of portal reconfig - will cause reboot a while later +extern CScreenManager ScreenManager; bool initWifi(int initpin,const char *failedssid, const char *failedpassword) { @@ -134,17 +136,6 @@ void doWiFiManager() { wm.process(); - // handle the tail end of new credentials being saved by WiFiManager - // whilst the new connection is established OK, the web server is detached - // Reboot the ESP so the config portal's root link is removed and our's becomes active - // reboot takes palce 7.5 seconds after the config portal params are saved - if(restartServer) { - long tDelta = millis() - restartServer; - if(tDelta > 7500) { - restartServer = 0; - ESP.restart(); - } - } // manage handling of pin to enter WiFManager config portal // we typically use the BOOT pin for this (pins.h) @@ -154,49 +145,78 @@ void doWiFiManager() // > 5 second press - erase credentials, enable config portal static bool pinDown = false; static long pinTime = 0; + unsigned long tDelta; + if(digitalRead(TRIG_PIN) == LOW) { if(!pinDown) pinTime = millis(); pinDown = true; + // track hold duration - change OLED Wifi annotation according to length of press + tDelta = millis() - pinTime; + if(tDelta > 5000) + isPortalAP = true; // we will start portal - show 'CFG' on OLED! + else if(tDelta > 1000) + isPortalAP = false; // we won't start portal - hide 'CFG' on OLED! + else + isPortalAP = true; // we will start portal - show 'CFG' on OLED! } else { if(pinDown) { pinDown = false; - unsigned long tDelta = millis() - pinTime; + tDelta = millis() - pinTime; DebugPort.print("Wifi config button tDelta = "); DebugPort.println(tDelta); // > 5 second press? if(tDelta > 5000) { - prepBootIntoConfigPortal(true); // very long press - clear credentials, boot into portal - wm.resetSettings(); - DebugPort.println("*** Clearing credentials and rebooting into portal ***"); - delay(1000); - ESP.restart(); + wifiEnterConfigPortal(true, true); // very long press - clear credentials, reboot into portal } // > 1 second press? else if(tDelta > 1000) { - prepBootIntoConfigPortal(false); // long press - boot into SoftAP - DebugPort.println("*** Rebooting into web server ***"); - delay(1000); - ESP.restart(); + wifiEnterConfigPortal(false); // long press - reboot into web server } // > 50ms press? else if(tDelta > 50) { - prepBootIntoConfigPortal(true); // short press - boot into Portal - DebugPort.println("*** Rebooting into config portal ***"); - delay(1000); - ESP.restart(); + wifiEnterConfigPortal(true); // quick press - reboot into portal } // consider as contact bounce if < 50ms! } } } +void wifiEnterConfigPortal(bool state, bool erase, long rebootDelay) +{ + wm.disconnect(); + prepBootIntoConfigPortal(state); + + const char* content[2]; + + if(isWifiSTA() && !erase) + content[0] = "WiFi Mode -> STA+AP"; + else + content[0] = "WiFi Mode -> AP only"; + + if(erase) { + wm.resetSettings(); + DebugPort.println("*** Erased wifi credentials ***"); + } + + if(state) { + DebugPort.println("*** Rebooting into config portal ***"); + content[1] = "Web -> Config Portal"; + } + else { + DebugPort.println("*** Rebooting into web server ***"); + content[1] = "Web -> Heater control"; + } + + restartServer = (millis() + rebootDelay) | 1; // prepare to reboot in the future - ensure non zero! + + ScreenManager.showRebootMsg(content, rebootDelay); +} + // callback is invoked by WiFiManager after new credentials are saved and verified void saveParamsCallback() { - restartServer = millis() | 1; // prepare to reboot in the near future - ensure non zero! - prepBootIntoConfigPortal(false); // ensure we present our web page after reboot - isPortalAP = false; // clear CFG adornment from OLED WiFi icon + wifiEnterConfigPortal(false); // stop config portal, reboot } // callback called if the WiFiManager started the config portal @@ -238,7 +258,7 @@ bool isWifiSTA() return isSTA; // true: STAtion mode link is active } -bool isConfigPortal() +bool isWifiConfigPortal() { return isPortalAP; // true: config portal is running } diff --git a/Arduino/BTCDieselHeater/src/WiFi/BTCWifi.h b/Arduino/BTCDieselHeater/src/WiFi/BTCWifi.h index 2014ff2..ce06df5 100644 --- a/Arduino/BTCDieselHeater/src/WiFi/BTCWifi.h +++ b/Arduino/BTCDieselHeater/src/WiFi/BTCWifi.h @@ -33,9 +33,10 @@ bool isWifiConnected(); bool isWifiAP(); bool isWifiSTA(); - bool isConfigPortal(); + bool isWifiConfigPortal(); bool isWebClientConnected(); bool hasWebClientSpoken(bool reset = false); bool hasWebServerSpoken(bool reset = false); + void wifiEnterConfigPortal(bool state, bool erase = false, long timeout = 7000); #endif __BTCWIFI_H__ diff --git a/Arduino/BTCDieselHeater/src/cfg/pins.h b/Arduino/BTCDieselHeater/src/cfg/pins.h index 1b9e249..49a3baa 100644 --- a/Arduino/BTCDieselHeater/src/cfg/pins.h +++ b/Arduino/BTCDieselHeater/src/cfg/pins.h @@ -46,5 +46,5 @@ const uint8_t keyLeft_pin = 39; // input only, no chip pullup const uint8_t ListenOnlyPin = 33; //const uint8_t WiFi_TriggerPin = 25; -const uint8_t WiFi_TriggerPin = 0; +const uint8_t WiFi_TriggerPin = 0; // BOOT switch!