diff --git a/Arduino/BTCDieselHeater/128x64OLED.cpp b/Arduino/BTCDieselHeater/128x64OLED.cpp index 41f6ef0..693171e 100644 --- a/Arduino/BTCDieselHeater/128x64OLED.cpp +++ b/Arduino/BTCDieselHeater/128x64OLED.cpp @@ -191,3 +191,11 @@ C128x64_OLED::printCentreJustified(const char* str) setCursor(textRect.xPos, textRect.yPos); print(str); } + +int +C128x64_OLED::textHeight() +{ + CRect extents; + getTextExtents("H", extents); + return extents.height; +} diff --git a/Arduino/BTCDieselHeater/128x64OLED.h b/Arduino/BTCDieselHeater/128x64OLED.h index d021d9a..e76db45 100644 --- a/Arduino/BTCDieselHeater/128x64OLED.h +++ b/Arduino/BTCDieselHeater/128x64OLED.h @@ -45,6 +45,7 @@ public: void printCentreJustified(const char* str); int xCentre() { return width() / 2; }; + int textHeight(); size_t write(uint8_t c); }; diff --git a/Arduino/BTCDieselHeater/BTCDieselHeater.ino b/Arduino/BTCDieselHeater/BTCDieselHeater.ino index 40117ae..c213ef1 100644 --- a/Arduino/BTCDieselHeater/BTCDieselHeater.ino +++ b/Arduino/BTCDieselHeater/BTCDieselHeater.ino @@ -169,6 +169,7 @@ CProtocolPackage HeaterData; unsigned long moderator; bool bUpdateDisplay = false; +bool bHaveWebClient = false; //////////////////////////////////////////////////////////////////////////////////////////////////////// // Bluetooth instantiation @@ -310,7 +311,7 @@ void loop() DoOTA(); #endif // USE_OTA #if USE_WEBSERVER == 1 - doWebServer(); + bHaveWebClient = doWebServer(); #endif //USE_WEBSERVER #endif // USE_WIFI @@ -819,20 +820,6 @@ bool validateFrame(const CProtocol& frame, const char* name) } -/*int getRunState() -{ - if(pRxFrame) - return pRxFrame->getRunState(); - return 0; -} - -int getErrState() -{ - if(pRxFrame) - return pRxFrame->getErrState(); - return 8; // Comms error! -}*/ - void requestOn() { TxManage.queueOnRequest(); @@ -874,25 +861,14 @@ void reqTempChange(int val) NVstore.setTemperature(curTemp); -// reqDisplayUpdate(); ScreenManager.reqUpdate(); } int getSetTemp() { -// pTxFrame->getTemperature_Desired(); // sluggish - delays until new packet goes out! return NVstore.getTemperature(); } -/*float getFixedHz() -{ - if(pRxFrame) { - return pRxFrame->getPump_Fixed(); - } - return 0.0; -} -*/ - void reqThermoToggle() { setThermostatMode(getThermostatMode() ? 0 : 1); @@ -912,14 +888,18 @@ bool getThermostatMode() void checkDisplayUpdate() { // only update OLED when not processing blue wire -// if(pTxFrame && pRxFrame) { - ScreenManager.checkUpdate(); -// } + if(ScreenManager.checkUpdate()) { + lastAnimationTime = millis() + 100; + ScreenManager.animate(); + ScreenManager.refresh(); // always refresh post major update + } + long tDelta = millis() - lastAnimationTime; if(tDelta >= 100) { - lastAnimationTime += 100; - ScreenManager.animate(); + lastAnimationTime = millis() + 100; + if(ScreenManager.animate()) + ScreenManager.refresh(); } } @@ -928,51 +908,11 @@ void reqPumpPrime(bool on) DefaultBTCParams.setPump_Prime(on); } -/*float getPumpHz() -{ - if(pRxFrame) { - return pRxFrame->getPump_Actual(); - } - return 0.0; -} -*/ float getActualTemperature() { return fFilteredTemperature; } -/*float getPumpMin() -{ - if(pTxFrame) { - return pTxFrame->getPump_Min(); - } - return 0.0; -} - -float getPumpMax() -{ - if(pTxFrame) { - return pTxFrame->getPump_Max(); - } - return 0.0; -} - -short getFanMin() -{ - if(pTxFrame) { - return pTxFrame->getFan_Min(); - } - return 0.0; -} - -short getFanMax() -{ - if(pTxFrame) { - return pTxFrame->getFan_Max(); - } - return 0.0; -}*/ - void setPumpMin(float val) { NVstore.setPmin(val); @@ -1001,4 +941,9 @@ void saveNV() const CProtocolPackage& getHeaterInfo() { return HeaterData; -} \ No newline at end of file +} + +bool isWebClientConnected() +{ + return bHaveWebClient; +} diff --git a/Arduino/BTCDieselHeater/BTCWebServer.cpp b/Arduino/BTCDieselHeater/BTCWebServer.cpp index 0fddbf4..229af72 100644 --- a/Arduino/BTCDieselHeater/BTCWebServer.cpp +++ b/Arduino/BTCDieselHeater/BTCWebServer.cpp @@ -32,6 +32,8 @@ extern void Command_Interpret(const char* pLine); // decodes received command WebServer server(80); WebSocketsServer webSocket = WebSocketsServer(81); +bool bRxWebData = false; +bool bTxWebData = false; const int led = 13; @@ -73,19 +75,22 @@ void initWebServer(void) { } unsigned char cVal; -void doWebServer(void) { +bool doWebServer(void) { static unsigned long lastTx = 0; webSocket.loop(); server.handleClient(); - if(millis() > lastTx) { // moderate the delivery of new messages - we simply cannot send every pass of the main loop! - lastTx = millis() + 1000; - char msg[16]; - sprintf(msg, "%.1f", getActualTemperature()); - webSocket.broadcastTXT(msg); - // char c[] = { "23" }; - // webSocket.broadcastTXT(c, sizeof(c)); -} - + int numClients = webSocket.connectedClients(); + if(numClients) { + if(millis() > lastTx) { // moderate the delivery of new messages - we simply cannot send every pass of the main loop! + lastTx = millis() + 1000; + char msg[16]; + sprintf(msg, "%.1f", getActualTemperature()); + webSocket.broadcastTXT(msg); + bTxWebData = true; + } + return true; + } + return false; } void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { @@ -94,10 +99,25 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length memset(cmd, 0, 16); for (int i = 0; i < length && i < 15; i++) { cmd[i] = payload[i]; -// Serial.print((char)payload[i]); } -// Serial.println(); - Serial.println(cmd); +// Serial.println(cmd); Command_Interpret(cmd); // send to the main heater controller decode routine + bRxWebData = true; + } +} + +bool hasWebClientSpoken(bool reset) +{ + bool retval = bRxWebData; + if(reset) + bRxWebData = false; + return retval; +} + +bool hasWebServerSpoken(bool reset) +{ + bool retval = bTxWebData; + if(reset) + bTxWebData = false; + return retval; } -} \ No newline at end of file diff --git a/Arduino/BTCDieselHeater/BTCWebServer.h b/Arduino/BTCDieselHeater/BTCWebServer.h index 8812e15..f37ff03 100644 --- a/Arduino/BTCDieselHeater/BTCWebServer.h +++ b/Arduino/BTCDieselHeater/BTCWebServer.h @@ -45,7 +45,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length); void initWebServer(); -void doWebServer(); +bool doWebServer(); void handleRoot(); void handleNotFound(); void webturnOn(); diff --git a/Arduino/BTCDieselHeater/BTCWifi.cpp b/Arduino/BTCDieselHeater/BTCWifi.cpp index 33efb18..8e2a943 100644 --- a/Arduino/BTCDieselHeater/BTCWifi.cpp +++ b/Arduino/BTCDieselHeater/BTCWifi.cpp @@ -112,3 +112,4 @@ bool isWifiConnected() { return WiFi.status() == WL_CONNECTED; } + diff --git a/Arduino/BTCDieselHeater/BTCWifi.h b/Arduino/BTCDieselHeater/BTCWifi.h index f3bfefd..3971250 100644 --- a/Arduino/BTCDieselHeater/BTCWifi.h +++ b/Arduino/BTCDieselHeater/BTCWifi.h @@ -34,5 +34,8 @@ void initWifi(int initpin,const char *failedssid, const char *failedpassword); const char* getWifiAddrStr(); bool isWifiConnected(); + bool isWebClientConnected(); + bool hasWebClientSpoken(bool reset = false); + bool hasWebServerSpoken(bool reset = false); #endif __BTCWIFI_H__ diff --git a/Arduino/BTCDieselHeater/OLEDconsts.cpp b/Arduino/BTCDieselHeater/Icons.cpp similarity index 57% rename from Arduino/BTCDieselHeater/OLEDconsts.cpp rename to Arduino/BTCDieselHeater/Icons.cpp index fa38c24..7b4bd3f 100644 --- a/Arduino/BTCDieselHeater/OLEDconsts.cpp +++ b/Arduino/BTCDieselHeater/Icons.cpp @@ -19,7 +19,8 @@ * */ -#include "OLEDconsts.h" +#include +#include "Icons.h" // 'Thermometer', 8x50px const unsigned char thermometerBitmap [] PROGMEM = { @@ -45,6 +46,15 @@ const unsigned char wifiIcon [] PROGMEM = { 0x07, 0x00, 0x08, 0x80, 0x00, 0x00, 0x02, 0x00 }; +// 'wifiInIcon, 5x5px +const unsigned char wifiInIcon [] PROGMEM = { + 0x70, 0x70, 0xf8, 0x70, 0x20 +}; + +// 'wifiOutIcon, 5x5px +const unsigned char wifiOutIcon [] PROGMEM = { + 0x20, 0x70, 0xf8, 0x70, 0x70 +}; // 'BatteryIcon', 15x10px const unsigned char BatteryIcon [] PROGMEM = { @@ -97,134 +107,3 @@ const unsigned char TargetIcon [] PROGMEM = { }; - -// # # ## ### # # ### ## ### ### ### -// # # ## # # # # # # # # # # # -// # # # # ## ### ## ### # ### ### -// # # # # # # # # # # # # # -// # ### ### ### # ## ### # ### ## -// '0', 3x5px -const unsigned char Mini0 [] PROGMEM = { - 0x40, 0xb0, 0xb0, 0xb0, 0x40 -}; - -// '1', 3x5px -const unsigned char Mini1 [] PROGMEM = { - 0x40, 0xc0, 0x40, 0x40, 0xe0 -}; - -// '2', 3x5px -const unsigned char Mini2 [] PROGMEM = { - 0xc0, 0x20, 0x40, 0x80, 0xe0 -}; - -// '3', 3x5px -const unsigned char Mini3 [] PROGMEM = { - 0xe0, 0x20, 0x60, 0x20, 0xe0 -}; - -// '4', 3x5px -const unsigned char Mini4 [] PROGMEM = { - 0xb0, 0xb0, 0xe0, 0x20, 0x20 -}; - -// '5', 3x5px -const unsigned char Mini5 [] PROGMEM = { - 0xe0, 0x80, 0xc0, 0x20, 0xc0 -}; - -// '6', 3x5px -const unsigned char Mini6 [] PROGMEM = { - 0x60, 0x80, 0xe0, 0xb0, 0xe0 -}; - -// '7', 3x5px -const unsigned char Mini7 [] PROGMEM = { - 0xe0, 0x20, 0x20, 0x20, 0x20 -}; - -// '8', 3x5px -const unsigned char Mini8 [] PROGMEM = { - 0xe0, 0xb0, 0xe0, 0xb0, 0xe0 -}; - -// '9', 3x5px -const unsigned char Mini9 [] PROGMEM = { - 0xe0, 0xb0, 0xe0, 0x20, 0xc0 -}; - -// 'DP', 3x5px -const unsigned char MiniDP [] PROGMEM = { - 0x00, 0x00, 0x00, 0x00, 0x40 -}; - -// 'Deg', 3x5px -const unsigned char MiniDeg [] PROGMEM = { - 0xc0, 0xc0, 0x00, 0x00, 0x00 -}; - -// 'C', 3x5px -const unsigned char MiniC [] PROGMEM = { - 0xe0, 0x80, 0x80, 0x80, 0xe0 -}; - -// 'H', 3x5px -const unsigned char MiniH [] PROGMEM = { - 0xb0, 0xb0, 0xe0, 0xb0, 0xb0 -}; - -// 'z', 3x5px -const unsigned char Miniz [] PROGMEM = { - 0x00, 0x00, 0xe0, 0x40, 0xe0 -}; - -// ' ', 3x5px -const unsigned char MiniSpc [] PROGMEM = { - 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -// 'A', 3x5px -const unsigned char MiniA [] PROGMEM = { - 0xe0, 0xb0, 0xe0, 0xb0, 0xb0 -}; - -// 'P', 3x5px -const unsigned char MiniP [] PROGMEM = { - 0xe0, 0xb0, 0xe0, 0x80, 0x80 -}; - -// 'V', 3x5px -const unsigned char MiniV [] PROGMEM = { - 0xb0, 0xb0, 0xb0, 0xb0, 0x40 -}; - -// 'W', 3x5px -const unsigned char MiniW [] PROGMEM = { - 0xb0, 0xb0, 0xb0, 0xe0, 0xb0 -}; - -const char* Runstates [] PROGMEM = { - " Stopped/Ready ", - "Starting...", - "Igniting...", - " Ignition retry ", - "Ignited", - "Running", - "Stopping", - "Shutting down", - "Cooling" -}; - -const char* Errstates [] PROGMEM = { - "Low voltage", // E-01 - "High voltage", // E-02 - "Glow plug fault", // E-03 - "Pump fault", // E-04 - "Overheat", // E-05 - "Motor fault", // E-06 - "Comms fault", // E-07 - "Flame out", // E-08 - "Temp sense", // E-09 - "Ignition fail", // E-10 - "Unknown error?" // mystery code! -}; diff --git a/Arduino/BTCDieselHeater/OLEDconsts.h b/Arduino/BTCDieselHeater/Icons.h similarity index 90% rename from Arduino/BTCDieselHeater/OLEDconsts.h rename to Arduino/BTCDieselHeater/Icons.h index cb75993..9d94099 100644 --- a/Arduino/BTCDieselHeater/OLEDconsts.h +++ b/Arduino/BTCDieselHeater/Icons.h @@ -19,8 +19,6 @@ * */ -#include - // 'Thermometer', 8x50px #define W_BULB_ICON 8 #define H_BULB_ICON 50 @@ -41,6 +39,16 @@ extern const unsigned char BTicon []; #define H_WIFI_ICON 10 extern const unsigned char wifiIcon []; +// 'wifiInIcon', 5x5px +#define W_WIFIIN_ICON 5 +#define H_WIFIIN_ICON 5 +extern const unsigned char wifiInIcon []; + +// 'wifiOutIcon', 5x5px +#define W_WIFIOUT_ICON 5 +#define H_WIFIOUT_ICON 5 +extern const unsigned char wifiOutIcon []; + // 'BatteryIcon', 15x10px #define W_BATT_ICON 15 #define H_BATT_ICON 10 @@ -79,6 +87,3 @@ extern const unsigned char FuelIcon []; extern const unsigned char TargetIcon []; -extern const char* Runstates []; - -extern const char* Errstates []; \ No newline at end of file diff --git a/Arduino/BTCDieselHeater/Protocol.cpp b/Arduino/BTCDieselHeater/Protocol.cpp index 9af8fc4..76636c1 100644 --- a/Arduino/BTCDieselHeater/Protocol.cpp +++ b/Arduino/BTCDieselHeater/Protocol.cpp @@ -22,6 +22,7 @@ #include #include "Protocol.h" #include "debugport.h" +#include "helpers.h" #ifdef TELNET #define DebugPort Debug @@ -31,7 +32,6 @@ #define DebugPort Serial #endif - unsigned short CProtocol::CalcCRC(int len) const { @@ -311,3 +311,51 @@ CProtocol::setThermostatMode(unsigned on) if(!on) setTemperature_Actual(0); // if using fixed mode, actual must be reported as 0 }; + +const char* Runstates [] PROGMEM = { + " Stopped/Ready ", + "Starting...", + "Igniting...", + " Ignition retry ", + "Ignited", + "Running", + "Stopping", + "Shutting down", + "Cooling", + "Unknown run state" +}; + + + +const char* +CProtocolPackage::getRunStateStr() const +{ + uint8_t runstate = Heater.getRunState(); + UPPERLIMIT(runstate, 9); + return Runstates[runstate]; +} + + +const char* Errstates [] PROGMEM = { + "", + "", + "Low voltage", // E-01 + "High voltage", // E-02 + "Glow plug fault", // E-03 + "Pump fault", // E-04 + "Overheat", // E-05 + "Motor fault", // E-06 + "Comms fault", // E-07 + "Flame out", // E-08 + "Temp sense", // E-09 + "Ignition fail", // E-10 + "Unknown error?" // mystery code! +}; + +const char* +CProtocolPackage::getErrStateStr() const +{ + uint8_t errstate = Heater.getErrState(); + UPPERLIMIT(errstate, 12); + return Errstates[errstate]; +} diff --git a/Arduino/BTCDieselHeater/Protocol.h b/Arduino/BTCDieselHeater/Protocol.h index 0d2c535..d470d7a 100644 --- a/Arduino/BTCDieselHeater/Protocol.h +++ b/Arduino/BTCDieselHeater/Protocol.h @@ -207,13 +207,15 @@ class CProtocolPackage { CProtocol Heater; CProtocol Controller; public: - void set(const CProtocol& htr, const CProtocol& ctl) { Heater = htr; Controller = ctl; }; - int getRunState() const { return Heater.getRunState(); }; - int getErrState() const { return Heater.getErrState(); }; + void set(const CProtocol& htr, const CProtocol& ctl) { Heater = htr; Controller = ctl; }; + int getRunState() const { return Heater.getRunState(); }; + const char* getRunStateStr() const; + int getErrState() const { return Heater.getErrState(); }; + const char* getErrStateStr() const; float getBattVoltage() const { return Heater.getVoltage_Supply(); }; - bool isThermostat() const { return Controller.isThermostat(); }; - float getTemperature_Desired() const { return Controller.getTemperature_Desired(); }; - float getTemperature_HeatExchg() const { return Heater.getTemperature_HeatExchg(); }; + bool isThermostat() const { return Controller.isThermostat(); }; + float getTemperature_Desired() const { return float(Controller.getTemperature_Desired()); }; + float getTemperature_HeatExchg() const { return float(Heater.getTemperature_HeatExchg()); }; float getPump_Fixed() const { return Heater.getPump_Fixed(); }; float getPump_Actual() const { return Heater.getPump_Actual(); }; float getPump_Min() const { return Controller.getPump_Min(); }; @@ -224,4 +226,5 @@ public: float getGlowPlug_Power() const { return Heater.getGlowPlug_Current() * Heater.getGlowPlug_Voltage(); }; }; + #endif \ No newline at end of file diff --git a/Arduino/BTCDieselHeater/Screen.cpp b/Arduino/BTCDieselHeater/Screen.cpp index f8e00ea..1b83d6e 100644 --- a/Arduino/BTCDieselHeater/Screen.cpp +++ b/Arduino/BTCDieselHeater/Screen.cpp @@ -17,9 +17,10 @@ CScreen::~CScreen() } -void +bool CScreen::animate() { + return false; } diff --git a/Arduino/BTCDieselHeater/Screen.h b/Arduino/BTCDieselHeater/Screen.h index 80e5ef3..c794566 100644 --- a/Arduino/BTCDieselHeater/Screen.h +++ b/Arduino/BTCDieselHeater/Screen.h @@ -47,7 +47,7 @@ protected: public: CScreen(C128x64_OLED& disp, CScreenManager& mgr); virtual ~CScreen(); - virtual void animate(); + virtual bool animate(); virtual void show(); virtual void keyHandler(uint8_t event) {}; }; diff --git a/Arduino/BTCDieselHeater/Screen1.cpp b/Arduino/BTCDieselHeater/Screen1.cpp index fef7d37..750bbbd 100644 --- a/Arduino/BTCDieselHeater/Screen1.cpp +++ b/Arduino/BTCDieselHeater/Screen1.cpp @@ -21,7 +21,7 @@ #include "128x64OLED.h" #include "MiniFont.h" -#include "OLEDconsts.h" +#include "Icons.h" #include "BluetoothAbstract.h" #include "Screen1.h" #include "BTCWifi.h" @@ -91,10 +91,6 @@ CScreen1::show() float desiredT = 0; if((runstate && (runstate <= 5)) || _showTarget) { - // if(CtlFrame.isThermostat()) - // desiredT = CtlFrame.getTemperature_Desired(); - // else - // desiredT = -HtrFrame.getPump_Fixed(); if(getHeaterInfo().isThermostat()) desiredT = getHeaterInfo().getTemperature_Desired(); else @@ -109,19 +105,15 @@ CScreen1::show() _animateGlow = false; if(runstate) { -// float power = HtrFrame.getGlowPlug_Current() * HtrFrame.getGlowPlug_Voltage(); float power = getHeaterInfo().getGlowPlug_Power(); if(power > 1) { showGlowPlug(power); } -// showFan(HtrFrame.getFan_Actual()); showFan(getHeaterInfo().getFan_Actual()); -// showFuel(HtrFrame.getPump_Actual()); showFuel(getHeaterInfo().getPump_Actual()); -// showBodyThermometer(HtrFrame.getTemperature_HeatExchg()); showBodyThermometer(getHeaterInfo().getTemperature_HeatExchg()); } @@ -129,9 +121,10 @@ CScreen1::show() } -void +bool CScreen1::animate() { + bool retval = CScreenHeader::animate(); if(_animatePump || _animateRPM || _animateGlow) { @@ -163,8 +156,9 @@ CScreen1::animate() _heatAnimationState -= 2; _heatAnimationState &= 0x07; } + return retval |= true; } - _display.display(); + return retval; } @@ -339,7 +333,7 @@ CScreen1::showRunState(int runstate, int errstate) char msg[16]; sprintf(msg, "E-%02d", errstate); if(runstate > 5) - yPos -= 8; + yPos -= _display.textHeight(); _display.setCursor(_display.xCentre(), yPos); // flash error code toggle = !toggle; @@ -348,13 +342,11 @@ CScreen1::showRunState(int runstate, int errstate) else { _display.printCentreJustified(" "); } - yPos += 8; - // bounds limit error and gather message - if(errstate > 10) errstate = 11; - toPrint = Errstates[errstate-1]; + yPos += _display.textHeight(); + toPrint = getHeaterInfo().getErrStateStr(); } else { - toPrint = Runstates[runstate]; + toPrint = getHeaterInfo().getRunStateStr(); } } if(toPrint) { diff --git a/Arduino/BTCDieselHeater/Screen1.h b/Arduino/BTCDieselHeater/Screen1.h index 42870d1..e51a71d 100644 --- a/Arduino/BTCDieselHeater/Screen1.h +++ b/Arduino/BTCDieselHeater/Screen1.h @@ -47,6 +47,6 @@ class CScreen1 : public CScreenHeader public: CScreen1(C128x64_OLED& display, CScreenManager& mgr); void show(); - void animate(); + bool animate(); void keyHandler(uint8_t event); }; diff --git a/Arduino/BTCDieselHeater/Screen2.cpp b/Arduino/BTCDieselHeater/Screen2.cpp index 021ac2a..c36ed3b 100644 --- a/Arduino/BTCDieselHeater/Screen2.cpp +++ b/Arduino/BTCDieselHeater/Screen2.cpp @@ -21,7 +21,7 @@ #include "128x64OLED.h" #include "tahoma16.h" -#include "OLEDconsts.h" +#include "Icons.h" #include "Screen2.h" #include "KeyPad.h" #include "helpers.h" @@ -72,7 +72,7 @@ CScreen2::show() long tDelta = millis() - _showMode; if(tDelta < 0) { - yPos = _display.height() - 8 - border; // bottom of screen, with room for box + yPos = _display.height() - _display.textHeight() - border; // bottom of screen, with room for box // display "Fixed Hz" at lower right, allowing space for a selection surrounding box strcpy(msg, "Fixed Hz"); @@ -103,7 +103,7 @@ CScreen2::show() sprintf(msg, "Setpoint = %.1fHz", getHeaterInfo().getPump_Fixed()); } // centre message at bottom of screen - _drawMenuText(_display.xCentre(), _display.height() - 8, msg, false, eCentreJustify); + _drawMenuText(_display.xCentre(), _display.height() - _display.textHeight(), msg, false, eCentreJustify); } else { _showSetMode = 0; @@ -112,18 +112,9 @@ CScreen2::show() if((_showMode == 0) && (_showSetMode == 0)) { showRunState(); } - - _display.display(); } -void -CScreen2::animate() -{ - // do nothing!! -}; - - void CScreen2::keyHandler(uint8_t event) { @@ -231,24 +222,22 @@ CScreen2::showRunState() _display.setTextColor(WHITE, BLACK); if(runstate >= 0 && runstate <= 8) { if(((runstate == 0) || (runstate > 5)) && errstate) { - // create an "E-XX" message to display - char msg[16]; - sprintf(msg, "E-%02d", errstate); - // determine height of font - CRect textRect; - _display.getTextExtents(msg, textRect); - _display.setCursor(_display.xCentre(), // locate at bottom centre, 1 line up - _display.height() - 2*textRect.height); + // flash error code + char msg[16]; toggle = !toggle; - if(toggle) - _display.printCentreJustified(msg); - else { - _display.printCentreJustified(" "); + if(toggle) { + // create an "E-XX" message to display + sprintf(msg, "E-%02d", errstate); } - // bounds limit error and gather message - if(errstate > 10) errstate = 11; - toPrint = Errstates[errstate-1]; + else { + strcpy(msg, " "); + } + int xPos = _display.xCentre(); + int yPos = _display.height() - 2*_display.textHeight(); + _drawMenuText(xPos, yPos, msg, false, eCentreJustify); + + toPrint = getHeaterInfo().getErrStateStr(); } else { if(runstate) { @@ -260,11 +249,7 @@ CScreen2::showRunState() } } if(toPrint) { - // determine height of font - CRect textRect; - _display.getTextExtents(toPrint, textRect); - _display.setCursor(_display.xCentre(), // locate at bottom centre - _display.height() - textRect.height); - _display.printCentreJustified(toPrint); + // locate at bottom centre + _drawMenuText(_display.xCentre(), _display.height() - _display.textHeight(), toPrint, false, eCentreJustify); } } diff --git a/Arduino/BTCDieselHeater/Screen2.h b/Arduino/BTCDieselHeater/Screen2.h index 0c471d2..757ee15 100644 --- a/Arduino/BTCDieselHeater/Screen2.h +++ b/Arduino/BTCDieselHeater/Screen2.h @@ -35,6 +35,5 @@ class CScreen2 : public CScreenHeader public: CScreen2(C128x64_OLED& display, CScreenManager& mgr); void show(); - void animate(); void keyHandler(uint8_t event); }; diff --git a/Arduino/BTCDieselHeater/Screen3.cpp b/Arduino/BTCDieselHeater/Screen3.cpp index 1ae17fc..516b4c0 100644 --- a/Arduino/BTCDieselHeater/Screen3.cpp +++ b/Arduino/BTCDieselHeater/Screen3.cpp @@ -96,18 +96,11 @@ CScreen3::show() } } - _display.display(); +// _display.display(); } -void -CScreen3::animate() -{ - // do nothing!! -}; - - void CScreen3::keyHandler(uint8_t event) { diff --git a/Arduino/BTCDieselHeater/Screen3.h b/Arduino/BTCDieselHeater/Screen3.h index 88af1f2..ea76bd6 100644 --- a/Arduino/BTCDieselHeater/Screen3.h +++ b/Arduino/BTCDieselHeater/Screen3.h @@ -34,6 +34,5 @@ class CScreen3 : public CScreenHeader { public: CScreen3(C128x64_OLED& display, CScreenManager& mgr); void show(); - void animate(); void keyHandler(uint8_t event); }; diff --git a/Arduino/BTCDieselHeater/Screen4.cpp b/Arduino/BTCDieselHeater/Screen4.cpp index bcc7041..f164148 100644 --- a/Arduino/BTCDieselHeater/Screen4.cpp +++ b/Arduino/BTCDieselHeater/Screen4.cpp @@ -57,17 +57,10 @@ CScreen4::show() _display.printRightJustified("Not active"); } - _display.display(); +// _display.display(); } -void -CScreen4::animate() -{ - // do nothing!! -}; - - void CScreen4::keyHandler(uint8_t event) { diff --git a/Arduino/BTCDieselHeater/Screen4.h b/Arduino/BTCDieselHeater/Screen4.h index 424773e..57b6b6d 100644 --- a/Arduino/BTCDieselHeater/Screen4.h +++ b/Arduino/BTCDieselHeater/Screen4.h @@ -29,6 +29,5 @@ class CScreen4 : public CScreenHeader { public: CScreen4(C128x64_OLED& display, CScreenManager& mgr); void show(); - void animate(); void keyHandler(uint8_t event); }; diff --git a/Arduino/BTCDieselHeater/Screen5.cpp b/Arduino/BTCDieselHeater/Screen5.cpp index 1e5dbca..285c702 100644 --- a/Arduino/BTCDieselHeater/Screen5.cpp +++ b/Arduino/BTCDieselHeater/Screen5.cpp @@ -128,17 +128,10 @@ CScreen5::show() break; } - _display.display(); +// _display.display(); } -void -CScreen5::animate() -{ - // do nothing!! -}; - - void CScreen5::keyHandler(uint8_t event) { diff --git a/Arduino/BTCDieselHeater/Screen5.h b/Arduino/BTCDieselHeater/Screen5.h index 22c1e7a..eb3649d 100644 --- a/Arduino/BTCDieselHeater/Screen5.h +++ b/Arduino/BTCDieselHeater/Screen5.h @@ -38,6 +38,5 @@ class CScreen5 : public CScreenHeader { public: CScreen5(C128x64_OLED& display, CScreenManager& mgr); void show(); - void animate(); void keyHandler(uint8_t event); }; diff --git a/Arduino/BTCDieselHeater/ScreenHeader.cpp b/Arduino/BTCDieselHeater/ScreenHeader.cpp index c78d0be..665e7bd 100644 --- a/Arduino/BTCDieselHeater/ScreenHeader.cpp +++ b/Arduino/BTCDieselHeater/ScreenHeader.cpp @@ -5,7 +5,7 @@ #include "BTCWifi.h" #include "BluetoothAbstract.h" #include "clock.h" -#include "OLEDconsts.h" +#include "Icons.h" #include "MiniFont.h" #include "helpers.h" @@ -20,9 +20,13 @@ #define MINI_BATTLABEL +#define DEMO_AP_MODE CScreenHeader::CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr) : CScreen(disp, mgr) { + _animateState = 0; + _animationHold = 0; + _needAnimationClear = false; } void @@ -44,6 +48,58 @@ CScreenHeader::show() showTime(_display); } +// Animate IN/OUT arrows against the WiFi icon, according to actual web server traffic +// an IN arrow is drawn if incoming data has been detected +// an OUT arrow is drawn if outgoing data has been sent +// +// Each arrow is drawn standalone, with a clear interval for a clean flash on the display +// The following is a typical sequence, relative to animation ticks, note the gap +// always appears in the animation interval between any arrow shown +// +// | | | | | | | | | | | | | | | | | | +// ________^^^^^^____vvvvv_______________vvvvv__________^^^^^_____vvvvv_____________________ + +bool +CScreenHeader::animate() +{ + bool retval = false; + if(isWifiConnected() && isWebClientConnected()) { + int xPos = X_WIFI_ICON + W_WIFI_ICON; +#ifdef DEMO_AP_MODE + xPos += 4; +#endif + int yPos = H_WIFI_ICON - H_WIFIIN_ICON + 1; + // animation hold ensures our arrow indications always have a clear + // period between them, otherwise they just visibly mush together + if(_animationHold) + _animationHold--; + // as we control (moderate) the delivery, check for any data we have sent first + // An over enthusiastic client would otherwise block the out arrow animation! + if(!_animationHold && hasWebServerSpoken(true)) { + // we have emitted data to the web client, show an OUT arrow +// _display.drawBitmap(xPos, yPos, wifiOutIcon, W_WIFIIN_ICON, H_WIFIIN_ICON, WHITE); + _display.drawBitmap(xPos, 0, wifiOutIcon, W_WIFIIN_ICON, H_WIFIIN_ICON, WHITE); + _needAnimationClear = true; // clear arrow upon next iteration + _animationHold = 2; // prevent anotehr arrow appearing before previous arrow has been scrubbed + retval = true; + } + else if(!_animationHold && hasWebClientSpoken(true)) { + // we have receievd data from the web client, show an IN arrow + _display.drawBitmap(xPos, yPos, wifiInIcon, W_WIFIIN_ICON, H_WIFIIN_ICON, WHITE); + _needAnimationClear = true; // clear arrow upon next iteration + _animationHold = 2; // prevent another arrow appearing before previous arrow has been scrubbed + retval = true; + } + else if(_needAnimationClear) { // an arrow was drawn in the prior iteration, now erase it + _display.fillRect(xPos, yPos, W_WIFIIN_ICON, H_WIFIIN_ICON, BLACK); + _display.fillRect(xPos, 0, W_WIFIIN_ICON, H_WIFIIN_ICON, BLACK); + retval = true; + _needAnimationClear = false; + } + } + return retval; // true if we have updated the display contents +} + void CScreenHeader::showBTicon() { diff --git a/Arduino/BTCDieselHeater/ScreenHeader.h b/Arduino/BTCDieselHeater/ScreenHeader.h index 673d0bc..ee4f0d2 100644 --- a/Arduino/BTCDieselHeater/ScreenHeader.h +++ b/Arduino/BTCDieselHeater/ScreenHeader.h @@ -29,6 +29,9 @@ class CScreenHeader : public CScreen { + int _animateState; + int _animationHold; + bool _needAnimationClear; protected: void showBTicon(); void showWifiIcon(); @@ -36,6 +39,7 @@ protected: public: CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr); virtual void show(); + virtual bool animate(); }; #endif // __SCREEN_HEADER_H__ diff --git a/Arduino/BTCDieselHeater/ScreenManager.cpp b/Arduino/BTCDieselHeater/ScreenManager.cpp index 140ccfe..cd8a2d7 100644 --- a/Arduino/BTCDieselHeater/ScreenManager.cpp +++ b/Arduino/BTCDieselHeater/ScreenManager.cpp @@ -156,15 +156,17 @@ CScreenManager::init() _switchScreen(); } -void +bool CScreenManager::checkUpdate() { if(_bReqUpdate) { if(_pActiveScreen) { _pActiveScreen->show(); _bReqUpdate = false; + return true; } } + return false; } void @@ -173,10 +175,19 @@ CScreenManager::reqUpdate() _bReqUpdate = true; } -void +bool CScreenManager::animate() { - if(_pActiveScreen) _pActiveScreen->animate(); + if(_pActiveScreen) + return _pActiveScreen->animate(); + return false; +} + +void +CScreenManager::refresh() +{ + if(_pDisplay) + _pDisplay->display(); } void diff --git a/Arduino/BTCDieselHeater/ScreenManager.h b/Arduino/BTCDieselHeater/ScreenManager.h index 73410de..34c813e 100644 --- a/Arduino/BTCDieselHeater/ScreenManager.h +++ b/Arduino/BTCDieselHeater/ScreenManager.h @@ -40,8 +40,9 @@ public: CScreenManager(); ~CScreenManager(); void init(); - void checkUpdate(); - void animate(); + bool checkUpdate(); + bool animate(); + void refresh(); void nextScreen(); void prevScreen(); void keyHandler(uint8_t event);