diff --git a/Arduino/Afterburner/Afterburner.ino b/Arduino/Afterburner/Afterburner.ino index 12ace0c..b033a45 100644 --- a/Arduino/Afterburner/Afterburner.ino +++ b/Arduino/Afterburner/Afterburner.ino @@ -183,10 +183,14 @@ bool bHasHtrData = false; // these variables will persist over a soft reboot. __NOINIT_ATTR bool bForceInit; // = false; -__NOINIT_ATTR bool bUserON; // = false; -__NOINIT_ATTR uint8_t demandDegC; -__NOINIT_ATTR uint8_t demandPump; +//__NOINIT_ATTR bool bUserON; // = false; +//__NOINIT_ATTR uint8_t demandDegC; +//__NOINIT_ATTR uint8_t demandPump; +//uint8_t demandDegC; +//uint8_t demandPump; +//bool bCyclicEngaged; CFuelGauge FuelGauge; +CRTC_Store RTC_Store; bool bReportBlueWireData = REPORT_RAW_DATA; bool bReportJSONData = REPORT_JSON_TRANSMIT; @@ -305,13 +309,11 @@ extern "C" unsigned long __wrap_millis() { void setup() { // ensure cyclic mode is disabled after power on - bool bPowerUpInit = false; - if(rtc_get_reset_reason(0) == 1/* || bForceInit*/) { - bPowerUpInit = true; - bForceInit = false; - bUserON = false; - demandPump = demandDegC = 22; - } +// bool bPowerUpInit = false; +// if(rtc_get_reset_reason(0) == 1/* || bForceInit*/) { +// bPowerUpInit = true; +// bForceInit = false; +// } // initially, ensure the GPIO outputs are not activated during startup // (GPIO2 tends to be one with default chip startup) @@ -334,7 +336,7 @@ void setup() { DebugPort.println("_______________________________________________________________"); DebugPort.printf("Reset reason: core0:%d, core1:%d\r\n", rtc_get_reset_reason(0), rtc_get_reset_reason(0)); - DebugPort.printf("Previous user ON = %d\r\n", bUserON); // state flag required for cyclic mode to persist properly after a WD reboot :-) +// DebugPort.printf("Previous user ON = %d\r\n", bUserON); // state flag required for cyclic mode to persist properly after a WD reboot :-) // initialise DS18B20 sensor interface TempSensor.begin(DS18B20_Pin); @@ -383,6 +385,9 @@ void setup() { BootTime = Clock.get().secondstime(); ScreenManager.begin(bNoClock); + if(!bNoClock && Clock.lostPower()) { + ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::SetClockUI); + } #if USE_WIFI == 1 @@ -442,9 +447,12 @@ void setup() { FilteredSamples.Fan.setAlpha(0.7); FilteredSamples.AmbientTemp.reset(-100.0); -// if(bPowerUpInit) { - FuelGauge.init(); -// } + RTC_Store.begin(); + FuelGauge.init(RTC_Store.getFuelGauge()); +// demandDegC = RTC_Store.getDesiredTemp(); +// demandPump = RTC_Store.getDesiredPump(); +// bCyclicEngaged = RTC_Store.getCyclicEngaged(); + DebugPort.printf("Previous cyclic active = %d\r\n", RTC_Store.getCyclicEngaged()); // state flag required for cyclic mode to persist properly after a WD reboot :-) delay(1000); // just to hold the splash screeen for while } @@ -812,7 +820,7 @@ void DebugReportFrame(const char* hdr, const CProtocol& Frame, const char* ftr) void manageCyclicMode() { const sCyclicThermostat& cyclic = NVstore.getUserSettings().cyclic; - if(cyclic.Stop && bUserON) { // cyclic mode enabled, and user has started heater + if(cyclic.Stop && RTC_Store.getCyclicEngaged()) { // cyclic mode enabled, and user has started heater int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over! float deltaT = FilteredSamples.AmbientTemp.getValue() - getDemandDegC(); // DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT); @@ -876,13 +884,13 @@ bool validateFrame(const CProtocol& frame, const char* name) void requestOn() { heaterOn(); - bUserON = true; // for cyclic mode + RTC_Store.setCyclicEngaged(true); // for cyclic mode } void requestOff() { heaterOff(); - bUserON = false; // for cyclic mode + RTC_Store.setCyclicEngaged(false); // for cyclic mode } void heaterOn() @@ -898,38 +906,42 @@ void heaterOff() } -bool reqTemp(uint8_t newTemp, bool save) +bool reqDemand(uint8_t newDemand, bool save) { if(bHasOEMController) return false; uint8_t max = DefaultBTCParams.getTemperature_Max(); uint8_t min = DefaultBTCParams.getTemperature_Min(); - if(newTemp >= max) - newTemp = max; - if(newTemp <= min) - newTemp = min; + if(newDemand >= max) + newDemand = max; + if(newDemand <= min) + newDemand = min; // set and save the demand to NV storage // note that we now maintain fixed Hz and Thermostat set points seperately - if(getThermostatModeActive()) - demandDegC = newTemp; - else - demandPump = newTemp; + if(getThermostatModeActive()) { + RTC_Store.setDesiredTemp(newDemand); + } + else { + RTC_Store.setDesiredPump(newDemand); + } ScreenManager.reqUpdate(); return true; } -bool reqTempDelta(int delta) +bool reqDemandDelta(int delta) { - uint8_t newTemp; - if(getThermostatModeActive()) - newTemp = demandDegC + delta; - else - newTemp = demandPump + delta; + uint8_t newDemand; + if(getThermostatModeActive()) { + newDemand = RTC_Store.getDesiredTemp() + delta; + } + else { + newDemand = RTC_Store.getDesiredPump() + delta; + } - return reqTemp(newTemp); + return reqDemand(newDemand); } bool reqThermoToggle() @@ -997,7 +1009,7 @@ void forceBootInit() uint8_t getDemandDegC() { - return demandDegC; + return RTC_Store.getDesiredTemp(); } void setDemandDegC(uint8_t val) @@ -1005,12 +1017,12 @@ void setDemandDegC(uint8_t val) uint8_t max = DefaultBTCParams.getTemperature_Max(); uint8_t min = DefaultBTCParams.getTemperature_Min(); BOUNDSLIMIT(val, min, max); - demandDegC = val; + RTC_Store.setDesiredTemp(val); } uint8_t getDemandPump() { - return demandPump; + return RTC_Store.getDesiredPump(); } @@ -1021,9 +1033,9 @@ float getTemperatureDesired() } else { if(getThermostatModeActive()) - return demandDegC; + return RTC_Store.getDesiredTemp(); else - return demandPump; + return RTC_Store.getDesiredPump(); } } @@ -1273,7 +1285,7 @@ int getSmartError() bool isCyclicActive() { - return bUserON && NVstore.getUserSettings().cyclic.isEnabled(); + return RTC_Store.getCyclicEngaged() && NVstore.getUserSettings().cyclic.isEnabled(); } void setupGPIO() diff --git a/Delayed.txt b/Delayed.txt deleted file mode 100644 index 536b816..0000000 --- a/Delayed.txt +++ /dev/null @@ -1,53 +0,0 @@ -Hi there, - -I've been somewhat overwhelmed with requests and actually getting units built. -At the moment all PCBs I have built for the cased variety are depleted, but I will be building more PCBs over the coming days. -I have the parts, but they lack a touch of solder in the right places :-) -Please be aware this is part time affair after a day's work and currently this is consuming all my spare time! - - -An important question for the sale of the early units is does the prospect of reflashing firmware concern you? -There are still some firmware aspects I'm working on, and the web pages still need a fair bit of work. I would hate for units to become stale with old out dated firmware!! -This requires the Arduino environment to be set up for an ESP32, and in cases of dire emergency a USB to serial adapter. -Over The Air programming using WiFi is also available via batch file and a pre-compiled binary which makes this a lot easier for the firmware, but web content presently must be via the Arduino environment. - -I have two possibilities: - -1/ the controller as you can currently view in the GitLab repo. -This would be supplied as is, without a case, but I have produced a 3D model you can print. -GitLab repo: https://gitlab.com/mrjones.id.au/bluetoothheater/wikis/home - -2/ a newer version that is housed in a case. -It also provides a few conditioned I/O expansion lines: -2 digital inputs, 2 digital outputs, 1 analogue input. -The software is still yet to be fully dealt with for this aspect, but you can presently start and stop the heater, and turn outputs on or off upon command. - -Pricing: -Option 1: 50AUD + post and handling -Option 2: 75AUD + post and handling - -For domestic customers in Australia, P&H is 10AUD -For international customers P&H tends to be around 30-36AUD depending upon which region you reside. - -Payment is accepted via PayPal. - -Also please confirm your present controller is a digital style. -Please refer to my wiki at the GitLab repo: https://gitlab.com/mrjones.id.au/bluetoothheater/wikis/home -Another criteria here is what style connector you presently have. -Most have a triangular 3 pin plug, but newer units are coming with a smaller round 3 pin connector. -Please advise. - -Option 2 with the case, has a range of colours available. -Black or White case. -Black, Grey, Blue or Green buttons. - -Case for Option 1 https://www.thingiverse.com/thing:3398068 - -Rest assured the pricing is purely for the hardware. -The software will always be open source and freely available for upgrades and bug fixes. -And as mentioned, you can expect extra features to appear as time goes on. -An example of things in the todo list are Low Voltage shutdown, and a "de-coke burn" which will be full power, but a touch leaner than usual. -I'm also yet to explore a 433MHz Receive option using the garage style remote controls. - -Thanks again for your interest -Cheers, Ray \ No newline at end of file diff --git a/DieselHeaterV2.PcbDoc b/DieselHeaterV2.PcbDoc deleted file mode 100644 index dcb22ce..0000000 Binary files a/DieselHeaterV2.PcbDoc and /dev/null differ diff --git a/HeaterHack-Tested.zip b/HeaterHack-Tested.zip deleted file mode 100644 index 1fd9e42..0000000 Binary files a/HeaterHack-Tested.zip and /dev/null differ diff --git a/LukeGirard.txt b/LukeGirard.txt deleted file mode 100644 index ea85fc6..0000000 --- a/LukeGirard.txt +++ /dev/null @@ -1,23 +0,0 @@ -To: -Luke Girard, -3494 Cedar Hill Road, -Victoria, -British Columbia, -V8P 3Z1, -CANADA - - - - - - - - - - -From: -Ray Jones, -31 Wiggins Place, -Wallan, -Victoria, 3756, -AUSTRALIA \ No newline at end of file diff --git a/OTA.txt b/OTA.txt deleted file mode 100644 index 852c5b0..0000000 --- a/OTA.txt +++ /dev/null @@ -1 +0,0 @@ -C:\Users\ray\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1/tools/espota.exe -i 192.168.20.40 -p 3232 --auth= -f C:\Users\ray\AppData\Local\Temp\arduino_build_241840/BTCDieselHeater.ino.bin diff --git a/OTA_COM.txt b/OTA_COM.txt deleted file mode 100644 index b0e28d7..0000000 --- a/OTA_COM.txt +++ /dev/null @@ -1 +0,0 @@ -C:\Users\ray\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\2.6.0/esptool.exe --chip esp32 --port COM11 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0xe000 C:\Users\ray\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1/tools/partitions/boot_app0.bin 0x1000 C:\Users\ray\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1/tools/sdk/bin/bootloader_qio_80m.bin 0x10000 C:\Users\ray\AppData\Local\Temp\arduino_build_241840/BTCDieselHeater.ino.bin 0x8000 C:\Users\ray\AppData\Local\Temp\arduino_build_241840/BTCDieselHeater.ino.partitions.bin diff --git a/StandardPricing.txt b/StandardPricing.txt deleted file mode 100644 index 5c5a4c0..0000000 --- a/StandardPricing.txt +++ /dev/null @@ -1,28 +0,0 @@ -Thank you ??? for your interest. -Yes I do have some units ready to sell. - -I have two possibilities: -1/ the controller as you can currently view in the GitLab repo. -This would be supplied as is without a case. -2/ a newer version that will be housed in a case. -It will also provide a few conditioned I/O expansion lines: -2 digital inputs, 2 digital outputs, 1 analogue input. -The software is still yet to be fully dealt with for this aspect. - -Pricing: -Option 1: 50AUD + post and handling -Option 2: 65AUD + post and handling - -Post and handling to ??? would be ???AUD - -An important question for the sale of the early units is does the prospect of reflashing firmware concern you? -As you can see there are still some aspects I'm working on, and the web pages need a fair bit of work still. -This requires the Arduino environment to be set up for an ESP32, and a USB to serial adapter. -Over The Air programming using WiFi is also available which makes this a lot easier. - -Rest assured the pricing is purely for the hardware. -The software will always be open source and freely available for upgrades and bug fixes. - -Thanks again for your interest -Cheers, Ray - \ No newline at end of file diff --git a/StandardResponse.txt b/StandardResponse.txt deleted file mode 100644 index 19f4513..0000000 --- a/StandardResponse.txt +++ /dev/null @@ -1,55 +0,0 @@ -Hi there, - -An important question for the sale of the early units is does the prospect of re-flashing firmware concern you? -There are still some firmware aspects I'm working on, and the web pages do still need a fair bit of work. -I would hate for units to become stale with old out dated firmware!! - -In extreme cases this may require the Arduino environment to be set up for an ESP32, and a USB to serial adapter. -The most recent firmware though now has the ability to be readily updated via web browser, or indeed directly from my web server if connected to a wifi network when new firmware is released (only upon user authorisation). -At an intermediate level, Over The Air programming using WiFi is also available via batch file and a pre-compiled binary which is also quite straight forward. -Web page content can be updated via the web browser interface, or the Arduino environment. - -For the unit itself I have two possibilities: - -1/ the Mk1 controller as you can currently view in the GitLab repo: https://gitlab.com/mrjones.id.au/bluetoothheater/wikis/home -This would be supplied as is, without a case, but I have produced a 3D model you can print: https://www.thingiverse.com/thing:3398068 - -2/ a newer Mk2 version that is housed in a case. -It also provides a few conditioned I/O expansion lines: -2 digital inputs, 2 digital outputs, 1 analogue input. -The software is still yet to be fully dealt with for this aspect, but you can presently start and stop the heater, and turn outputs on or off upon command. - -Please visit my webpage http://www.mrjones.id.au/afterburner for examples of the unit in a case, and the full capabilities of the unit. -There you can also find the user manual. - -Pricing: -Option 1: 50AUD + post and handling -Option 2: 75AUD + post and handling - -For domestic customers in Australia, P&H is 10AUD -For international customers P&H tends to be around 30-36AUD depending upon which region you reside. - -Payment is accepted via PayPal. - -Also please confirm your present controller is a digital style. -Please refer to my wiki at the GitLab repo: https://gitlab.com/mrjones.id.au/bluetoothheater/wikis/home or the user manual from my website. - -Another important criteria here is what style connector you presently have. -Most have a triangular 3 pin plug, but newer units are coming with a smaller round 3 pin connector. -Please advise, i will supply the appropriate style connector with the unit. - -Option 2 with the case, has a range of colours available. -Black or White case. -Black, Grey, Blue or Green buttons. - -Please note there is typically a week delay as I do this in my "spare time" and demand can be high at times. - -Rest assured the pricing is purely for the hardware and my time to build. -The software will always be open source and freely available for upgrades and bug fixes. -And as mentioned, you can expect extra features to appear as time goes on. -An example of things in the todo list are Low Voltage shutdown, and a "de-coke burn" which will be full power, but a touch leaner than usual. -I'm also yet to explore a 433MHz Receive option using the garage style remote controls. - -Thanks again for your interest -Cheers, Ray - diff --git a/src/Afterburner/Afterburner.cpp b/src/Afterburner/Afterburner.cpp index 12ace0c..b033a45 100644 --- a/src/Afterburner/Afterburner.cpp +++ b/src/Afterburner/Afterburner.cpp @@ -183,10 +183,14 @@ bool bHasHtrData = false; // these variables will persist over a soft reboot. __NOINIT_ATTR bool bForceInit; // = false; -__NOINIT_ATTR bool bUserON; // = false; -__NOINIT_ATTR uint8_t demandDegC; -__NOINIT_ATTR uint8_t demandPump; +//__NOINIT_ATTR bool bUserON; // = false; +//__NOINIT_ATTR uint8_t demandDegC; +//__NOINIT_ATTR uint8_t demandPump; +//uint8_t demandDegC; +//uint8_t demandPump; +//bool bCyclicEngaged; CFuelGauge FuelGauge; +CRTC_Store RTC_Store; bool bReportBlueWireData = REPORT_RAW_DATA; bool bReportJSONData = REPORT_JSON_TRANSMIT; @@ -305,13 +309,11 @@ extern "C" unsigned long __wrap_millis() { void setup() { // ensure cyclic mode is disabled after power on - bool bPowerUpInit = false; - if(rtc_get_reset_reason(0) == 1/* || bForceInit*/) { - bPowerUpInit = true; - bForceInit = false; - bUserON = false; - demandPump = demandDegC = 22; - } +// bool bPowerUpInit = false; +// if(rtc_get_reset_reason(0) == 1/* || bForceInit*/) { +// bPowerUpInit = true; +// bForceInit = false; +// } // initially, ensure the GPIO outputs are not activated during startup // (GPIO2 tends to be one with default chip startup) @@ -334,7 +336,7 @@ void setup() { DebugPort.println("_______________________________________________________________"); DebugPort.printf("Reset reason: core0:%d, core1:%d\r\n", rtc_get_reset_reason(0), rtc_get_reset_reason(0)); - DebugPort.printf("Previous user ON = %d\r\n", bUserON); // state flag required for cyclic mode to persist properly after a WD reboot :-) +// DebugPort.printf("Previous user ON = %d\r\n", bUserON); // state flag required for cyclic mode to persist properly after a WD reboot :-) // initialise DS18B20 sensor interface TempSensor.begin(DS18B20_Pin); @@ -383,6 +385,9 @@ void setup() { BootTime = Clock.get().secondstime(); ScreenManager.begin(bNoClock); + if(!bNoClock && Clock.lostPower()) { + ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::SetClockUI); + } #if USE_WIFI == 1 @@ -442,9 +447,12 @@ void setup() { FilteredSamples.Fan.setAlpha(0.7); FilteredSamples.AmbientTemp.reset(-100.0); -// if(bPowerUpInit) { - FuelGauge.init(); -// } + RTC_Store.begin(); + FuelGauge.init(RTC_Store.getFuelGauge()); +// demandDegC = RTC_Store.getDesiredTemp(); +// demandPump = RTC_Store.getDesiredPump(); +// bCyclicEngaged = RTC_Store.getCyclicEngaged(); + DebugPort.printf("Previous cyclic active = %d\r\n", RTC_Store.getCyclicEngaged()); // state flag required for cyclic mode to persist properly after a WD reboot :-) delay(1000); // just to hold the splash screeen for while } @@ -812,7 +820,7 @@ void DebugReportFrame(const char* hdr, const CProtocol& Frame, const char* ftr) void manageCyclicMode() { const sCyclicThermostat& cyclic = NVstore.getUserSettings().cyclic; - if(cyclic.Stop && bUserON) { // cyclic mode enabled, and user has started heater + if(cyclic.Stop && RTC_Store.getCyclicEngaged()) { // cyclic mode enabled, and user has started heater int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over! float deltaT = FilteredSamples.AmbientTemp.getValue() - getDemandDegC(); // DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT); @@ -876,13 +884,13 @@ bool validateFrame(const CProtocol& frame, const char* name) void requestOn() { heaterOn(); - bUserON = true; // for cyclic mode + RTC_Store.setCyclicEngaged(true); // for cyclic mode } void requestOff() { heaterOff(); - bUserON = false; // for cyclic mode + RTC_Store.setCyclicEngaged(false); // for cyclic mode } void heaterOn() @@ -898,38 +906,42 @@ void heaterOff() } -bool reqTemp(uint8_t newTemp, bool save) +bool reqDemand(uint8_t newDemand, bool save) { if(bHasOEMController) return false; uint8_t max = DefaultBTCParams.getTemperature_Max(); uint8_t min = DefaultBTCParams.getTemperature_Min(); - if(newTemp >= max) - newTemp = max; - if(newTemp <= min) - newTemp = min; + if(newDemand >= max) + newDemand = max; + if(newDemand <= min) + newDemand = min; // set and save the demand to NV storage // note that we now maintain fixed Hz and Thermostat set points seperately - if(getThermostatModeActive()) - demandDegC = newTemp; - else - demandPump = newTemp; + if(getThermostatModeActive()) { + RTC_Store.setDesiredTemp(newDemand); + } + else { + RTC_Store.setDesiredPump(newDemand); + } ScreenManager.reqUpdate(); return true; } -bool reqTempDelta(int delta) +bool reqDemandDelta(int delta) { - uint8_t newTemp; - if(getThermostatModeActive()) - newTemp = demandDegC + delta; - else - newTemp = demandPump + delta; + uint8_t newDemand; + if(getThermostatModeActive()) { + newDemand = RTC_Store.getDesiredTemp() + delta; + } + else { + newDemand = RTC_Store.getDesiredPump() + delta; + } - return reqTemp(newTemp); + return reqDemand(newDemand); } bool reqThermoToggle() @@ -997,7 +1009,7 @@ void forceBootInit() uint8_t getDemandDegC() { - return demandDegC; + return RTC_Store.getDesiredTemp(); } void setDemandDegC(uint8_t val) @@ -1005,12 +1017,12 @@ void setDemandDegC(uint8_t val) uint8_t max = DefaultBTCParams.getTemperature_Max(); uint8_t min = DefaultBTCParams.getTemperature_Min(); BOUNDSLIMIT(val, min, max); - demandDegC = val; + RTC_Store.setDesiredTemp(val); } uint8_t getDemandPump() { - return demandPump; + return RTC_Store.getDesiredPump(); } @@ -1021,9 +1033,9 @@ float getTemperatureDesired() } else { if(getThermostatModeActive()) - return demandDegC; + return RTC_Store.getDesiredTemp(); else - return demandPump; + return RTC_Store.getDesiredPump(); } } @@ -1273,7 +1285,7 @@ int getSmartError() bool isCyclicActive() { - return bUserON && NVstore.getUserSettings().cyclic.isEnabled(); + return RTC_Store.getCyclicEngaged() && NVstore.getUserSettings().cyclic.isEnabled(); } void setupGPIO() diff --git a/src/Afterburner/src/OLED/BasicScreen.cpp b/src/Afterburner/src/OLED/BasicScreen.cpp index 06df4bf..9538c88 100644 --- a/src/Afterburner/src/OLED/BasicScreen.cpp +++ b/src/Afterburner/src/OLED/BasicScreen.cpp @@ -231,7 +231,7 @@ CBasicScreen::keyHandler(uint8_t event) if(!_showModeTime) { // release DOWN key to reduce set demand, provided we are not in mode select if(event & key_Down) { - if(reqTempDelta(-1)) { + if(reqDemandDelta(-1)) { _showSetModeTime = millis() + 2000; _feedbackType = 0; _ScreenManager.reqUpdate(); @@ -241,7 +241,7 @@ CBasicScreen::keyHandler(uint8_t event) } // release UP key to increase set demand, provided we are not in mode select if(event & key_Up) { - if(reqTempDelta(+1)) { + if(reqDemandDelta(+1)) { _showSetModeTime = millis() + 2000; _feedbackType = 0; _ScreenManager.reqUpdate(); diff --git a/src/Afterburner/src/OLED/DetailedScreen.cpp b/src/Afterburner/src/OLED/DetailedScreen.cpp index 63bfc76..68308fe 100644 --- a/src/Afterburner/src/OLED/DetailedScreen.cpp +++ b/src/Afterburner/src/OLED/DetailedScreen.cpp @@ -251,11 +251,11 @@ CDetailedScreen::keyHandler(uint8_t event) if(event & keyReleased) { if(_keyRepeatCount == 0) { // short Up press - lower target if(event & key_Up) { - if(reqTempDelta(+1)) _showTarget = millis() + 3500; + if(reqDemandDelta(+1)) _showTarget = millis() + 3500; else _reqOEMWarning(); } if(event & key_Down) { // short Down press - lower target - if(reqTempDelta(-1)) _showTarget = millis() + 3500; + if(reqDemandDelta(-1)) _showTarget = millis() + 3500; else _reqOEMWarning(); } if(event & key_Centre) { // short Centre press - show target diff --git a/src/Afterburner/src/OLED/ScreenManager.cpp b/src/Afterburner/src/OLED/ScreenManager.cpp index 63e5e27..f71dad6 100644 --- a/src/Afterburner/src/OLED/ScreenManager.cpp +++ b/src/Afterburner/src/OLED/ScreenManager.cpp @@ -385,7 +385,7 @@ CScreenManager::checkUpdate() if(runState > 0 && prevRunState == 0) { // heater has started uint8_t userStartMenu = NVstore.getUserSettings().HomeMenu.onStart; - if(userStartMenu && userStartMenu <= 3) { // allow user to override defualt screen + if(userStartMenu && userStartMenu <= 3) { // allow user to override default screen userStartMenu--; DebugPort.print("Screen Manager: Heater start detected, switching to user preferred screen: "); switch(userStartMenu) { @@ -397,10 +397,10 @@ CScreenManager::checkUpdate() _enterScreen(); } } - if(runState == 0 && prevRunState != 0) { + if(runState == 0 && prevRunState > 0) { // heater has stopped uint8_t userStopMenu = NVstore.getUserSettings().HomeMenu.onStop; - if(userStopMenu && userStopMenu <= 3) { // allow user to override defualt screen + if(userStopMenu && userStopMenu <= 3) { // allow user to override default screen userStopMenu--; DebugPort.print("Screen Manager: Heater stop detected, switching to user preferred screen: "); switch(userStopMenu) { @@ -544,6 +544,7 @@ CScreenManager::selectMenu(eUIMenuSets menuSet, int specific) // targetting a specific menu _subMenu = specific; UPPERLIMIT(_subMenu, _Screens[_menu].size()-1); // check bounds! + DebugPort.printf("selectMenu %d %d\r\n", _menu, _subMenu); } else { // default sub menu behaviour @@ -574,7 +575,7 @@ CScreenManager::showOTAMessage(int percent, eOTAmodes updateType) static long prevTime = millis(); long tDelta = millis() - prevTime; - if(percent != prevPercent && tDelta > 500) { + if(percent != prevPercent/* && tDelta > 500*/) { prevTime = millis(); _pDisplay->clearDisplay(); _pDisplay->setCursor(64,22); diff --git a/src/Afterburner/src/RTC/Clock.cpp b/src/Afterburner/src/RTC/Clock.cpp index 2da6036..1e1aeb7 100644 --- a/src/Afterburner/src/RTC/Clock.cpp +++ b/src/Afterburner/src/RTC/Clock.cpp @@ -117,6 +117,17 @@ CClock::readData(uint8_t* pData, int len, int ofs) _rtc.readData(pData, len, ofs); } +bool +CClock::lostPower() +{ + return _rtc.lostPower(); +} + +void +CClock::resetLostPower() +{ + _rtc.resetLostPower(); +} void setDateTime(const char* newTime) { @@ -153,7 +164,8 @@ void setTime(const char* newTime) #define _I2C_WRITE write #define _I2C_READ read -void RTC_DS3231Ex::writeData(uint8_t* pData, int len, int ofs) { +void +RTC_DS3231Ex::writeData(uint8_t* pData, int len, int ofs) { Wire.beginTransmission(DS3231_ADDRESS); Wire._I2C_WRITE((byte)(7+ofs)); // start at alarm bytes for(int i=0; ikey) == 0) { - if( !reqTemp(it->value.as(), false) ) { // this request is blocked if OEM controller active + if( !reqDemand(it->value.as(), false) ) { // this request is blocked if OEM controller active JSONmoderator.reset("TempDesired"); } } @@ -265,6 +265,21 @@ void interpretJsonCommand(char* pLine) NVstore.setUserSettings(us); NVstore.save(); } + else if(strcmp("PumpCount", it->key) == 0) { // reset fuel gauge + int Count = it->value.as(); + if(Count == 0) { + RTC_Store.setFuelGauge(0); + } + } + else if(strcmp("PumpCal", it->key) == 0) { + float fCal = it->value.as(); + if(INBOUNDS(fCal, 0.001, 1)) { + sHeaterTuning ht = NVstore.getHeaterTuning(); + ht.pumpCal = fCal; + NVstore.setHeaterTuning(ht); + NVstore.save(); + } + } } } @@ -340,6 +355,8 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len) bSend |= moderator.addJson("CyclicTemp", getDemandDegC(), root); // actual pivot point for cyclic mode bSend |= moderator.addJson("CyclicOff", stop, root); // threshold of over temp for cyclic mode bSend |= moderator.addJson("CyclicOn", NVstore.getUserSettings().cyclic.Start, root); // threshold of under temp for cyclic mode + bSend |= moderator.addJson("PumpCount", RTC_Store.getFuelGauge(), root); // running count of pump strokes + bSend |= moderator.addJson("PumpCal", NVstore.getHeaterTuning().pumpCal, root); // ml/stroke if(bSend) { root.printTo(opStr, len); diff --git a/src/Afterburner/src/Utility/FuelGauge.cpp b/src/Afterburner/src/Utility/FuelGauge.cpp index 65870b4..0434632 100644 --- a/src/Afterburner/src/Utility/FuelGauge.cpp +++ b/src/Afterburner/src/Utility/FuelGauge.cpp @@ -19,78 +19,28 @@ * */ -// -// We need to identify the PCB the firmware is running upon for 2 reasons related to GPIO functions -// -// 1: Digital Inputs -// To the outside world, the digital inputs are always treated as contact closures to ground. -// V1.0 PCBs expose the bare ESP inputs for GPIO, they are normally pulled HIGH. -// V2.0+ PCBs use an input conditioning transistor that inverts the sense state. -// Inactive state for V1.0 is HIGH -// Inactive state for V2.0+ is LOW -// -// 2: Analogue input -// Unfortunately the pin originally chosen for the analogue input on the V2.0 PCB goes to -// an ADC2 channel of the ESP32. -// It turns out NONE of the 10 ADC2 channels can be used if Wifi is enabled! -// The remedy on V2.0 PCBs is to cut the traces leading from Digital input 1 and the Analogue input. -// The signals are then tranposed. -// This then presents Digital Input #1 to GPIO26, and analogue to GPIO33. -// As GPIO33 uses an ADC1 channel no issue is present reading analogue values with wifi enabled. -// -// Board Detection -// Fortunately due to the use of the digital input transistors on V2.0+ PCBs, a logical -// determination of the board configuration can be made. -// By setting the pins as digital inputs with pull ups enabled, the logic level presented -// can be read and thus the input signal paths can be determined. -// Due to the input conditioning transistors, V2.0 PCBs will hold the inputs to the ESP32 -// LOW when inactive, V1.0 PCBs will pull HIGH. -// Likewise, the analogue input is left to float, so it will always be pulled HIGH. -// NOTE: a 100nF capacitor exists on the analogue input so a delay is required to ensure -// a reliable read. -// -// Input state truth table -// GPIO26 GPIO33 -// ------ ------ -// V1.0 HIGH HIGH -// unmodified V2.0 HIGH LOW -// modified V2.0 LOW HIGH -// V2.1 LOW HIGH -// -// -// **************************************************************************************** -// This test only needs to be performed upon the very first firmware execution. -// Once the board has been identified, the result is saved to non volatile memory -// If a valid value is detected, the test is bypassed. -// This avoids future issues should the GPIO inputs be legitimately connected to -// extension hardware that may distort the test results when the system is repowered. -// **************************************************************************************** -// #include "FuelGauge.h" #include "NVStorage.h" #include "DebugPort.h" +#include "../RTC/Clock.h" CFuelGauge::CFuelGauge() { - _tank_mL = 0; + _pumpStrokes = 0; _pumpCal = 0.02; - record.lastsave = millis(); - record.storedval = _tank_mL; + _lastStoredVal = _pumpStrokes; DebugPort.println("CFuelGauge::CFuelGauge"); } void -CFuelGauge::init() +CFuelGauge::init(float fuelUsed) { _pumpCal = NVstore.getHeaterTuning().pumpCal; - float testVal; - getStoredFuelGauge(testVal); // RTC registers used to store this - if(INBOUNDS(testVal, 0, 200000)) { - DebugPort.printf("Initialising fuel gauge with %.2fmL\r\n", testVal); - _tank_mL = testVal; - record.storedval = _tank_mL; - } + + _pumpStrokes = fuelUsed; + DebugPort.printf("Initialising fuel gauge with %.2f strokes\r\n", _pumpStrokes); + _lastStoredVal = _pumpStrokes; } @@ -101,16 +51,14 @@ CFuelGauge::Integrate(float Hz) long tSample = timenow - _lasttime; _lasttime = timenow; - _tank_mL += Hz * tSample * 0.001 * _pumpCal; // Hz * seconds * mL / stroke + _pumpStrokes += Hz * tSample * 0.001; // Hz * seconds - long tDiff = millis() - record.lastsave; - float fuelDelta = _tank_mL - record.storedval; - bool bStoppedSave = (Hz == 0) && (_tank_mL != record.storedval); - if(tDiff > 600000 || fuelDelta > 1 || bStoppedSave) { // record fuel usage every 10 minutes, or every 5mL used - DebugPort.printf("Storing fuel gauge: %.2fmL\r\n", _tank_mL); - storeFuelGauge(_tank_mL); // uses RTC registers to store this - record.lastsave = millis(); - record.storedval = _tank_mL; + float fuelDelta = _pumpStrokes - _lastStoredVal; + bool bStoppedSave = (Hz == 0) && (_pumpStrokes != _lastStoredVal); + if(fuelDelta > 10 || bStoppedSave) { // record fuel usage every 10 minutes, or every 10 strokes + DebugPort.printf("Storing fuel gauge: %.2f strokes\r\n", _pumpStrokes); + RTC_Store.setFuelGauge(_pumpStrokes); // uses RTC registers to store this + _lastStoredVal = _pumpStrokes; } } @@ -118,5 +66,5 @@ CFuelGauge::Integrate(float Hz) float CFuelGauge::Used_mL() { - return _tank_mL; + return _pumpStrokes * _pumpCal; // strokes * mL / stroke } diff --git a/src/Afterburner/src/Utility/FuelGauge.h b/src/Afterburner/src/Utility/FuelGauge.h index d66131a..912dc1d 100644 --- a/src/Afterburner/src/Utility/FuelGauge.h +++ b/src/Afterburner/src/Utility/FuelGauge.h @@ -25,16 +25,13 @@ #include class CFuelGauge { - float _tank_mL; + float _pumpStrokes; unsigned long _lasttime; float _pumpCal; - struct { - unsigned long lastsave; - float storedval; - } record; + float _lastStoredVal; public: CFuelGauge(); - void init(); + void init(float fuelUsed = 0); void Integrate(float Hz); float Used_mL(); }; diff --git a/src/Afterburner/src/Utility/helpers.h b/src/Afterburner/src/Utility/helpers.h index 7346826..95f07a7 100644 --- a/src/Afterburner/src/Utility/helpers.h +++ b/src/Afterburner/src/Utility/helpers.h @@ -31,8 +31,8 @@ extern void forceBootInit(); extern void requestOn(); extern void requestOff(); -extern bool reqTempDelta(int delta); -extern bool reqTemp(uint8_t newTemp, bool save=true); +extern bool reqDemandDelta(int delta); +extern bool reqDemand(uint8_t newTemp, bool save=true); extern bool reqThermoToggle(); extern bool setThermostatMode(uint8_t); extern bool getThermostatModeActive(); // OEM: actual mode from blue wire, BTC: or our NV @@ -84,12 +84,12 @@ extern float getGlowCurrent(); extern float getFanSpeed(); extern int sysUptime(); -extern void storeFuelGauge(float val); -extern void getStoredFuelGauge(float& val); -extern void storeDesiredTemp(uint8_t val); -extern void getStoredDesiredTemp(uint8_t& val); -extern void storeDesiredPump(uint8_t val); -extern void getStoredDesiredPump(uint8_t& val); +/* extern void setFuelGauge_RTC(float val); +extern void getFuelGauge_RTC(float& val); +extern void setDesiredTemp_RTC(uint8_t val); +extern void getDesiredTemp_RTC(uint8_t& val); +extern void setDesiredPump_RTC(uint8_t val); +extern void getDesiredPump_RTC(uint8_t& val);*/ extern void ShowOTAScreen(int percent=0, eOTAmodes updateType=eOTAnormal);