Revised HC05 setup code

HeaterManager introduced
433MHz remote support
This commit is contained in:
Ray Jones 2020-06-19 09:44:14 +10:00
parent 2548191173
commit 2f1605e6a3
85 changed files with 939 additions and 450 deletions

Binary file not shown.

View file

@ -1,5 +1,5 @@
REM Firmware REM Firmware
esptool.exe --chip esp32 --port COM5 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0xe000 boot_app0.bin 0x1000 bootloader_qio_80m.bin 0x10000 AfterburnerV3.1.9.bin 0x8000 Afterburner.partitions.bin esptool.exe --chip esp32 --port COM5 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0xe000 boot_app0.bin 0x1000 bootloader_qio_80m.bin 0x10000 Afterburner.bin 0x8000 Afterburner.partitions.bin
REM SPIFFS REM SPIFFS
esptool.exe --chip esp32 --port COM5 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_size detect 0x3d0000 spiffs.bin esptool.exe --chip esp32 --port COM5 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_size detect 0x3d0000 spiffs.bin

Binary file not shown.

View file

@ -120,7 +120,8 @@
#include "RTC/TimerManager.h" #include "RTC/TimerManager.h"
#include "Utility/GetLine.h" #include "Utility/GetLine.h"
#include "Utility/DemandManager.h" #include "Utility/DemandManager.h"
#include "Protocol/BlueWireTask.h" #include "Protocol/HeaterManager.h"
#include "Protocol/433MHz.h"
#if USE_TWDT == 1 #if USE_TWDT == 1
#include "esp_task_wdt.h" #include "esp_task_wdt.h"
#endif #endif
@ -131,10 +132,10 @@
// #define RX_DATA_TIMOUT 50 // #define RX_DATA_TIMOUT 50
const int FirmwareRevision = 32; const int FirmwareRevision = 40;
const int FirmwareSubRevision = 0; const int FirmwareSubRevision = 0;
const int FirmwareMinorRevision = 0; const int FirmwareMinorRevision = 1;
const char* FirmwareDate = "21 May 2020"; const char* FirmwareDate = "22 May 2020";
/* /*
* Macro to check the outputs of TWDT functions and trigger an abort if an * Macro to check the outputs of TWDT functions and trigger an abort if an
@ -165,11 +166,11 @@ void manageHumidity();
void doStreaming(); void doStreaming();
void heaterOn(); void heaterOn();
void heaterOff(); void heaterOff();
void updateFilteredData(CProtocol& HeaterInfo);
bool HandleMQTTsetup(char rxVal); bool HandleMQTTsetup(char rxVal);
void showMainmenu(); void showMainmenu();
bool checkTemperatureSensors(); bool checkTemperatureSensors();
void checkBlueWireEvents(); void checkBlueWireEvents();
void checkUHF();
// DS18B20 temperature sensor support // DS18B20 temperature sensor support
// Uses the RMT timeslot driver to operate as a one-wire bus // Uses the RMT timeslot driver to operate as a one-wire bus
@ -201,8 +202,9 @@ CGPIOalg GPIOalg;
CMQTTsetup MQTTmenu; CMQTTsetup MQTTmenu;
CSecuritySetup SecurityMenu; CSecuritySetup SecurityMenu;
TaskHandle_t handleWatchdogTask; TaskHandle_t handleWatchdogTask = NULL;
TaskHandle_t handleBlueWireTask; // TaskHandle_t handleBlueWireTask = NULL;
// TaskHandle_t handleAltCtrlTask = NULL;
extern TaskHandle_t handleWebServerTask; extern TaskHandle_t handleWebServerTask;
// these variables will persist over a soft reboot. // these variables will persist over a soft reboot.
@ -217,10 +219,8 @@ bool bReportBlueWireData = REPORT_RAW_DATA;
bool bReportJSONData = REPORT_JSON_TRANSMIT; bool bReportJSONData = REPORT_JSON_TRANSMIT;
bool bReportRecyleEvents = REPORT_BLUEWIRE_RECYCLES; bool bReportRecyleEvents = REPORT_BLUEWIRE_RECYCLES;
bool bReportOEMresync = REPORT_OEM_RESYNC; bool bReportOEMresync = REPORT_OEM_RESYNC;
bool pair433MHz = false;
CProtocol BlueWireRxData;
CProtocol BlueWireTxData;
CProtocolPackage BlueWireData;
bool bUpdateDisplay = false; bool bUpdateDisplay = false;
bool bHaveWebClient = false; bool bHaveWebClient = false;
@ -282,48 +282,70 @@ CBluetoothAbstract& getBluetoothClient()
return Bluetooth; return Bluetooth;
} }
char taskMsg[BLUEWIRE_MSGQUEUESIZE]; // char taskMsg[BLUEWIRE_MSGQUEUESIZE];
void checkBlueWireEvents() void checkBlueWireEvents()
{ {
// collect and report any debug messages from the blue wire task // collect and report any debug messages from the blue wire task
if(BlueWireMsgQueue && xQueueReceive(BlueWireMsgQueue, taskMsg, 0)) // if(BlueWireMsgQueue && xQueueReceive(BlueWireMsgQueue, taskMsg, 0))
DebugPort.print(taskMsg); // DebugPort.print(taskMsg);
// check for complted data exchange from the blue wire task // if(AltCommsTask.getMsgQueue(taskMsg))
if(BlueWireSemaphore && xSemaphoreTake(BlueWireSemaphore, 0)) { // DebugPort.print(taskMsg);
// QueueHandle_t MsgQueue = HeaterManager.getMsgQueue();
// if(MsgQueue && xQueueReceive(MsgQueue, taskMsg, 0))
// DebugPort.print(taskMsg);
// if(AltControllerMsgQueue && xQueueReceive(AltControllerMsgQueue, taskMsg, 0))
// DebugPort.print(taskMsg);
// check for completed data exchange from the blue wire task
SemaphoreHandle_t handleSemaphore;
handleSemaphore = HeaterManager.getSemaphore();
if(handleSemaphore && xSemaphoreTake(handleSemaphore, 0)) {
updateJSONclients(bReportJSONData); updateJSONclients(bReportJSONData);
updateMQTT(); updateMQTT();
NVstore.doSave(); // now is a good time to store to the NV storage, well away from any blue wire activity NVstore.doSave(); // now is a good time to store to the NV storage, well away from any blue wire activity
} }
// collect transmitted heater data from blue wire task // // collect transmitted heater data from blue wire task
if(BlueWireTxQueue && xQueueReceive(BlueWireTxQueue, BlueWireTxData.Data, 0)) { // if(BlueWireTxQueue && xQueueReceive(BlueWireTxQueue, BlueWireTxData.Data, 0)) {
} // }
// collect and process received heater data from blue wire task // // collect and process received heater data from blue wire task
if(BlueWireRxQueue && xQueueReceive(BlueWireRxQueue, BlueWireRxData.Data, 0)) { // if(BlueWireRxQueue && xQueueReceive(BlueWireRxQueue, BlueWireRxData.Data, 0)) {
BlueWireData.set(BlueWireRxData, BlueWireTxData); // BlueWireData.set(BlueWireRxData, BlueWireTxData);
SmartError.monitor(BlueWireRxData); // SmartError.monitor(BlueWireRxData);
updateFilteredData(BlueWireRxData); // updateFilteredData(BlueWireRxData);
FuelGauge.Integrate(BlueWireRxData.getPump_Actual()); // FuelGauge.Integrate(BlueWireRxData.getPump_Actual());
if(INBOUNDS(BlueWireRxData.getRunState(), 1, 5)) { // check for Low Voltage Cutout // if(INBOUNDS(BlueWireRxData.getRunState(), 1, 5)) { // check for Low Voltage Cutout
SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue()); // SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
SmartError.checkfuelUsage(); // SmartError.checkfuelUsage();
} // }
// trap being in state 0 with a heater error - cancel user on memory to avoid unexpected cyclic restarts // // trap being in state 0 with a heater error - cancel user on memory to avoid unexpected cyclic restarts
if(RTC_Store.getUserStart() && (BlueWireRxData.getRunState() == 0) && (BlueWireRxData.getErrState() > 1)) { // if(RTC_Store.getUserStart() && (BlueWireRxData.getRunState() == 0) && (BlueWireRxData.getErrState() > 1)) {
DebugPort.println("Forcing cyclic cancel due to error induced shutdown"); // DebugPort.println("Forcing cyclic cancel due to error induced shutdown");
// DebugPort.println("Forcing cyclic cancel due to error induced shutdown"); // // DebugPort.println("Forcing cyclic cancel due to error induced shutdown");
RTC_Store.setUserStart(false); // RTC_Store.setUserStart(false);
} // }
pHourMeter->monitor(BlueWireRxData); // pHourMeter->monitor(BlueWireRxData);
} // }
// int AltHeater;
// if(AltRxQueue && xQueueReceive(AltRxQueue, &AltHeater, 0)) {
// decodeAltHeater(AltHeater);
// }
// isAltActive();
HeaterManager.checkMsgEvents();
HeaterManager.checkTxEvents();
HeaterManager.checkRxEvents();
} }
@ -593,15 +615,15 @@ void setup() {
TempSensor.getDS18B20().mapSensor(1, NVstore.getHeaterTuning().DS18B20probe[1].romCode); TempSensor.getDS18B20().mapSensor(1, NVstore.getHeaterTuning().DS18B20probe[1].romCode);
TempSensor.getDS18B20().mapSensor(2, NVstore.getHeaterTuning().DS18B20probe[2].romCode); TempSensor.getDS18B20().mapSensor(2, NVstore.getHeaterTuning().DS18B20probe[2].romCode);
// create task to run blue wire interface // create task to run heater comms
xTaskCreate(BlueWireTask, // HeaterManager.setHeaterStyle(1); // alternate blue digit LCD
"BlueWireTask", // HeaterManager.setHeaterStyle(0); // conventional blue wire
1600, if(HeaterManager.detect())
NULL, DebugPort.printf("Detected heater type %d\r\r", HeaterManager.getHeaterStyle());
TASK_PRIORITY_HEATERCOMMS, else
&handleBlueWireTask); DebugPort.println("UNABLE TO DETECT HEATER???");
UHFremote.begin(Rx433MHz_pin, RMT_CHANNEL_4);
delay(1000); // just to hold the splash screeen for while delay(1000); // just to hold the splash screeen for while
@ -632,6 +654,8 @@ void loop()
checkBlueWireEvents(); checkBlueWireEvents();
checkUHF();
vTaskDelay(1); vTaskDelay(1);
} // loop } // loop
@ -645,9 +669,10 @@ bool checkTemperatureSensors()
if(bReportStack) { if(bReportStack) {
DebugPort.println("Stack high water marks"); DebugPort.println("Stack high water marks");
DebugPort.printf(" Arduino: %d\r\n", uxTaskGetStackHighWaterMark(NULL)); DebugPort.printf(" Arduino: %d\r\n", uxTaskGetStackHighWaterMark(NULL));
DebugPort.printf(" BlueWire: %d\r\n", uxTaskGetStackHighWaterMark(handleBlueWireTask)); const TaskHandle_t handleCommsTask = HeaterManager.getTaskHandle();
DebugPort.printf(" Watchdog: %d\r\n", uxTaskGetStackHighWaterMark(handleWatchdogTask)); if(handleCommsTask) DebugPort.printf(" Heater Comms: %d\r\n", uxTaskGetStackHighWaterMark(handleCommsTask));
DebugPort.printf(" SSL loop: %d\r\n", uxTaskGetStackHighWaterMark(handleWebServerTask)); if(handleWatchdogTask) DebugPort.printf(" Watchdog: %d\r\n", uxTaskGetStackHighWaterMark(handleWatchdogTask));
if(handleWebServerTask) DebugPort.printf(" SSL loop: %d\r\n", uxTaskGetStackHighWaterMark(handleWebServerTask));
} }
TempSensor.readSensors(); TempSensor.readSensors();
@ -685,7 +710,8 @@ void manageStopStartMode()
if(NVstore.getUserSettings().ThermostatMethod == 4 && RTC_Store.getUserStart() ) { if(NVstore.getUserSettings().ThermostatMethod == 4 && RTC_Store.getUserStart() ) {
float deltaT = getTemperatureSensor() - CDemandManager::getDegC(); float deltaT = getTemperatureSensor() - CDemandManager::getDegC();
float thresh = NVstore.getUserSettings().ThermostatWindow/2; float thresh = NVstore.getUserSettings().ThermostatWindow/2;
int heaterState = getHeaterInfo().getRunState(); // native heater state // int heaterState = getHeaterInfo().getRunState(); // native heater state
int heaterState = HeaterManager.getRunState(); // native heater state
if(deltaT > thresh) { if(deltaT > thresh) {
if(heaterState > 0 && heaterState <= 5) { if(heaterState > 0 && heaterState <= 5) {
DebugPort.printf("STOP START MODE: Stopping heater, deltaT > +%.1f\r\n", thresh); DebugPort.printf("STOP START MODE: Stopping heater, deltaT > +%.1f\r\n", thresh);
@ -710,13 +736,15 @@ void manageCyclicMode()
// DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT); // DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT);
// ensure we cancel user ON mode if heater throws an error // ensure we cancel user ON mode if heater throws an error
int errState = getHeaterInfo().getErrState(); // int errState = getHeaterInfo().getErrState();
int errState = HeaterManager.getErrState();
if((errState > 1) && (errState < 12) && (errState != 8)) { if((errState > 1) && (errState < 12) && (errState != 8)) {
// excludes errors 0,1(OK), 12(E1-11,Retry) & 8(E-07,Comms Error) // excludes errors 0,1(OK), 12(E1-11,Retry) & 8(E-07,Comms Error)
DebugPort.println("CYCLIC MODE: cancelling user ON status"); DebugPort.println("CYCLIC MODE: cancelling user ON status");
requestOff(); // forcibly cancel cyclic operation - pretend user pressed OFF requestOff(); // forcibly cancel cyclic operation - pretend user pressed OFF
} }
int heaterState = getHeaterInfo().getRunState(); // int heaterState = getHeaterInfo().getRunState();
int heaterState = HeaterManager.getRunState();
// check if over temp, turn off heater // check if over temp, turn off heater
if(deltaT > stopDeltaT) { if(deltaT > stopDeltaT) {
if(heaterState > 0 && heaterState <= 5) { if(heaterState > 0 && heaterState <= 5) {
@ -741,7 +769,8 @@ void manageFrostMode()
uint8_t engage = NVstore.getUserSettings().FrostOn; uint8_t engage = NVstore.getUserSettings().FrostOn;
if(engage) { if(engage) {
float deltaT = getTemperatureSensor() - engage; float deltaT = getTemperatureSensor() - engage;
int heaterState = getHeaterInfo().getRunState(); // int heaterState = getHeaterInfo().getRunState();
int heaterState = HeaterManager.getRunState();
if(deltaT < 0) { if(deltaT < 0) {
if(heaterState == 0) { if(heaterState == 0) {
RTC_Store.setFrostOn(true); RTC_Store.setFrostOn(true);
@ -782,14 +811,20 @@ void manageHumidity()
CDemandManager::eStartCode CDemandManager::eStartCode
requestOn() requestOn()
{ {
bool altHeater = HeaterManager.getHeaterStyle() == 1;
if(HeaterManager.getRunState()) // already running?
return CDemandManager::eStartOK;
DebugPort.println("Start Request!"); DebugPort.println("Start Request!");
bool fuelOK = 2 != SmartError.checkfuelUsage();
bool fuelOK = 2 != SmartError.checkfuelUsage() || altHeater;
if(!fuelOK) { if(!fuelOK) {
DebugPort.println("Start denied - Low fuel"); DebugPort.println("Start denied - Low fuel");
return CDemandManager::eStartLowFuel; return CDemandManager::eStartLowFuel;
} }
bool LVCOK = 2 != SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue()); bool LVCOK = 2 != SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
if(hasHtrData() && LVCOK) { if((hasHtrData() || altHeater) && LVCOK) {
RTC_Store.setUserStart(true); // for cyclic mode RTC_Store.setUserStart(true); // for cyclic mode
RTC_Store.setFrostOn(false); // cancel frost mode RTC_Store.setFrostOn(false); // cancel frost mode
// only start if below appropriate temperature threshold, raised for cyclic mode // only start if below appropriate temperature threshold, raised for cyclic mode
@ -815,23 +850,23 @@ requestOn()
void requestOff() void requestOff()
{ {
DebugPort.println("Stop Request!"); if(HeaterManager.getRunState()) { // heater running?
heaterOff(); DebugPort.println("Stop Request!");
RTC_Store.setUserStart(false); // for cyclic mode heaterOff();
RTC_Store.setFrostOn(false); // cancel active frost mode RTC_Store.setUserStart(false); // for cyclic mode
CTimerManager::cancelActiveTimer(); RTC_Store.setFrostOn(false); // cancel active frost mode
CTimerManager::cancelActiveTimer();
}
} }
void heaterOn() void heaterOn()
{ {
TxManage.queueOnRequest(); HeaterManager.reqOnOff(true);
SmartError.reset();
} }
void heaterOff() void heaterOff()
{ {
TxManage.queueOffRequest(); HeaterManager.reqOnOff(false);
SmartError.inhibit();
} }
@ -1006,6 +1041,9 @@ void checkDebugCommands()
else if(rxVal == ('h' & 0x1f)) { // CTRL-H hourmeter reset else if(rxVal == ('h' & 0x1f)) { // CTRL-H hourmeter reset
pHourMeter->resetHard(); pHourMeter->resetHard();
} }
else if(rxVal == ('p' & 0x1f)) { // CTRL-P fuel usage reset
FuelGauge.reset();
}
else if(rxVal == ('r' & 0x1f)) { // CTRL-R reboot else if(rxVal == ('r' & 0x1f)) { // CTRL-R reboot
ESP.restart(); // reset the esp ESP.restart(); // reset the esp
} }
@ -1340,21 +1378,12 @@ float getGlowCurrent()
int getFanSpeed() int getFanSpeed()
{ {
#ifdef RAW_SAMPLES return HeaterManager.getFanRPM();
/*#ifdef RAW_SAMPLES
return getHeaterInfo().getFan_Actual(); return getHeaterInfo().getFan_Actual();
#else #else
return (int)FilteredSamples.Fan.getValue(); return (int)FilteredSamples.Fan.getValue();
#endif #endif*/
}
void updateFilteredData(CProtocol& HeaterInfo)
{
FilteredSamples.ipVolts.update(HeaterInfo.getVoltage_Supply());
FilteredSamples.GlowVolts.update(HeaterInfo.getGlowPlug_Voltage());
FilteredSamples.GlowAmps.update(HeaterInfo.getGlowPlug_Current());
FilteredSamples.Fan.update(HeaterInfo.getFan_Actual());
FilteredSamples.FastipVolts.update(HeaterInfo.getVoltage_Supply());
FilteredSamples.FastGlowAmps.update(HeaterInfo.getGlowPlug_Current());
} }
int sysUptime() int sysUptime()
@ -1465,8 +1494,56 @@ void reqHeaterCalUpdate()
TxManage.queueSysUpdate(); TxManage.queueSysUpdate();
} }
const CProtocolPackage& getHeaterInfo() // const CProtocolPackage& getHeaterInfo()
// {
// return BlueWireData;
// }
int UHFsubcode(int val)
{ {
return BlueWireData; val &= 0x03;
val = 0x0001 << val;
return val;
} }
void checkUHF()
{
if(!pair433MHz) {
UHFremote.manage();
// unsigned long test = 0xF5F0AC10;
// if(UHFremote.available()) {
// unsigned long code;
// UHFremote.read(code);
// DebugPort.printf("UHF remote code = %08lX\r\n", code);
// unsigned long ID = (test >> 8) & 0xfffff0;
// if(((code ^ ID) & 0xfffff0) == 0) {
// int subCode = code & 0xf;
// if(test & 0x800) {
// if((UHFsubcode(test >> 6) ^ subCode) == 0xf) {
// DebugPort.println("UHF start request!");
// HeaterManager.reqOnOff(true);
// }
// }
// if(test & 0x400) {
// if((UHFsubcode(test >> 4) ^ subCode) == 0xf) {
// DebugPort.println("UHF stop request!");
// HeaterManager.reqOnOff(false);
// }
// }
// if(test & 0x200) {
// if((UHFsubcode(test >> 2) ^ subCode) == 0xf) {
// DebugPort.println("UHF inc temp request!");
// CDemandManager::deltaDemand(+1);
// }
// }
// if(test & 0x100) {
// if((UHFsubcode(test >> 0) ^ subCode) == 0xf) {
// DebugPort.println("UHF dec temp request!");
// CDemandManager::deltaDemand(+1);
// }
// }
// }
// }
}
}

View file

@ -113,6 +113,12 @@ CBluetoothHC05::begin()
DebugPort.println("HC-05 found"); DebugPort.println("HC-05 found");
Reset(true); // reset, staying in command mode
_openSerial(38400); // open serial port at a std. baud rate
delay(100);
DebugPort.print(" Setting Name to \"Afterburner\"... "); DebugPort.print(" Setting Name to \"Afterburner\"... ");
if(!ATCommand("AT+NAME=\"Afterburner\"\r\n")) { if(!ATCommand("AT+NAME=\"Afterburner\"\r\n")) {
DebugPort.println("FAILED"); DebugPort.println("FAILED");
@ -122,7 +128,7 @@ CBluetoothHC05::begin()
} }
DebugPort.print(" Setting baud rate to 9600N81..."); DebugPort.print(" Setting baud rate to 9600N81...");
if(!ATCommand("AT+UART=9600,1,0\r\n")) { if(!ATCommand("AT+UART=38400,1,0\r\n")) {
DebugPort.println("FAILED"); DebugPort.println("FAILED");
} }
else { else {
@ -164,10 +170,11 @@ CBluetoothHC05::begin()
}*/ }*/
_flush(); _flush();
delay(100); delay(100);
_openSerial(9600); // _openSerial(9600);
// leave HC-05 command mode, return to data mode // leave HC-05 command mode, return to data mode
digitalWrite(_keyPin, LOW); Reset(false); // reset, shift into data mode6
// digitalWrite(_keyPin, LOW);
} }
@ -236,6 +243,16 @@ CBluetoothHC05::ATCommand(const char* cmd)
return false; return false;
} }
bool
CBluetoothHC05::Reset(bool keystate)
{
HC05_SerialPort.print("AT+RESET\r\n");
digitalWrite(_keyPin, keystate ? HIGH : LOW);
delay(1000);
_flush();
return true;
}
// protected function, to perform Hayes commands with HC-05 // protected function, to perform Hayes commands with HC-05
bool bool
CBluetoothHC05::ATResponse(const char* cmd, const char* respHdr, char* response, int& len) CBluetoothHC05::ATResponse(const char* cmd, const char* respHdr, char* response, int& len)

View file

@ -39,6 +39,7 @@ static HardwareSerial& HC05_SerialPort(Serial2);
class CBluetoothHC05 : public CBluetoothAbstract { class CBluetoothHC05 : public CBluetoothAbstract {
bool ATCommand(const char* str); bool ATCommand(const char* str);
bool ATResponse(const char* str, const char* respHdr, char* response, int& len); bool ATResponse(const char* str, const char* respHdr, char* response, int& len);
bool Reset(bool keystate);
int _sensePin, _keyPin; int _sensePin, _keyPin;
CModerator foldbackModerator; CModerator foldbackModerator;
char _MAC[32]; char _MAC[32];

View file

@ -66,7 +66,7 @@ CBME280Screen::show()
_printMenuText(64, 16, "Sensor not found", false, eCentreJustify); _printMenuText(64, 16, "Sensor not found", false, eCentreJustify);
} }
_printMenuText(_display.xCentre(), 52, " \021 Exit \020 ", true, eCentreJustify); _printMenuText(_display.xCentre(), 53, " \021 Exit \020 ", true, eCentreJustify);
} }
return true; return true;

View file

@ -27,7 +27,7 @@
#include "../Utility/helpers.h" #include "../Utility/helpers.h"
#include "../Utility/UtilClasses.h" #include "../Utility/UtilClasses.h"
#include "../Utility/NVStorage.h" #include "../Utility/NVStorage.h"
#include "../Protocol/Protocol.h" #include "../Protocol/HeaterManager.h"
#include "../Utility/TempSense.h" #include "../Utility/TempSense.h"
#include "../RTC/RTCStore.h" #include "../RTC/RTCStore.h"
@ -123,7 +123,8 @@ CBasicScreen::show()
if(CDemandManager::isThermostat()) { if(CDemandManager::isThermostat()) {
if(CDemandManager::isExtThermostatMode()) { if(CDemandManager::isExtThermostatMode()) {
sprintf(msg, "External @ %.1fHz", getHeaterInfo().getPump_Fixed()); // sprintf(msg, "External @ %.1fHz", getHeaterInfo().getPump_Fixed());
sprintf(msg, "External @ %.1fHz", HeaterManager.getPumpDemand());
} }
else { else {
float fTemp = CDemandManager::getDegC(); float fTemp = CDemandManager::getDegC();
@ -137,7 +138,8 @@ CBasicScreen::show()
} }
} }
else { else {
sprintf(msg, "Setpoint = %.1fHz", getHeaterInfo().getPump_Fixed()); sprintf(msg, "Setpoint = %.1fHz", HeaterManager.getPumpDemand());
// sprintf(msg, "Setpoint = %.1fHz", getHeaterInfo().getPump_Fixed());
} }
break; break;
case 1: case 1:
@ -288,7 +290,8 @@ CBasicScreen::keyHandler(uint8_t event)
// hold CENTRE to turn ON or OFF // hold CENTRE to turn ON or OFF
if(event & key_Centre) { if(event & key_Centre) {
if(NVstore.getUserSettings().menuMode < 2) { if(NVstore.getUserSettings().menuMode < 2) {
int runstate = getHeaterInfo().getRunStateEx(); // int runstate = getHeaterInfo().getRunStateEx();
int runstate = HeaterManager.getRunStateEx();
if(runstate && !RTC_Store.getFrostOn()) { // running, including cyclic mode idle if(runstate && !RTC_Store.getFrostOn()) { // running, including cyclic mode idle
if(repeatCount > 5) { if(repeatCount > 5) {
repeatCount = -1; repeatCount = -1;
@ -399,8 +402,10 @@ CBasicScreen::showRunState()
if(NVstore.getUserSettings().menuMode == 2) if(NVstore.getUserSettings().menuMode == 2)
return; return;
int runstate = getHeaterInfo().getRunStateEx(); int runstate = HeaterManager.getRunStateEx();
int errstate = getHeaterInfo().getErrState(); int errstate = HeaterManager.getErrState();
// int runstate = getHeaterInfo().getRunStateEx();
// int errstate = getHeaterInfo().getErrState();
if(errstate) errstate--; // correct for +1 biased return value if(errstate) errstate--; // correct for +1 biased return value
@ -423,11 +428,13 @@ CBasicScreen::showRunState()
int yPos = _display.height() - 2*_display.textHeight(); int yPos = _display.height() - 2*_display.textHeight();
_printMenuText(xPos, yPos, msg, false, eCentreJustify); _printMenuText(xPos, yPos, msg, false, eCentreJustify);
toPrint = getHeaterInfo().getErrStateStr(); // toPrint = getHeaterInfo().getErrStateStr();
toPrint = HeaterManager.getErrStateStr();
} }
else { else {
if(runstate) { if(runstate) {
toPrint = getHeaterInfo().getRunStateStr(); // toPrint = getHeaterInfo().getRunStateStr();
toPrint = HeaterManager.getRunStateStr();
// simplify starting states // simplify starting states
switch(runstate) { switch(runstate) {
case 1: case 1:

View file

@ -37,12 +37,14 @@ CDS18B20Screen::CDS18B20Screen(C128x64_OLED& display, CScreenManager& mgr) : CPa
_initUI(); _initUI();
} }
void bool
CDS18B20Screen::onSelect() CDS18B20Screen::onSelect()
{ {
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
_nNumSensors = getTempSensor().getDS18B20().getNumSensors(); _nNumSensors = getTempSensor().getDS18B20().getNumSensors();
_readNV(); _readNV();
return true;
} }
void void

View file

@ -45,7 +45,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
void adjust(int dir); void adjust(int dir);
}; };

View file

@ -30,6 +30,7 @@
#include "../Utility/FuelGauge.h" #include "../Utility/FuelGauge.h"
#include "../RTC/RTCStore.h" #include "../RTC/RTCStore.h"
#include "../Utility/DemandManager.h" #include "../Utility/DemandManager.h"
#include "../Protocol/HeaterManager.h"
#define MINIFONT miniFontInfo #define MINIFONT miniFontInfo
@ -87,8 +88,10 @@ CDetailedScreen::show()
CScreenHeader::show(false); CScreenHeader::show(false);
int runstate = getHeaterInfo().getRunStateEx(); int runstate = HeaterManager.getRunStateEx();
int errstate = getHeaterInfo().getErrState(); int errstate = HeaterManager.getErrState();
// int runstate = getHeaterInfo().getRunStateEx();
// int errstate = getHeaterInfo().getErrState();
if(errstate) errstate--; // correct for +1 biased return value if(errstate) errstate--; // correct for +1 biased return value
long tDelta = millis() - _showTarget; long tDelta = millis() - _showTarget;
@ -103,7 +106,8 @@ CDetailedScreen::show()
desiredT = CDemandManager::getDemand(); desiredT = CDemandManager::getDemand();
} }
else { else {
fPump = getHeaterInfo().getPump_Fixed(); // fPump = getHeaterInfo().getPump_Fixed();
fPump = HeaterManager.getPumpDemand();
if(NVstore.getUserSettings().cyclic.isEnabled()) if(NVstore.getUserSettings().cyclic.isEnabled())
desiredT = CDemandManager::getDegC(); desiredT = CDemandManager::getDegC();
} }
@ -120,23 +124,37 @@ CDetailedScreen::show()
bool bGlowActive = false; bool bGlowActive = false;
if(runstate != 0 && runstate != 10) { // not idle modes if(runstate != 0 && runstate != 10) { // not idle modes
float power = getHeaterInfo().getGlowPlug_Power(); float power = HeaterManager.getGlowPlugPower();
if(power > 1) { if(power != 0) {
showGlowPlug(power); showGlowPlug(power);
bGlowActive = true; bGlowActive = true;
} }
if(_showTarget) if(_showTarget)
showFanV(getHeaterInfo().getFan_Voltage()); showFanV(HeaterManager.getFanVoltage());
else else
showFan(getHeaterInfo().getFan_Actual()); showFan(HeaterManager.getFanRPM());
showFuel(getHeaterInfo().getPump_Actual()); showFuel(HeaterManager.getPumpRate());
showBodyThermometer(getHeaterInfo().getTemperature_HeatExchg()); showBodyThermometer(HeaterManager.getBodyTemp());
// float power = getHeaterInfo().getGlowPlug_Power();
// if(power > 1) {
// showGlowPlug(power);
// bGlowActive = true;
// }
// if(_showTarget)
// showFanV(getHeaterInfo().getFan_Voltage());
// else
// showFan(getHeaterInfo().getFan_Actual());
// showFuel(getHeaterInfo().getPump_Actual());
// showBodyThermometer(getHeaterInfo().getTemperature_HeatExchg());
} }
if(!bGlowActive) { if(!bGlowActive && HeaterManager.getHeaterStyle() == 0) {
showBowser(FuelGauge.Used_mL()); showBowser(FuelGauge.Used_mL());
} }
showRunState(runstate, errstate); showRunState(runstate, errstate);
@ -218,7 +236,8 @@ CDetailedScreen::keyHandler(uint8_t event)
} }
if(event & key_Centre) { if(event & key_Centre) {
int runstate = getHeaterInfo().getRunStateEx(); // int runstate = getHeaterInfo().getRunStateEx();
int runstate = HeaterManager.getRunStateEx();
if(runstate && !RTC_Store.getFrostOn()) { // running, including cyclic mode idle if(runstate && !RTC_Store.getFrostOn()) { // running, including cyclic mode idle
if(_keyRepeatCount > 5) { if(_keyRepeatCount > 5) {
_keyRepeatCount = -1; // prevent double handling _keyRepeatCount = -1; // prevent double handling
@ -387,6 +406,11 @@ CDetailedScreen::showThermometer(float fDesired, float fActual, float fPump)
void void
CDetailedScreen::showBodyThermometer(int actual) CDetailedScreen::showBodyThermometer(int actual)
{ {
if(HeaterManager.getHeaterStyle() == 1 && HeaterManager.getRunState() > 5 ) {
// don't get body temp updates on crappy heater ECUs once shutting down
return;
}
// draw bulb design // draw bulb design
_drawBitmap(X_BODY_BULB, Y_BULB, BodyThermometerIconInfo); _drawBitmap(X_BODY_BULB, Y_BULB, BodyThermometerIconInfo);
// draw mercury // draw mercury
@ -418,14 +442,16 @@ CDetailedScreen::showGlowPlug(float power)
{ {
_drawBitmap(X_GLOW_ICON, Y_GLOW_ICON, GlowPlugIconInfo); _drawBitmap(X_GLOW_ICON, Y_GLOW_ICON, GlowPlugIconInfo);
// _animateGlow = true; // _animateGlow = true;
char msg[16]; if(power > 0) {
sprintf(msg, "%.0fW", power); char msg[16];
sprintf(msg, "%.0fW", power);
#ifdef MINI_GLOWLABEL #ifdef MINI_GLOWLABEL
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
#endif #endif
_printMenuText(X_GLOW_ICON + (GlowPlugIconInfo.width/2), _printMenuText(X_GLOW_ICON + (GlowPlugIconInfo.width/2),
Y_GLOW_ICON + GlowPlugIconInfo.height + 3, Y_GLOW_ICON + GlowPlugIconInfo.height + 3,
msg, false, eCentreJustify); msg, false, eCentreJustify);
}
} }
void void
@ -435,12 +461,14 @@ CDetailedScreen::showFan(int RPM)
_animateRPM = RPM != 0; // used by animation routine _animateRPM = RPM != 0; // used by animation routine
_display.setTextColor(WHITE); _display.setTextColor(WHITE);
char msg[16]; if(RPM > 0) {
sprintf(msg, "%d", RPM); char msg[16];
sprintf(msg, "%d", RPM);
#ifdef MINI_FANLABEL #ifdef MINI_FANLABEL
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
#endif #endif
_printMenuText(X_FAN_ICON + (FanIcon1Info.width/2), Y_BASELINE, msg, false, eCentreJustify); _printMenuText(X_FAN_ICON + (FanIcon1Info.width/2), Y_BASELINE, msg, false, eCentreJustify);
}
} }
void void
@ -450,12 +478,14 @@ CDetailedScreen::showFanV(float volts)
_animateRPM = volts != 0; // used by animation routine _animateRPM = volts != 0; // used by animation routine
_display.setTextColor(WHITE); _display.setTextColor(WHITE);
char msg[16]; if(volts > 0) {
sprintf(msg, "%.1fV", volts); char msg[16];
sprintf(msg, "%.1fV", volts);
#ifdef MINI_FANLABEL #ifdef MINI_FANLABEL
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
#endif #endif
_printMenuText(X_FAN_ICON + (FanIcon1Info.width/2), Y_BASELINE, msg, false, eCentreJustify); _printMenuText(X_FAN_ICON + (FanIcon1Info.width/2), Y_BASELINE, msg, false, eCentreJustify);
}
} }
void void
@ -463,7 +493,7 @@ CDetailedScreen::showFuel(float rate)
{ {
// NOTE: fuel drop animation performed in animateOLED // NOTE: fuel drop animation performed in animateOLED
_animatePump = rate != 0; // used by animation routine _animatePump = rate != 0; // used by animation routine
if(rate) { if(rate > 0) {
char msg[16]; char msg[16];
sprintf(msg, "%.1f", rate); sprintf(msg, "%.1f", rate);
#ifdef MINI_FUELLABEL #ifdef MINI_FUELLABEL
@ -510,11 +540,13 @@ CDetailedScreen::showRunState(int runstate, int errstate)
_display.printCentreJustified(" "); _display.printCentreJustified(" ");
} }
yPos += _display.textHeight(); yPos += _display.textHeight();
toPrint = getHeaterInfo().getErrStateStr(); // toPrint = getHeaterInfo().getErrStateStr();
toPrint = HeaterManager.getErrStateStr();
} }
else { else {
// no errors, heater normal // no errors, heater normal
toPrint = getHeaterInfo().getRunStateStr(); // toPrint = getHeaterInfo().getRunStateStr();
toPrint = HeaterManager.getRunStateStr();
} }
if(toPrint) { if(toPrint) {
_printMenuText(_display.xCentre(), yPos, toPrint, false, eCentreJustify); _printMenuText(_display.xCentre(), yPos, toPrint, false, eCentreJustify);

View file

@ -30,13 +30,14 @@ CFrostScreen::CFrostScreen(C128x64_OLED& display, CScreenManager& mgr) : CUIEdit
{ {
} }
void bool
CFrostScreen::onSelect() CFrostScreen::onSelect()
{ {
CUIEditScreen::onSelect(); CUIEditScreen::onSelect();
_frostOn = NVstore.getUserSettings().FrostOn; _frostOn = NVstore.getUserSettings().FrostOn;
_frostRise = NVstore.getUserSettings().FrostRise; _frostRise = NVstore.getUserSettings().FrostRise;
_scrollChar = 0; _scrollChar = 0;
return true;
} }
bool bool

View file

@ -41,7 +41,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
void adjust(int dir); void adjust(int dir);
}; };

View file

@ -39,7 +39,7 @@ CFuelCalScreen::CFuelCalScreen(C128x64_OLED& display, CScreenManager& mgr) : CPa
_mlPerStroke = 0.02; _mlPerStroke = 0.02;
} }
void bool
CFuelCalScreen::onSelect() CFuelCalScreen::onSelect()
{ {
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
@ -47,6 +47,7 @@ CFuelCalScreen::onSelect()
_mlPerStroke = NVstore.getHeaterTuning().pumpCal; _mlPerStroke = NVstore.getHeaterTuning().pumpCal;
_maxUsage = NVstore.getHeaterTuning().maxFuelUsage; _maxUsage = NVstore.getHeaterTuning().maxFuelUsage;
_warnUsage = NVstore.getHeaterTuning().warnFuelUsage; _warnUsage = NVstore.getHeaterTuning().warnFuelUsage;
return true;
} }
bool bool

View file

@ -41,7 +41,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -35,6 +35,7 @@
#include "../Utility/macros.h" #include "../Utility/macros.h"
#include "../Utility/NVStorage.h" #include "../Utility/NVStorage.h"
#include "../Protocol/Protocol.h" #include "../Protocol/Protocol.h"
#include "../Protocol/HeaterManager.h"
#include "fonts/Icons.h" #include "fonts/Icons.h"
@ -43,12 +44,16 @@ CFuelMixtureScreen::CFuelMixtureScreen(C128x64_OLED& display, CScreenManager& mg
_initUI(); _initUI();
} }
void bool
CFuelMixtureScreen::onSelect() CFuelMixtureScreen::onSelect()
{ {
if(HeaterManager.getHeaterStyle() != 0)
return false;
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
_load(); _load();
return true;
} }
void void

View file

@ -40,7 +40,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -45,6 +45,12 @@ CGPIOInfoScreen::CGPIOInfoScreen(C128x64_OLED& display, CScreenManager& mgr) : C
_keyRepeatCount = -1; _keyRepeatCount = -1;
} }
bool
CGPIOInfoScreen::onSelect()
{
return getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO; // has GPIO support
}
void void
CGPIOInfoScreen::_initUI() CGPIOInfoScreen::_initUI()
{ {

View file

@ -35,6 +35,7 @@ class CGPIOInfoScreen : public CScreen
void _initUI(); void _initUI();
public: public:
CGPIOInfoScreen(C128x64_OLED& display, CScreenManager& mgr); CGPIOInfoScreen(C128x64_OLED& display, CScreenManager& mgr);
bool onSelect();
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);

View file

@ -66,13 +66,17 @@ CGPIOSetupScreen::CGPIOSetupScreen(C128x64_OLED& display, CScreenManager& mgr) :
_ExtHold = 0; _ExtHold = 0;
} }
void bool
CGPIOSetupScreen::onSelect() CGPIOSetupScreen::onSelect()
{ {
CUIEditScreen::onSelect(); if(getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO) { // has GPIO support ?
_GPIOparams = NVstore.getUserSettings().GPIO; CUIEditScreen::onSelect();
_ExtHold = NVstore.getUserSettings().ExtThermoTimeout; _GPIOparams = NVstore.getUserSettings().GPIO;
_repeatCount = -1; _ExtHold = NVstore.getUserSettings().ExtThermoTimeout;
_repeatCount = -1;
return true;
}
return false;
} }

View file

@ -43,7 +43,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -27,6 +27,7 @@
#include "../Utility/macros.h" #include "../Utility/macros.h"
#include "../Utility/NVStorage.h" #include "../Utility/NVStorage.h"
#include "../Protocol/Protocol.h" #include "../Protocol/Protocol.h"
#include "../Protocol/HeaterManager.h"
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// //
@ -51,14 +52,17 @@ CHeaterSettingsScreen::CHeaterSettingsScreen(C128x64_OLED& display, CScreenManag
_sysVoltage = 12; _sysVoltage = 12;
} }
void bool
CHeaterSettingsScreen::onSelect() CHeaterSettingsScreen::onSelect()
{ {
if(HeaterManager.getHeaterStyle() != 0)
return false;
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
_initUI(); _initUI();
_fanSensor = NVstore.getHeaterTuning().fanSensor; _fanSensor = NVstore.getHeaterTuning().fanSensor;
_glowDrive = NVstore.getHeaterTuning().glowDrive; _glowDrive = NVstore.getHeaterTuning().glowDrive;
_sysVoltage = NVstore.getHeaterTuning().sysVoltage / 10; _sysVoltage = NVstore.getHeaterTuning().sysVoltage / 10;
return true;
} }
bool bool

View file

@ -41,7 +41,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -30,11 +30,12 @@ CHomeMenuSelScreen::CHomeMenuSelScreen(C128x64_OLED& display, CScreenManager& mg
{ {
} }
void bool
CHomeMenuSelScreen::onSelect() CHomeMenuSelScreen::onSelect()
{ {
CUIEditScreen::onSelect(); CUIEditScreen::onSelect();
_action = NVstore.getUserSettings().HomeMenu; _action = NVstore.getUserSettings().HomeMenu;
return true;
} }
bool bool
@ -199,7 +200,7 @@ CNoHeaterHomeMenuSelScreen::CNoHeaterHomeMenuSelScreen(C128x64_OLED& display, CS
{ {
} }
void bool
CNoHeaterHomeMenuSelScreen::onSelect() CNoHeaterHomeMenuSelScreen::onSelect()
{ {
CUIEditScreen::onSelect(); CUIEditScreen::onSelect();
@ -208,6 +209,7 @@ CNoHeaterHomeMenuSelScreen::onSelect()
_menuTimeout = NVstore.getUserSettings().menuTimeout; _menuTimeout = NVstore.getUserSettings().menuTimeout;
if(_action.onTimeout == 0 || _action.onTimeout == 1) if(_action.onTimeout == 0 || _action.onTimeout == 1)
_action.onTimeout = 2; _action.onTimeout = 2;
return true;
} }
bool bool

View file

@ -40,7 +40,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
void adjust(int dir); void adjust(int dir);
}; };
@ -57,7 +57,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
void adjust(int dir); void adjust(int dir);
}; };

View file

@ -30,12 +30,16 @@ CHumidityScreen::CHumidityScreen(C128x64_OLED& display, CScreenManager& mgr) : C
{ {
} }
void bool
CHumidityScreen::onSelect() CHumidityScreen::onSelect()
{ {
if(getTempSensor().getBME280().getCount() == 0)
return false;
CUIEditScreen::onSelect(); CUIEditScreen::onSelect();
_humidityThresh = NVstore.getUserSettings().humidityStart; _humidityThresh = NVstore.getUserSettings().humidityStart;
_scrollChar = 0; _scrollChar = 0;
return true;
} }
bool bool

View file

@ -40,7 +40,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
void adjust(int dir); void adjust(int dir);
}; };

View file

@ -40,12 +40,13 @@ CInheritSettingsScreen::CInheritSettingsScreen(C128x64_OLED& display, CScreenMan
_initUI(); _initUI();
} }
void bool
CInheritSettingsScreen::onSelect() CInheritSettingsScreen::onSelect()
{ {
// ensure standard entry to screen - especially after a dimming timeout // ensure standard entry to screen - especially after a dimming timeout
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
_nAdoptSettings = hasOEMLCDcontroller() ? 1 : 2; _nAdoptSettings = hasOEMLCDcontroller() ? 1 : 2;
return true;
} }
void void

View file

@ -36,7 +36,7 @@ public:
CInheritSettingsScreen(C128x64_OLED& display, CScreenManager& mgr); CInheritSettingsScreen(C128x64_OLED& display, CScreenManager& mgr);
bool show(); bool show();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -39,12 +39,13 @@ CLVCScreen::CLVCScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordSc
_LVC = 115; _LVC = 115;
} }
void bool
CLVCScreen::onSelect() CLVCScreen::onSelect()
{ {
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
_initUI(); _initUI();
_LVC = NVstore.getHeaterTuning().lowVolts; _LVC = NVstore.getHeaterTuning().lowVolts;
return true;
} }
bool bool

View file

@ -39,7 +39,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -47,13 +47,14 @@ CMQTTScreen::CMQTTScreen(C128x64_OLED& display, CScreenManager& mgr) : CUIEditSc
_initUI(); _initUI();
} }
void bool
CMQTTScreen::onSelect() CMQTTScreen::onSelect()
{ {
CScreen::onSelect(); CScreen::onSelect();
_initUI(); _initUI();
_IPScrollPos = 0; _IPScrollPos = 0;
_UsernameScrollPos = 0; _UsernameScrollPos = 0;
return true;
} }

View file

@ -31,7 +31,7 @@ class CScreenManager;
class CMQTTScreen : public CUIEditScreen { class CMQTTScreen : public CUIEditScreen {
public: public:
CMQTTScreen(C128x64_OLED& display, CScreenManager& mgr); CMQTTScreen(C128x64_OLED& display, CScreenManager& mgr);
void onSelect(); bool onSelect();
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);

View file

@ -31,13 +31,14 @@ CMenuSelScreen::CMenuSelScreen(C128x64_OLED& display, CScreenManager& mgr) : CPa
_bReload = false; _bReload = false;
} }
void bool
CMenuSelScreen::onSelect() CMenuSelScreen::onSelect()
{ {
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
_menuMode = NVstore.getUserSettings().menuMode; _menuMode = NVstore.getUserSettings().menuMode;
_holdPW = NVstore.getUserSettings().holdPassword; _holdPW = NVstore.getUserSettings().holdPassword;
_scrollChar = 0; _scrollChar = 0;
return true;
} }
bool bool

View file

@ -42,7 +42,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
void adjust(int dir); void adjust(int dir);
}; };

View file

@ -44,12 +44,13 @@ CPrimingScreen::CPrimingScreen(C128x64_OLED& display, CScreenManager& mgr) : CSc
_initUI(); _initUI();
} }
void bool
CPrimingScreen::onSelect() CPrimingScreen::onSelect()
{ {
CScreenHeader::onSelect(); CScreenHeader::onSelect();
_stopPump(); _stopPump();
_initUI(); _initUI();
return true;
} }
void void

View file

@ -38,7 +38,7 @@ class CPrimingScreen : public CScreenHeader {
void _initUI(); void _initUI();
public: public:
CPrimingScreen(C128x64_OLED& display, CScreenManager& mgr); CPrimingScreen(C128x64_OLED& display, CScreenManager& mgr);
void onSelect(); bool onSelect();
void onExit(); void onExit();
bool show(); bool show();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);

View file

@ -61,10 +61,11 @@ CScreen::show()
return false; return false;
} }
void bool
CScreen::onSelect() CScreen::onSelect()
{ {
_display.clearDisplay(); _display.clearDisplay();
return true;
} }
void void

View file

@ -63,7 +63,7 @@ protected:
public: public:
CScreen(C128x64_OLED& disp, CScreenManager& mgr); CScreen(C128x64_OLED& disp, CScreenManager& mgr);
virtual ~CScreen(); virtual ~CScreen();
virtual void onSelect(); virtual bool onSelect();
virtual void onExit(); virtual void onExit();
virtual bool animate(); virtual bool animate();
virtual bool show(); virtual bool show();

View file

@ -77,13 +77,14 @@ CScreenHeader::CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr) : CScreen(
_hdrDetail = false; _hdrDetail = false;
} }
void bool
CScreenHeader::onSelect() CScreenHeader::onSelect()
{ {
CScreen::onSelect(); CScreen::onSelect();
_batteryCount = 255; _batteryCount = 255;
_animateCount = 255; _animateCount = 255;
return true;
} }

View file

@ -60,7 +60,7 @@ public:
CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr); CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr);
bool show(bool erase); bool show(bool erase);
bool animate(); bool animate();
void onSelect(); bool onSelect();
}; };
#endif // __SCREEN_HEADER_H__ #endif // __SCREEN_HEADER_H__

View file

@ -52,6 +52,7 @@
#include "FrostScreen.h" #include "FrostScreen.h"
#include "HumidityScreen.h" #include "HumidityScreen.h"
#include "WebPageUpdateScreen.h" #include "WebPageUpdateScreen.h"
#include "433MHzScreen.h"
#include "LVCScreen.h" #include "LVCScreen.h"
#include <Wire.h> #include <Wire.h>
#include "../cfg/pins.h" #include "../cfg/pins.h"
@ -358,8 +359,7 @@ CScreenManager::_loadScreens()
menuloop.push_back(new CBasicScreen(*_pDisplay, *this)); // basic control menuloop.push_back(new CBasicScreen(*_pDisplay, *this)); // basic control
menuloop.push_back(new CClockScreen(*_pDisplay, *this)); // clock menuloop.push_back(new CClockScreen(*_pDisplay, *this)); // clock
menuloop.push_back(new CPrimingScreen(*_pDisplay, *this)); // mode / priming menuloop.push_back(new CPrimingScreen(*_pDisplay, *this)); // mode / priming
if(getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO) // has GPIO support menuloop.push_back(new CGPIOInfoScreen(*_pDisplay, *this)); // GPIO info
menuloop.push_back(new CGPIOInfoScreen(*_pDisplay, *this)); // GPIO info
menuloop.push_back(new CMenuTrunkScreen(*_pDisplay, *this)); menuloop.push_back(new CMenuTrunkScreen(*_pDisplay, *this));
} }
else if(NVstore.getUserSettings().menuMode == 1) { else if(NVstore.getUserSettings().menuMode == 1) {
@ -371,8 +371,7 @@ CScreenManager::_loadScreens()
menuloop.push_back(new CMenuTrunkScreen(*_pDisplay, *this)); menuloop.push_back(new CMenuTrunkScreen(*_pDisplay, *this));
menuloop.push_back(new CBasicScreen(*_pDisplay, *this)); // basic control menuloop.push_back(new CBasicScreen(*_pDisplay, *this)); // basic control
menuloop.push_back(new CClockScreen(*_pDisplay, *this)); // clock menuloop.push_back(new CClockScreen(*_pDisplay, *this)); // clock
if(getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO) // has GPIO support menuloop.push_back(new CGPIOInfoScreen(*_pDisplay, *this)); // GPIO info
menuloop.push_back(new CGPIOInfoScreen(*_pDisplay, *this)); // GPIO info
} }
_Screens.push_back(menuloop); _Screens.push_back(menuloop);
@ -400,14 +399,11 @@ CScreenManager::_loadScreens()
if(NVstore.getUserSettings().menuMode == 0) { // standard heater control menu set if(NVstore.getUserSettings().menuMode == 0) { // standard heater control menu set
menuloop.push_back(new CThermostatModeScreen(*_pDisplay, *this)); // thermostat settings screen menuloop.push_back(new CThermostatModeScreen(*_pDisplay, *this)); // thermostat settings screen
menuloop.push_back(new CFrostScreen(*_pDisplay, *this)); // frost mode screen menuloop.push_back(new CFrostScreen(*_pDisplay, *this)); // frost mode screen
if(getTempSensor().getBME280().getCount()) { menuloop.push_back(new CHumidityScreen(*_pDisplay, *this)); // humidity settings screen
menuloop.push_back(new CHumidityScreen(*_pDisplay, *this)); // humidity settings screen
}
menuloop.push_back(new CHomeMenuSelScreen(*_pDisplay, *this)); // Home menu settings screen menuloop.push_back(new CHomeMenuSelScreen(*_pDisplay, *this)); // Home menu settings screen
menuloop.push_back(new CTimeoutsScreen(*_pDisplay, *this)); // Other options screen menuloop.push_back(new CTimeoutsScreen(*_pDisplay, *this)); // Other options screen
menuloop.push_back(new CMenuSelScreen(*_pDisplay, *this)); // Menu mode screen menuloop.push_back(new CMenuSelScreen(*_pDisplay, *this)); // Menu mode screen
if(getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO) // has GPIO support ? menuloop.push_back(new CGPIOSetupScreen(*_pDisplay, *this)); // GPIO settings screen
menuloop.push_back(new CGPIOSetupScreen(*_pDisplay, *this)); // GPIO settings screen
} }
else if(NVstore.getUserSettings().menuMode == 1) { // "no fiddle" menu set else if(NVstore.getUserSettings().menuMode == 1) { // "no fiddle" menu set
menuloop.push_back(new CMenuSelScreen(*_pDisplay, *this)); // Menu mode screen menuloop.push_back(new CMenuSelScreen(*_pDisplay, *this)); // Menu mode screen
@ -415,8 +411,6 @@ CScreenManager::_loadScreens()
else if(NVstore.getUserSettings().menuMode == 2) { // no heater menu set else if(NVstore.getUserSettings().menuMode == 2) { // no heater menu set
menuloop.push_back(new CNoHeaterHomeMenuSelScreen(*_pDisplay, *this)); // No Heater Home menu settings screen menuloop.push_back(new CNoHeaterHomeMenuSelScreen(*_pDisplay, *this)); // No Heater Home menu settings screen
menuloop.push_back(new CMenuSelScreen(*_pDisplay, *this)); // Menu mode screen menuloop.push_back(new CMenuSelScreen(*_pDisplay, *this)); // Menu mode screen
// if(getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO) // has GPIO support ?
// menuloop.push_back(new CGPIOSetupScreen(*_pDisplay, *this)); // GPIO settings screen
} }
_Screens.push_back(menuloop); _Screens.push_back(menuloop);
@ -432,6 +426,7 @@ CScreenManager::_loadScreens()
menuloop.push_back(new CWiFiSTAScreen(*_pDisplay, *this)); menuloop.push_back(new CWiFiSTAScreen(*_pDisplay, *this));
menuloop.push_back(new CMQTTScreen(*_pDisplay, *this)); menuloop.push_back(new CMQTTScreen(*_pDisplay, *this));
menuloop.push_back(new CBTScreen(*_pDisplay, *this)); menuloop.push_back(new CBTScreen(*_pDisplay, *this));
menuloop.push_back(new C433MHzScreen(*_pDisplay, *this));
if(getTempSensor().getBME280().getCount()) { if(getTempSensor().getBME280().getCount()) {
menuloop.push_back(new CTempSensorScreen(*_pDisplay, *this)); menuloop.push_back(new CTempSensorScreen(*_pDisplay, *this));
menuloop.push_back(new CBME280Screen(*_pDisplay, *this)); menuloop.push_back(new CBME280Screen(*_pDisplay, *this));
@ -625,13 +620,16 @@ CScreenManager::refresh()
_pDisplay->display(); _pDisplay->display();
} }
void bool
CScreenManager::_enterScreen() CScreenManager::_enterScreen()
{ {
bool retval = true;
if(_menu >= 0) if(_menu >= 0)
_Screens[_menu][_subMenu]->onSelect(); retval = _Screens[_menu][_subMenu]->onSelect();
reqUpdate(); reqUpdate();
return retval;
} }
void void
@ -656,12 +654,13 @@ void
CScreenManager::_changeSubMenu(int dir) CScreenManager::_changeSubMenu(int dir)
{ {
_leaveScreen(); _leaveScreen();
_subMenu += dir; do {
int bounds = _Screens[_menu].size() - 1; _subMenu += dir;
WRAPLIMITS(_subMenu, 0, bounds); int bounds = _Screens[_menu].size() - 1;
if(_menu == 0) WRAPLIMITS(_subMenu, 0, bounds);
_rootMenu = _subMenu; // track the root menu for when we branch then return if(_menu == 0)
_enterScreen(); _rootMenu = _subMenu; // track the root menu for when we branch then return
} while (!_enterScreen());
} }
void void

View file

@ -44,7 +44,7 @@ class CScreenManager {
unsigned long _DimTime_ms; unsigned long _DimTime_ms;
unsigned long _MenuTimeout; unsigned long _MenuTimeout;
bool _bReqUpdate; bool _bReqUpdate;
void _enterScreen(); bool _enterScreen();
void _leaveScreen(); void _leaveScreen();
void _changeSubMenu(int dir); void _changeSubMenu(int dir);
void _dim(bool state); void _dim(bool state);
@ -56,7 +56,7 @@ public:
enum eUIRootMenus { DetailedControlUI, BasicControlUI, ClockUI, ModeUI, GPIOInfoUI, TrunkUI }; enum eUIRootMenus { DetailedControlUI, BasicControlUI, ClockUI, ModeUI, GPIOInfoUI, TrunkUI };
enum eUITimerMenus { TimerOverviewUI, Timer1UI, Timer2UI, Timer3UI, Timer4UI, Timer5UI, Timer6UI, Timer7UI, enum eUITimerMenus { TimerOverviewUI, Timer1UI, Timer2UI, Timer3UI, Timer4UI, Timer5UI, Timer6UI, Timer7UI,
Timer8UI, Timer9UI, Timer10UI, Timer11UI, Timer12UI, Timer13UI, Timer14UI }; Timer8UI, Timer9UI, Timer10UI, Timer11UI, Timer12UI, Timer13UI, Timer14UI };
enum eUITuningMenus { MixtureUI, HeaterSettingsUI, FuelCalUI }; enum eUITuningMenus { MixtureUI, HeaterSettingsUI, FuelCalUI, LVCCalUI };
enum eUIUserSettingsMenus { ExThermostatUI, FrostUI, HomeMenuUI, TimeIntervalsUI, TempSensorUI, GPIOUI }; enum eUIUserSettingsMenus { ExThermostatUI, FrostUI, HomeMenuUI, TimeIntervalsUI, TempSensorUI, GPIOUI };
enum eUIBranchMenus { SetClockUI, InheritSettingsUI, HtrSettingsUI, DS18B20UI }; enum eUIBranchMenus { SetClockUI, InheritSettingsUI, HtrSettingsUI, DS18B20UI };
enum eUISystemSettingsMenus { SysVerUI, SysHoursUI, SysWifiUI, SysBTUI }; enum eUISystemSettingsMenus { SysVerUI, SysHoursUI, SysWifiUI, SysBTUI };

View file

@ -41,11 +41,12 @@ CSetClockScreen::CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr) : C
_initUI(); _initUI();
} }
void bool
CSetClockScreen::onSelect() CSetClockScreen::onSelect()
{ {
CScreen::onSelect(); CScreen::onSelect();
_initUI(); _initUI();
return true;
} }
void void

View file

@ -40,7 +40,7 @@ class CSetClockScreen : public CUIEditScreen {
public: public:
CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr); CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr);
void onSelect(); bool onSelect();
bool show(); bool show();
void showTime(int); void showTime(int);
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);

View file

@ -55,12 +55,13 @@ CSetTimerScreen::CSetTimerScreen(C128x64_OLED& display, CScreenManager& mgr, int
_timerID = instance; _timerID = instance;
} }
void bool
CSetTimerScreen::onSelect() CSetTimerScreen::onSelect()
{ {
CUIEditScreen::onSelect(); CUIEditScreen::onSelect();
_initUI(); _initUI();
NVstore.getTimerInfo(_timerID, _timerInfo); NVstore.getTimerInfo(_timerID, _timerInfo);
return true;
} }
bool bool

View file

@ -41,7 +41,7 @@ class CSetTimerScreen : public CUIEditScreen {
void _showConflict(const char* str); void _showConflict(const char* str);
public: public:
CSetTimerScreen(C128x64_OLED& display, CScreenManager& mgr, int instance); CSetTimerScreen(C128x64_OLED& display, CScreenManager& mgr, int instance);
void onSelect(); bool onSelect();
bool show(); bool show();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
}; };

View file

@ -33,6 +33,7 @@
#include "../Utility/helpers.h" #include "../Utility/helpers.h"
#include "../Utility/macros.h" #include "../Utility/macros.h"
#include "../Protocol/Protocol.h" #include "../Protocol/Protocol.h"
#include "../Protocol/HeaterManager.h"
#include "fonts/Arial.h" #include "fonts/Arial.h"
static const int Line3 = 20; // system voltage static const int Line3 = 20; // system voltage
@ -47,12 +48,13 @@ CSettingsScreen::CSettingsScreen(C128x64_OLED& display, CScreenManager& mgr) : C
_initUI(); _initUI();
} }
void bool
CSettingsScreen::onSelect() CSettingsScreen::onSelect()
{ {
// ensure standard entry to screen - especially after a dimming timeout // ensure standard entry to screen - especially after a dimming timeout
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
_initUI(); _initUI();
return true;
} }
bool bool
@ -71,14 +73,22 @@ CSettingsScreen::show()
if(!CPasswordScreen::show()) { if(!CPasswordScreen::show()) {
sprintf(str, "%.0fV", getHeaterInfo().getSystemVoltage()); if(HeaterManager.getHeaterStyle() == 0) {
_printMenuText(_display.width(), Line3, str, false, eRightJustify);
sprintf(str, "Min: %.1f/%d", getHeaterInfo().getPump_Min(), getHeaterInfo().getFan_Min()); sprintf(str, "%.0fV", getHeaterInfo().getSystemVoltage());
_printMenuText(0, Line3, str); _printMenuText(_display.width(), Line3, str, false, eRightJustify);
sprintf(str, "Max: %.1f/%d", getHeaterInfo().getPump_Max(), getHeaterInfo().getFan_Max()); sprintf(str, "Min: %.1f/%d", getHeaterInfo().getPump_Min(), getHeaterInfo().getFan_Min());
_printMenuText(0, Line2, str); _printMenuText(0, Line3, str);
sprintf(str, "Max: %.1f/%d", getHeaterInfo().getPump_Max(), getHeaterInfo().getFan_Max());
_printMenuText(0, Line2, str);
}
else {
_printMenuText(64, Line3, "Alternate Heater", false, eCentreJustify);
_printMenuText(64, Line2, "ECU cannot be tuned", false, eCentreJustify);
}
int yPos = 53; int yPos = 53;
int xPos = _display.xCentre(); int xPos = _display.xCentre();
@ -102,32 +112,33 @@ CSettingsScreen::animate()
_printMenuText(Column, Line2, " "); _printMenuText(Column, Line2, " ");
} }
else { else {
_animateCount++; if(HeaterManager.getHeaterStyle() == 0) {
WRAPUPPERLIMIT(_animateCount, 9, 0); _animateCount++;
WRAPUPPERLIMIT(_animateCount, 9, 0);
int glowDrive = getHeaterInfo().getGlow_Drive(); int glowDrive = getHeaterInfo().getGlow_Drive();
_printMenuText(Column, Line1, " "); _printMenuText(Column, Line1, " ");
if(_animateCount < 4) { if(_animateCount < 4) {
sprintf(msg, "PF-%d", glowDrive); sprintf(msg, "PF-%d", glowDrive);
_printMenuText(Column+6, Line1, msg); _printMenuText(Column+6, Line1, msg);
} }
else { else {
sprintf(msg, "(%dW)", plugPowers[glowDrive-1]); sprintf(msg, "(%dW)", plugPowers[glowDrive-1]);
_printMenuText(Column, Line1, msg); _printMenuText(Column, Line1, msg);
} }
int fanSensor = getHeaterInfo().getFan_Sensor(); int fanSensor = getHeaterInfo().getFan_Sensor();
if(_animateCount < 4) { if(_animateCount < 4) {
sprintf(msg, "SN-%d", fanSensor); sprintf(msg, "SN-%d", fanSensor);
_printMenuText(Column+6, Line2, msg); _printMenuText(Column+6, Line2, msg);
}
else {
int xPos = Column+6;
_printMenuText(xPos, Line2, " "); // erase
sprintf(msg, "(\365%d)", fanSensor); // \365 is division character
_printMenuText(xPos, Line2, msg);
}
} }
else {
int xPos = Column+6;
_printMenuText(xPos, Line2, " "); // erase
sprintf(msg, "(\365%d)", fanSensor); // \365 is division character
_printMenuText(xPos, Line2, msg);
}
} }
return true; return true;
} }
@ -137,7 +148,12 @@ CSettingsScreen::keyHandler(uint8_t event)
{ {
if(CPasswordScreen::keyHandler(event)) { // handles password collection if(CPasswordScreen::keyHandler(event)) { // handles password collection
if(_isPasswordOK()) { if(_isPasswordOK()) {
_ScreenManager.selectMenu(CScreenManager::TuningMenuLoop); if(HeaterManager.getHeaterStyle() == 0) {
_ScreenManager.selectMenu(CScreenManager::TuningMenuLoop);
}
else {
_ScreenManager.selectMenu(CScreenManager::TuningMenuLoop, CScreenManager::FuelCalUI);
}
} }
return true; return true;
} }

View file

@ -34,7 +34,7 @@ public:
bool show(); bool show();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
bool animate(); bool animate();
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -36,7 +36,7 @@ CTempSensorScreen::CTempSensorScreen(C128x64_OLED& display, CScreenManager& mgr)
_initUI(); _initUI();
} }
void bool
CTempSensorScreen::onSelect() CTempSensorScreen::onSelect()
{ {
CPasswordScreen::onSelect(); CPasswordScreen::onSelect();
@ -45,6 +45,7 @@ CTempSensorScreen::onSelect()
_nDS18B20 = getTempSensor().getDS18B20().getNumSensors(); _nDS18B20 = getTempSensor().getDS18B20().getNumSensors();
_bPrimary = NVstore.getHeaterTuning().BME280probe.bPrimary; _bPrimary = NVstore.getHeaterTuning().BME280probe.bPrimary;
_readNV(); _readNV();
return true;
} }
void void

View file

@ -47,7 +47,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
void adjust(int dir); void adjust(int dir);
}; };

View file

@ -48,7 +48,7 @@ CThermostatModeScreen::CThermostatModeScreen(C128x64_OLED& display, CScreenManag
_cyclicMode.init(); _cyclicMode.init();
} }
void bool
CThermostatModeScreen::onSelect() CThermostatModeScreen::onSelect()
{ {
CUIEditScreen::onSelect(); CUIEditScreen::onSelect();
@ -56,6 +56,7 @@ CThermostatModeScreen::onSelect()
_window = NVstore.getUserSettings().ThermostatWindow; _window = NVstore.getUserSettings().ThermostatWindow;
_thermoMode = NVstore.getUserSettings().ThermostatMethod; _thermoMode = NVstore.getUserSettings().ThermostatMethod;
_cyclicMode = NVstore.getUserSettings().cyclic; _cyclicMode = NVstore.getUserSettings().cyclic;
return true;
} }
void void

View file

@ -45,7 +45,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -31,7 +31,7 @@ CTimeoutsScreen::CTimeoutsScreen(C128x64_OLED& display, CScreenManager& mgr) : C
{ {
} }
void bool
CTimeoutsScreen::onSelect() CTimeoutsScreen::onSelect()
{ {
CUIEditScreen::onSelect(); CUIEditScreen::onSelect();
@ -39,6 +39,7 @@ CTimeoutsScreen::onSelect()
_frameRate = NVstore.getUserSettings().FrameRate; _frameRate = NVstore.getUserSettings().FrameRate;
_dispTimeout = NVstore.getUserSettings().dimTime; _dispTimeout = NVstore.getUserSettings().dimTime;
_menuTimeout = NVstore.getUserSettings().menuTimeout; _menuTimeout = NVstore.getUserSettings().menuTimeout;
return true;
} }
bool bool

View file

@ -43,7 +43,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
void adjust(int dir); void adjust(int dir);
}; };

View file

@ -45,10 +45,11 @@ CTimerChartScreen::CTimerChartScreen(C128x64_OLED& display, CScreenManager& mgr,
_instance = instance; _instance = instance;
} }
void bool
CTimerChartScreen::onSelect() CTimerChartScreen::onSelect()
{ {
CTimerManager::condenseMap(condensed); CTimerManager::condenseMap(condensed);
return true;
} }
bool bool

View file

@ -35,7 +35,7 @@ class CTimerChartScreen : public CUIEditScreen {
public: public:
CTimerChartScreen(C128x64_OLED& display, CScreenManager& mgr, int instance); CTimerChartScreen(C128x64_OLED& display, CScreenManager& mgr, int instance);
void onSelect(); bool onSelect();
bool show(); bool show();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
}; };

View file

@ -41,11 +41,12 @@ CUIEditScreen::CUIEditScreen(C128x64_OLED& display, CScreenManager& mgr) : CScre
_initUI(); _initUI();
} }
void bool
CUIEditScreen::onSelect() CUIEditScreen::onSelect()
{ {
CScreen::onSelect(); CScreen::onSelect();
_initUI(); _initUI();
return true;
} }
void void

View file

@ -42,7 +42,7 @@ protected:
int _animateCount; int _animateCount;
public: public:
CUIEditScreen(C128x64_OLED& display, CScreenManager& mgr); CUIEditScreen(C128x64_OLED& display, CScreenManager& mgr);
virtual void onSelect(); virtual bool onSelect();
bool show(); bool show();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
bool animate(); bool animate();

View file

@ -54,11 +54,12 @@ CVersionInfoScreen::CVersionInfoScreen(C128x64_OLED& display, CScreenManager& mg
{ {
} }
void bool
CVersionInfoScreen::onSelect() CVersionInfoScreen::onSelect()
{ {
CUIEditScreen::onSelect(); CUIEditScreen::onSelect();
checkFOTA(); checkFOTA();
return true;
} }
bool bool

View file

@ -37,7 +37,7 @@ public:
CVersionInfoScreen(C128x64_OLED& display, CScreenManager& mgr); CVersionInfoScreen(C128x64_OLED& display, CScreenManager& mgr);
bool show(); bool show();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
bool animate(); bool animate();
}; };

View file

@ -33,11 +33,11 @@ CWebPageUpdateScreen::CWebPageUpdateScreen(C128x64_OLED& display, CScreenManager
_holdoff = 0; _holdoff = 0;
} }
void bool
CWebPageUpdateScreen::onSelect() CWebPageUpdateScreen::onSelect()
{ {
CScreen::onSelect(); CScreen::onSelect();
return true;
} }

View file

@ -39,7 +39,7 @@ public:
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);
void onSelect(); bool onSelect();
}; };
#endif #endif

View file

@ -46,11 +46,12 @@ CWiFiScreen::CWiFiScreen(C128x64_OLED& display, CScreenManager& mgr) : CUIEditSc
_initUI(); _initUI();
} }
void bool
CWiFiScreen::onSelect() CWiFiScreen::onSelect()
{ {
CScreen::onSelect(); CScreen::onSelect();
_initUI(); _initUI();
return true;
} }
void void

View file

@ -31,7 +31,7 @@ class CScreenManager;
class CWiFiScreen : public CUIEditScreen { class CWiFiScreen : public CUIEditScreen {
public: public:
CWiFiScreen(C128x64_OLED& display, CScreenManager& mgr); CWiFiScreen(C128x64_OLED& display, CScreenManager& mgr);
void onSelect(); bool onSelect();
bool show(); bool show();
bool animate(); bool animate();
bool keyHandler(uint8_t event); bool keyHandler(uint8_t event);

View file

@ -636,6 +636,18 @@ const uint8_t PROGMEM startIcon[] =
}; };
const BITMAP_INFO StartIconInfo(5, 9, startIcon); const BITMAP_INFO StartIconInfo(5, 9, startIcon);
const uint8_t PROGMEM medStartIcon[] =
{
0x80, // #
0xC0, // ##
0xE0, // ###
0xF0, // ####
0xE0, // ###
0xC0, // ##
0x80, // #
};
const BITMAP_INFO medStartIconInfo(4, 7, medStartIcon);
const uint8_t PROGMEM miniStartIcon[] = const uint8_t PROGMEM miniStartIcon[] =
{ {
0x80, // # 0x80, // #
@ -659,6 +671,33 @@ const uint8_t PROGMEM stopIcon[] =
0x00, // 0x00, //
}; };
const BITMAP_INFO StopIconInfo(6, 8, stopIcon); const BITMAP_INFO StopIconInfo(6, 8, stopIcon);
const uint8_t PROGMEM medStopIcon[] =
{
0xF8, // #####
0xF8, // #####
0xF8, // #####
0xF8, // #####
0xF8, // #####
};
const BITMAP_INFO medStopIconInfo(5, 5, medStopIcon);
// 'wifiInIcon, 5x5px
const uint8_t dnIcon [] PROGMEM = {
0xfe, // #######
0x7c, // #####
0x38, // ###
0x10, // #
};
const BITMAP_INFO dnIconInfo(7, 4, dnIcon);
// 'wifiOutIcon, 5x5px
const uint8_t upIcon [] PROGMEM = {
0x10, // #
0x38, // ###
0x7c, // #####
0xfe, // #######
};
const BITMAP_INFO upIconInfo(7, 4, upIcon);
const uint8_t PROGMEM miniStopIcon[] = const uint8_t PROGMEM miniStopIcon[] =
{ {

View file

@ -97,12 +97,17 @@ extern const BITMAP_INFO BulbOffIconInfo;
// Bitmap for start // Bitmap for start
extern const BITMAP_INFO StartIconInfo; extern const BITMAP_INFO StartIconInfo;
extern const BITMAP_INFO medStartIconInfo;
extern const BITMAP_INFO miniStartIconInfo; extern const BITMAP_INFO miniStartIconInfo;
// Bitmap sizes for stop // Bitmap sizes for stop
extern const BITMAP_INFO StopIconInfo; extern const BITMAP_INFO StopIconInfo;
extern const BITMAP_INFO medStopIconInfo;
extern const BITMAP_INFO miniStopIconInfo; extern const BITMAP_INFO miniStopIconInfo;
extern const BITMAP_INFO dnIconInfo;
extern const BITMAP_INFO upIconInfo;
// Bitmap for displayTimeout // Bitmap for displayTimeout
extern const BITMAP_INFO DisplayTimeoutIconInfo; extern const BITMAP_INFO DisplayTimeoutIconInfo;

View file

@ -33,14 +33,11 @@
#include "../Utility/macros.h" #include "../Utility/macros.h"
// Setup Serial Port Definitions // Setup Serial Port Definitions
#if defined(__arm__)
// Required for Arduino Due, UARTclass is derived from HardwareSerial
static UARTClass& BlueWireSerial(Serial1);
#else
// for ESP32, Mega // for ESP32, Mega
// HardwareSerial is it for these boards // HardwareSerial is it for these boards
static HardwareSerial& BlueWireSerial(Serial1); static HardwareSerial& BlueWireSerial(Serial1);
#endif
CBlueWireCommsTask BlueWireCommsTask; // AltCommsTaskInfo;
#define RX_DATA_TIMOUT 50 #define RX_DATA_TIMOUT 50
@ -53,7 +50,7 @@ CProtocol HeaterFrame2; // data packet received from heater in resp
// CSmartError SmartError; // CSmartError SmartError;
CProtocolPackage reportHeaterData; CProtocolPackage reportHeaterData;
CProtocolPackage primaryHeaterData; CProtocolPackage primaryHeaterData;
char dbgMsg[BLUEWIRE_MSGQUEUESIZE]; char dbgMsg[COMMS_MSGQUEUESIZE];
static bool bHasOEMController = false; static bool bHasOEMController = false;
static bool bHasOEMLCDController = false; static bool bHasOEMLCDController = false;
@ -64,36 +61,62 @@ extern bool bReportOEMresync;
extern bool bReportBlueWireData; extern bool bReportBlueWireData;
extern sFilteredData FilteredSamples; extern sFilteredData FilteredSamples;
QueueHandle_t BlueWireMsgQueue = NULL; // cannot use general Serial.print etc from this task without causing conflicts // QueueHandle_t BlueWireMsgQueue = NULL; // cannot use general Serial.print etc from this task without causing conflicts
QueueHandle_t BlueWireRxQueue = NULL; // queue to pass down heater receive data // QueueHandle_t BlueWireRxQueue = NULL; // queue to pass down heater receive data
QueueHandle_t BlueWireTxQueue = NULL; // queue to pass down heater transmit data // QueueHandle_t BlueWireTxQueue = NULL; // queue to pass down heater transmit data
SemaphoreHandle_t BlueWireSemaphore = NULL; // flag to indicate completion of heater data exchange // SemaphoreHandle_t BlueWireSemaphore = NULL; // flag to indicate completion of heater data exchange
bool validateFrame(const CProtocol& frame, const char* name); bool validateFrame(const CProtocol& frame, const char* name);
void DebugReportFrame(const char* hdr, const CProtocol& Frame, const char* ftr, char* msg); void DebugReportFrame(const char* hdr, const CProtocol& Frame, const char* ftr, char* msg);
// void updateFilteredData(); // void updateFilteredData();
void initBlueWireSerial(); void initBlueWireSerial();
void pushDebugMsg(const char* msg) { /*void pushDebugMsg(const char* msg) {
if(BlueWireMsgQueue) if(BlueWireMsgQueue)
xQueueSend(BlueWireMsgQueue, msg, 0); xQueueSend(BlueWireMsgQueue, msg, 0);
}*/
void pushDebugMsg(const char* msg) {
BlueWireCommsTask.putMsgQueue(msg);
} }
void BlueWireTask(void*) {
CBlueWireCommsTask::CBlueWireCommsTask()
{
}
void
CBlueWireCommsTask::commsTask(void* arg)
{
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// Blue wire data reception // Blue wire data reception
// Reads data from the "blue wire" Serial port, (to/from heater) // Reads data from the "blue wire" Serial port, (to/from heater)
// If an OEM controller exists we will also see it's data frames // If an OEM controller exists we will also see it's data frames
// Note that the data is read now, then held for later use in the state machine // Note that the data is read now, then held for later use in the state machine
// //
CBlueWireCommsTask* pThis = (CBlueWireCommsTask*)arg;
pThis->_task(); // loops here until terminated
vTaskDelete(NULL); // NEVER fall out from a task!
for(;;);
}
void
CBlueWireCommsTask::_task()
{
static unsigned long lastRxTime = 0; // used to observe inter character delays static unsigned long lastRxTime = 0; // used to observe inter character delays
static unsigned long moderator = 50; static unsigned long moderator = 50;
bool isBTCmaster = false; bool isBTCmaster = false;
BlueWireMsgQueue = xQueueCreate(4, BLUEWIRE_MSGQUEUESIZE); // create FreeRTOS queues etc
BlueWireRxQueue = xQueueCreate(4, BLUEWIRE_DATAQUEUESIZE); create(BLUEWIRE_DATAQUEUESIZE);
BlueWireTxQueue = xQueueCreate(4, BLUEWIRE_DATAQUEUESIZE); // BlueWireMsgQueue = xQueueCreate(4, BLUEWIRE_MSGQUEUESIZE);
BlueWireSemaphore = xSemaphoreCreateBinary(); // BlueWireRxQueue = xQueueCreate(4, BLUEWIRE_DATAQUEUESIZE);
// BlueWireTxQueue = xQueueCreate(4, BLUEWIRE_DATAQUEUESIZE);
// BlueWireSemaphore = xSemaphoreCreateBinary();
TxManage.begin(); // ensure Tx enable pin is setup TxManage.begin(); // ensure Tx enable pin is setup
@ -107,12 +130,15 @@ void BlueWireTask(void*) {
DefaultBTCParams.setFan_Max(4500); DefaultBTCParams.setFan_Max(4500);
DefaultBTCParams.Controller.FanSensor = 1; DefaultBTCParams.Controller.FanSensor = 1;
initBlueWireSerial(); _initSerial();
// initBlueWireSerial();
CommState.setCallback(pushDebugMsg); CommState.setCallback(pushDebugMsg);
TxManage.setCallback(pushDebugMsg); TxManage.setCallback(pushDebugMsg);
for(;;) { // for(;;) {
_runState = 1;
while(_runState == 1) {
sRxData BlueWireRxData; sRxData BlueWireRxData;
unsigned long timenow = millis(); unsigned long timenow = millis();
@ -231,6 +257,8 @@ void BlueWireTask(void*) {
// collect OEM controller frame // collect OEM controller frame
if(BlueWireRxData.available()) { if(BlueWireRxData.available()) {
digitalWrite(LED_Pin, LOW);
digitalWrite(LED_Pin, HIGH);
if(CommState.collectData(OEMCtrlFrame, BlueWireRxData.getValue()) ) { if(CommState.collectData(OEMCtrlFrame, BlueWireRxData.getValue()) ) {
CommState.set(CommStates::OEMCtrlValidate); // collected 24 bytes, move on! CommState.set(CommStates::OEMCtrlValidate); // collected 24 bytes, move on!
} }
@ -264,6 +292,8 @@ void BlueWireTask(void*) {
// collect heater frame, always in response to an OEM controller frame // collect heater frame, always in response to an OEM controller frame
if(BlueWireRxData.available()) { if(BlueWireRxData.available()) {
digitalWrite(LED_Pin, LOW);
digitalWrite(LED_Pin, HIGH);
if( CommState.collectData(HeaterFrame1, BlueWireRxData.getValue()) ) { if( CommState.collectData(HeaterFrame1, BlueWireRxData.getValue()) ) {
CommState.set(CommStates::HeaterValidate1); CommState.set(CommStates::HeaterValidate1);
} }
@ -302,7 +332,7 @@ void BlueWireTask(void*) {
case CommStates::TxStart: case CommStates::TxStart:
xQueueSend(BlueWireTxQueue, TxManage.getFrame().Data, 0); xQueueSend(_txQueue, TxManage.getFrame().Data, 0);
TxManage.Start(timenow); TxManage.Start(timenow);
CommState.set(CommStates::TxInterval); CommState.set(CommStates::TxInterval);
break; break;
@ -356,7 +386,8 @@ void BlueWireTask(void*) {
// received heater frame (after our control message), report // received heater frame (after our control message), report
xQueueSend(BlueWireRxQueue, HeaterFrame2.Data, 0); xQueueSend(_rxQueue, HeaterFrame2.Data, 0);
_online = true;
// do some monitoring of the heater state variables // do some monitoring of the heater state variables
// if abnormal transitions, introduce a smart error! // if abnormal transitions, introduce a smart error!
@ -374,7 +405,7 @@ void BlueWireTask(void*) {
case CommStates::ExchangeComplete: case CommStates::ExchangeComplete:
xSemaphoreGive(BlueWireSemaphore); xSemaphoreGive(_semaphore);
CommState.set(CommStates::Idle); CommState.set(CommStates::Idle);
break; break;
} // switch(CommState) } // switch(CommState)
@ -382,11 +413,26 @@ void BlueWireTask(void*) {
#if DBG_FREERTOS == 1 #if DBG_FREERTOS == 1
digitalWrite(GPIOout1_pin, LOW); digitalWrite(GPIOout1_pin, LOW);
#endif #endif
vTaskDelay(1); if (!BlueWireSerial.available()) {
vTaskDelay(1);
}
#if DBG_FREERTOS == 1 #if DBG_FREERTOS == 1
digitalWrite(GPIOout1_pin, HIGH); digitalWrite(GPIOout1_pin, HIGH);
#endif #endif
} }
BlueWireSerial.end();
// return pins to standard GPIO functions
pinMode(Tx1Pin, OUTPUT);
pinMode(Rx1Pin, INPUT_PULLUP); // required for MUX to work properly
pinMode(TxEnbPin, OUTPUT);
digitalWrite(Tx1Pin, HIGH);
digitalWrite(TxEnbPin, LOW);
_runState = 0;
DebugPort.println("Blue wire task concluded");
} }
@ -435,20 +481,16 @@ bool hasHtrData()
return bHasHtrData; return bHasHtrData;
} }
void initBlueWireSerial() void
CBlueWireCommsTask::_initSerial()
{ {
// initialize serial port to interact with the "blue wire" // initialize serial port to interact with the "blue wire"
// 25000 baud, Tx and Rx channels of Chinese heater comms interface: // 25000 baud, Tx and Rx channels of Chinese heater comms interface:
// Tx/Rx data to/from heater, // Tx/Rx data to/from heater,
// Note special baud rate for Chinese heater controllers // Note special baud rate for Chinese heater controllers
#if defined(__arm__) || defined(__AVR__)
BlueWireSerial.begin(25000);
pinMode(Rx1Pin, INPUT_PULLUP); // required for MUX to work properly
#elif ESP32
// ESP32 // ESP32
BlueWireSerial.begin(25000, SERIAL_8N1, Rx1Pin, Tx1Pin); // need to explicitly specify pins for pin multiplexer! BlueWireSerial.begin(25000, SERIAL_8N1, Rx1Pin, Tx1Pin); // need to explicitly specify pins for pin multiplexer!
pinMode(Rx1Pin, INPUT_PULLUP); // required for MUX to work properly pinMode(Rx1Pin, INPUT_PULLUP); // required for MUX to work properly
#endif
} }
// 0x00 - Normal: BTC, with heater responding // 0x00 - Normal: BTC, with heater responding
@ -479,4 +521,15 @@ void reqPumpPrime(bool on)
TxManage.reqPrime(on); TxManage.reqPrime(on);
} }
void
CBlueWireCommsTask::taskStart()
{
CCommsTask::taskStart();
_runState = 0;
xTaskCreate(commsTask,
"BlueWireTask",
1600,
this,
TASK_PRIORITY_HEATERCOMMS,
&_taskHandle);
}

View file

@ -24,6 +24,7 @@
#include <FreeRTOS.h> #include <FreeRTOS.h>
#include "../Utility/UtilClasses.h" #include "../Utility/UtilClasses.h"
#include "CommsTask.h"
extern QueueHandle_t BlueWireMsgQueue; // cannot use general Serial.print etc from this task without causing conflicts extern QueueHandle_t BlueWireMsgQueue; // cannot use general Serial.print etc from this task without causing conflicts
extern QueueHandle_t BlueWireRxQueue; // queue to pass down heater receive data extern QueueHandle_t BlueWireRxQueue; // queue to pass down heater receive data
@ -33,8 +34,21 @@ extern SemaphoreHandle_t BlueWireSemaphore; // flag to indicate completion of h
const int BLUEWIRE_MSGQUEUESIZE = 192; const int BLUEWIRE_MSGQUEUESIZE = 192;
const int BLUEWIRE_DATAQUEUESIZE = 24; const int BLUEWIRE_DATAQUEUESIZE = 24;
extern void BlueWireTask(void*); // extern void BlueWireTask(void*);
extern CommStates CommState; extern CommStates CommState;
class CBlueWireCommsTask : public CCommsTask {
protected:
static void commsTask(void* arg);
void _initSerial();
void _task();
public:
CBlueWireCommsTask();
void taskStart();
};
extern CBlueWireCommsTask BlueWireCommsTask; // AltCommsTaskInfo;
#endif #endif

View file

@ -25,7 +25,23 @@
#include "../Utility/helpers.h" #include "../Utility/helpers.h"
#include "../cfg/BTCConfig.h" #include "../cfg/BTCConfig.h"
#include "../Utility/macros.h" #include "../Utility/macros.h"
#include "BlueWireTask.h"
#include "SmartError.h"
#include "../Utility/FuelGauge.h"
#include "../Utility/DataFilter.h"
#include "../Utility/HourMeter.h"
#include "../RTC/RTCStore.h"
CProtocol BlueWireRxData;
CProtocol BlueWireTxData;
CProtocolPackage BlueWireData;
void updateFilteredData(CProtocol& HeaterInfo);
const CProtocolPackage& getHeaterInfo()
{
return BlueWireData;
}
void void
CProtocol::setCRC() CProtocol::setCRC()
@ -233,11 +249,19 @@ CProtocol::getVoltage_Supply() const
} }
void void
CProtocol::setAltitude(float altitude) CProtocol::setAltitude(float altitude, bool valid)
{ {
int16_t alt = (int16_t)altitude; int16_t alt = (int16_t)altitude;
Controller.Altitude_MSB = (alt >> 8) & 0xff; Controller.Altitude_MSB = (alt >> 8) & 0xff;
Controller.Altitude_LSB = (alt >> 0) & 0xff; Controller.Altitude_LSB = (alt >> 0) & 0xff;
if(valid) {
Controller.Unknown1_MSB = 0xeb;
Controller.Unknown1_LSB = 0x47;
}
else {
Controller.Unknown1_MSB = 0x01; // always 0x01
Controller.Unknown1_LSB = 0x2c; // always 0x2c 16bit: "300 secs = max run without burn detected" ??
}
} }
int int
@ -342,88 +366,88 @@ int CProtocolPackage::getRunStateEx() const
return runstate; return runstate;
} }
const char* Runstates [] PROGMEM = { // const char* Runstates [] PROGMEM = {
" Stopped/Ready ", // 0 // " Stopped/Ready ", // 0
"Starting...", // 1 // "Starting...", // 1
"Igniting...", // 2 // "Igniting...", // 2
"Ignition retry pause", // 3 // "Ignition retry pause", // 3
"Ignited", // 4 // "Ignited", // 4
"Running", // 5 // "Running", // 5
"Stopping", // 6 // "Stopping", // 6
"Shutting down", // 7 // "Shutting down", // 7
"Cooling", // 8 // "Cooling", // 8
"Heating glow plug", // 9 - interpreted state - actually runstate 2 with no pump action! // "Heating glow plug", // 9 - interpreted state - actually runstate 2 with no pump action!
"Suspended", // 10 - interpreted state - cyclic mode has suspended heater // "Suspended", // 10 - interpreted state - cyclic mode has suspended heater
"Suspending...", // 11 - interpreted state - cyclic mode is suspending heater // "Suspending...", // 11 - interpreted state - cyclic mode is suspending heater
"Suspend cooling", // 12 - interpreted state - cyclic mode is suspending heater // "Suspend cooling", // 12 - interpreted state - cyclic mode is suspending heater
"Unknown run state" // "Unknown run state"
}; // };
const char* // const char*
CProtocolPackage::getRunStateStr() const // CProtocolPackage::getRunStateStr() const
{ // {
uint8_t runstate = getRunStateEx(); // uint8_t runstate = getRunStateEx();
UPPERLIMIT(runstate, 13); // UPPERLIMIT(runstate, 13);
if(runstate == 2 && getPump_Actual() == 0) { // split runstate 2 - glow, then fuel // if(runstate == 2 && getPump_Actual() == 0) { // split runstate 2 - glow, then fuel
runstate = 9; // runstate = 9;
} // }
return Runstates[runstate]; // return Runstates[runstate];
} // }
const char* Errstates [] PROGMEM = { // const char* Errstates [] PROGMEM = {
"", // [0] // "", // [0]
"", // [1] // "", // [1]
"Low voltage", // [2] E-01 // "Low voltage", // [2] E-01
"High voltage", // [3] E-02 // "High voltage", // [3] E-02
"Glow plug fault", // [4] E-03 // "Glow plug fault", // [4] E-03
"Pump fault", // [5] E-04 // "Pump fault", // [5] E-04
"Overheat", // [6] E-05 // "Overheat", // [6] E-05
"Motor fault", // [7] E-06 // "Motor fault", // [7] E-06
"Comms fault", // [8] E-07 // "Comms fault", // [8] E-07
"Flame out", // [9] E-08 // "Flame out", // [9] E-08
"Temp sense", // [10] E-09 // "Temp sense", // [10] E-09
"Ignition fail", // [11] E-10 SmartError manufactured state - sensing runstate 2 -> >5 // "Ignition fail", // [11] E-10 SmartError manufactured state - sensing runstate 2 -> >5
"Failed 1st ignite", // [12] E-11 SmartError manufactured state - sensing runstate 2 -> 3 // "Failed 1st ignite", // [12] E-11 SmartError manufactured state - sensing runstate 2 -> 3
"Excess fuel usage", // [13] E-12 SmartError manufactured state - excess fuel consumed // "Excess fuel usage", // [13] E-12 SmartError manufactured state - excess fuel consumed
"Unknown error?" // mystery code! // "Unknown error?" // mystery code!
}; // };
const char* ErrstatesEx [] PROGMEM = { // const char* ErrstatesEx [] PROGMEM = {
"E-00: OK", // [0] // "E-00: OK", // [0]
"E-00: OK", // [1] // "E-00: OK", // [1]
"E-01: Low voltage", // [2] E-01 // "E-01: Low voltage", // [2] E-01
"E-02: High voltage", // [3] E-02 // "E-02: High voltage", // [3] E-02
"E-03: Glow plug fault", // [4] E-03 // "E-03: Glow plug fault", // [4] E-03
"E-04: Pump fault", // [5] E-04 // "E-04: Pump fault", // [5] E-04
"E-05: Overheat", // [6] E-05 // "E-05: Overheat", // [6] E-05
"E-06: Motor fault", // [7] E-06 // "E-06: Motor fault", // [7] E-06
"E-07: No heater comms", // [8] E-07 // "E-07: No heater comms", // [8] E-07
"E-08: Flame out", // [9] E-08 // "E-08: Flame out", // [9] E-08
"E-09: Temp sense", // [10] E-09 // "E-09: Temp sense", // [10] E-09
"E-10: Ignition fail", // [11] E-10 SmartError manufactured state - sensing runstate 2 -> >5 // "E-10: Ignition fail", // [11] E-10 SmartError manufactured state - sensing runstate 2 -> >5
"E-11: Failed 1st ignite", // [12] E-11 SmartError manufactured state - sensing runstate 2 -> 3 // "E-11: Failed 1st ignite", // [12] E-11 SmartError manufactured state - sensing runstate 2 -> 3
"E-12: Excess fuel shutdown", // [13] E-12 SmartError manufactured state - excess fuel consumed // "E-12: Excess fuel shutdown", // [13] E-12 SmartError manufactured state - excess fuel consumed
"Unknown error?" // mystery code! // "Unknown error?" // mystery code!
}; // };
const char* // const char*
CProtocolPackage::getErrStateStr() const // CProtocolPackage::getErrStateStr() const
{ // {
uint8_t errstate = getErrState(); // uint8_t errstate = getErrState();
UPPERLIMIT(errstate, 13); // UPPERLIMIT(errstate, 13);
return Errstates[errstate]; // return Errstates[errstate];
} // }
const char* // const char*
CProtocolPackage::getErrStateStrEx() const // CProtocolPackage::getErrStateStrEx() const
{ // {
uint8_t errstate = getErrState(); // uint8_t errstate = getErrState();
UPPERLIMIT(errstate, 13); // UPPERLIMIT(errstate, 13);
return ErrstatesEx[errstate]; // return ErrstatesEx[errstate];
} // }
/*void /*void
CProtocolPackage::setRefTime() CProtocolPackage::setRefTime()
@ -471,3 +495,52 @@ CProtocolPackage::getErrState() const
} }
void checkBlueWireRxEvents()
{
// collect and process received heater data from blue wire task
if(BlueWireCommsTask.getRxQueue( BlueWireRxData.Data) ) {
// if(BlueWireRxQueue && xQueueReceive(BlueWireRxQueue, BlueWireRxData.Data, 0)) {
BlueWireData.set(BlueWireRxData, BlueWireTxData);
SmartError.monitor(BlueWireRxData);
updateFilteredData(BlueWireRxData);
FuelGauge.Integrate(BlueWireRxData.getPump_Actual());
if(INBOUNDS(BlueWireRxData.getRunState(), 1, 5)) { // check for Low Voltage Cutout
SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
SmartError.checkfuelUsage();
}
// trap being in state 0 with a heater error - cancel user on memory to avoid unexpected cyclic restarts
if(RTC_Store.getUserStart() && (BlueWireRxData.getRunState() == 0) && (BlueWireRxData.getErrState() > 1)) {
DebugPort.println("Forcing cyclic cancel due to error induced shutdown");
// DebugPort.println("Forcing cyclic cancel due to error induced shutdown");
RTC_Store.setUserStart(false);
}
pHourMeter->monitor(BlueWireRxData);
}
}
void checkBlueWireTxEvents()
{
// collect transmitted heater data from blue wire task
if(BlueWireCommsTask.getTxQueue(BlueWireTxData.Data) ) {
}
// if(BlueWireTxQueue && xQueueReceive(BlueWireTxQueue, BlueWireTxData.Data, 0)) {
// }
}
void updateFilteredData(CProtocol& HeaterInfo)
{
FilteredSamples.ipVolts.update(HeaterInfo.getVoltage_Supply());
FilteredSamples.GlowVolts.update(HeaterInfo.getGlowPlug_Voltage());
FilteredSamples.GlowAmps.update(HeaterInfo.getGlowPlug_Current());
FilteredSamples.Fan.update(HeaterInfo.getFan_Actual());
FilteredSamples.FastipVolts.update(HeaterInfo.getVoltage_Supply());
FilteredSamples.FastGlowAmps.update(HeaterInfo.getGlowPlug_Current());
}

View file

@ -162,7 +162,7 @@ public:
int16_t getTemperature_HeatExchg() const; // temperature of heat exchanger int16_t getTemperature_HeatExchg() const; // temperature of heat exchanger
void setTemperature_HeatExchg(uint16_t degC); // temperature of heat exchanger void setTemperature_HeatExchg(uint16_t degC); // temperature of heat exchanger
// altitude // altitude
void setAltitude(float altitude); void setAltitude(float altitude, bool valid);
int getAltitude() const; int getAltitude() const;
void DebugReport(const char* hdr, const char* ftr); void DebugReport(const char* hdr, const char* ftr);
@ -217,6 +217,9 @@ public:
void reportFrames(bool isOEM, std::function<void(const char*)> pushMsg); void reportFrames(bool isOEM, std::function<void(const char*)> pushMsg);
}; };
void checkBlueWireRxEvents();
void checkBlueWireTxEvents();
extern const CProtocolPackage& getHeaterInfo(); extern const CProtocolPackage& getHeaterInfo();
#endif #endif

View file

@ -173,10 +173,16 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
float altitude; float altitude;
if(getTempSensor().getAltitude(altitude)) { // if a BME280 is fitted if(getTempSensor().getAltitude(altitude)) { // if a BME280 is fitted
m_TxFrame.setAltitude(altitude); // use calcualted height
// set 0xeb 0x47 in "unknown bytes"
// - 0xeb happens with all pressure quipped units
// - 0x47 with all other than coffee pod which sends 0x00?
m_TxFrame.setAltitude(altitude, true);
} }
else { else {
m_TxFrame.setAltitude(3500); // default height - yes it is weird, but that's what the simple controllers send! // default height - yes it is weird, but that's what the simple controllers send!
// set 0x01 0x2c in "unknown bytes" - all no pressure equipped OEM controlelrs do that
m_TxFrame.setAltitude(3500, false);
} }
m_TxFrame.setPump_Prime(_prime); m_TxFrame.setPump_Prime(_prime);

View file

@ -29,7 +29,6 @@
#include "../Utility/NVStorage.h" #include "../Utility/NVStorage.h"
#include "../Utility/DebugPort.h" #include "../Utility/DebugPort.h"
// create ONE of the RTClib supported real time clock classes // create ONE of the RTClib supported real time clock classes
#if RTC_USE_DS3231 == 1 #if RTC_USE_DS3231 == 1
RTC_DS3231Ex rtc; RTC_DS3231Ex rtc;

View file

@ -31,17 +31,17 @@
// MAXIMUM OF 7 BYTES // MAXIMUM OF 7 BYTES
// //
// [0..3] float fuelGauge strokes // [0..3] float fuelGauge strokes
// [4] uint8_t DesiredTemp (typ. 8-35) // [4] int8_t DesiredTemp (typ. 8-35)
// [5] uint8_t DesiredPump (typ. 8-35) // [5] int8_t DesiredPump (typ. 8-35)
// [6] uint8_t spare // [6] uint8_t spare
// //
// ____________________________________________________ // _________________________________________________________
// | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
// |---------------|------|-----------------------------| // |---------------|-----------|-----------------------------|
// Byte[4]: | CyclicEngaged | bit6 | Desired Deg Celcius | // Byte[4]: | CyclicEngaged | BootInit | Desired Deg Celcius |
// |---------------|------|-----------------------------| // |---------------|-----------|-----------------------------|
// Byte[5]: | | | Desired Pump Speed | // Byte[5]: | Spare | FrostMode | Desired Pump Speed |
// ---------------------------------------------------- // ---------------------------------------------------------
CRTC_Store::CRTC_Store() CRTC_Store::CRTC_Store()
{ {
@ -99,13 +99,13 @@ CRTC_Store::getFuelGauge()
} }
void void
CRTC_Store::setDesiredTemp(uint8_t val) CRTC_Store::setDesiredTemp(int8_t val)
{ {
_demandDegC = val; _demandDegC = val;
_PackAndSaveByte4(); _PackAndSaveByte4();
} }
uint8_t int8_t
CRTC_Store::getDesiredTemp() CRTC_Store::getDesiredTemp()
{ {
_ReadAndUnpackByte4(); _ReadAndUnpackByte4();
@ -141,13 +141,13 @@ CRTC_Store::setUserStart(bool active)
} }
void void
CRTC_Store::setDesiredPump(uint8_t val) CRTC_Store::setDesiredPump(int8_t val)
{ {
_demandPump = val; _demandPump = val;
_PackAndSaveByte5(); _PackAndSaveByte5();
} }
uint8_t int8_t
CRTC_Store::getDesiredPump() CRTC_Store::getDesiredPump()
{ {
_ReadAndUnpackByte5(); _ReadAndUnpackByte5();

View file

@ -28,10 +28,10 @@
class CRTC_Store { class CRTC_Store {
bool _accessed[4]; // [0] - bytes 0..3, [1] byte 4, [2] byte 5, [3] byte 6 bool _accessed[4]; // [0] - bytes 0..3, [1] byte 4, [2] byte 5, [3] byte 6
float _fuelgauge; // Byte0..Byte3 float _fuelgauge; // Byte0..Byte3
uint8_t _demandDegC; // Byte4[0..5] int8_t _demandDegC; // Byte4[0..5]
bool _BootInit; // Byte4[6] bool _BootInit; // Byte4[6]
bool _userStart; // Byte4[7] bool _userStart; // Byte4[7]
uint8_t _demandPump; // Byte5[0..5] int8_t _demandPump; // Byte5[0..5]
bool _frostOn; // Byte5[6] bool _frostOn; // Byte5[6]
bool _spare; // Byte5[7] bool _spare; // Byte5[7]
uint8_t _RunTime; // Byte6[0..4] uint8_t _RunTime; // Byte6[0..4]
@ -46,8 +46,8 @@ public:
CRTC_Store(); CRTC_Store();
void begin(); void begin();
void setFuelGauge(float val); void setFuelGauge(float val);
void setDesiredTemp(uint8_t val); void setDesiredTemp(int8_t val);
void setDesiredPump(uint8_t val); void setDesiredPump(int8_t val);
void resetRunTime(); void resetRunTime();
void resetGlowTime(); void resetGlowTime();
bool incRunTime(); bool incRunTime();
@ -55,8 +55,8 @@ public:
void setUserStart(bool state); void setUserStart(bool state);
void setBootInit(bool val = true); void setBootInit(bool val = true);
float getFuelGauge(); float getFuelGauge();
uint8_t getDesiredTemp(); int8_t getDesiredTemp();
uint8_t getDesiredPump(); int8_t getDesiredPump();
bool getUserStart(); bool getUserStart();
bool getBootInit(); bool getBootInit();
int getRunTime(); int getRunTime();

View file

@ -227,6 +227,10 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
int minute = currentTime.minute(); int minute = currentTime.minute();
int dow = currentTime.dayOfTheWeek(); int dow = currentTime.dayOfTheWeek();
if(!INBOUNDS(dow, 0, 6)) DebugPort.printf("CTimerManager::manageTime out of bounds dow : %d\r\n", dow);
if(!INBOUNDS(minute, 0, 59)) DebugPort.printf("CTimerManager::manageTime out of bounds minute : %d\r\n", minute);
if(!INBOUNDS(hour, 0, 23)) DebugPort.printf("CTimerManager::manageTime out of bounds hour : %d\r\n", hour);
int retval = 0; int retval = 0;
int dayMinute = (hour * 60) + minute; int dayMinute = (hour * 60) + minute;
int newID = _weekMap[dow][dayMinute]; int newID = _weekMap[dow][dayMinute];

View file

@ -210,6 +210,17 @@ struct sGPIOparams {
CGPIOout2::Modes out2Mode; CGPIOout2::Modes out2Mode;
CGPIOalg::Modes algMode; CGPIOalg::Modes algMode;
int8_t thresh[2]; int8_t thresh[2];
sGPIOparams& operator=(const sGPIOparams& rhs) {
in1Mode = rhs.in1Mode;
in2Mode = rhs.in2Mode;
out1Mode = rhs.out1Mode;
out2Mode = rhs.out2Mode;
algMode = rhs.algMode;
thresh[0] = rhs.thresh[0];
thresh[1] = rhs.thresh[1];
return *this;
}
}; };
struct sGPIO { struct sGPIO {

View file

@ -34,6 +34,7 @@
#include "../cfg/BTCConfig.h" #include "../cfg/BTCConfig.h"
#include "macros.h" #include "macros.h"
#include "../Protocol/Protocol.h" #include "../Protocol/Protocol.h"
#include "../Protocol/HeaterManager.h"
#include <string.h> #include <string.h>
#include "HourMeter.h" #include "HourMeter.h"
#include "TempSense.h" #include "TempSense.h"
@ -172,27 +173,41 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len)
bSend |= moderator.addJson("TempDesired", CDemandManager::getDemand(), root); bSend |= moderator.addJson("TempDesired", CDemandManager::getDemand(), root);
bSend |= moderator.addJson("TempMode", NVstore.getUserSettings().degF, root); bSend |= moderator.addJson("TempMode", NVstore.getUserSettings().degF, root);
if(NVstore.getUserSettings().menuMode < 2) { if(NVstore.getUserSettings().menuMode < 2) {
bSend |= moderator.addJson("TempMin", getHeaterInfo().getTemperature_Min(), root); if(HeaterManager.getHeaterStyle() == 0) {
bSend |= moderator.addJson("TempMax", getHeaterInfo().getTemperature_Max(), root); bSend |= moderator.addJson("TempMin", getHeaterInfo().getTemperature_Min(), root);
bSend |= moderator.addJson("TempBody", getHeaterInfo().getTemperature_HeatExchg(), root, 5000); bSend |= moderator.addJson("TempMax", getHeaterInfo().getTemperature_Max(), root);
bSend |= moderator.addJson("RunState", getHeaterInfo().getRunStateEx(), root); }
bSend |= moderator.addJson("RunString", getHeaterInfo().getRunStateStr(), root); // verbose it up! // bSend |= moderator.addJson("TempBody", getHeaterInfo().getTemperature_HeatExchg(), root, 5000);
bSend |= moderator.addJson("ErrorState", getHeaterInfo().getErrState(), root ); // bSend |= moderator.addJson("RunState", getHeaterInfo().getRunStateEx(), root);
bSend |= moderator.addJson("ErrorString", getHeaterInfo().getErrStateStrEx(), root); // verbose it up! // bSend |= moderator.addJson("RunString", getHeaterInfo().getRunStateStr(), root); // verbose it up!
// bSend |= moderator.addJson("ErrorState", getHeaterInfo().getErrState(), root );
// bSend |= moderator.addJson("ErrorString", getHeaterInfo().getErrStateStrEx(), root); // verbose it up!
bSend |= moderator.addJson("TempBody", HeaterManager.getBodyTemp(), root, 5000);
bSend |= moderator.addJson("RunState", HeaterManager.getRunStateEx(), root);
bSend |= moderator.addJson("RunString", HeaterManager.getRunStateStr(), root); // verbose it up!
bSend |= moderator.addJson("ErrorState", HeaterManager.getErrState(), root );
bSend |= moderator.addJson("ErrorString", HeaterManager.getErrStateStrEx(), root); // verbose it up!
bSend |= moderator.addJson("Thermostat", CDemandManager::isThermostat(), root ); bSend |= moderator.addJson("Thermostat", CDemandManager::isThermostat(), root );
bSend |= moderator.addJson("PumpFixed", getHeaterInfo().getPump_Fixed(), root ); bSend |= moderator.addJson("PumpFixed", getHeaterInfo().getPump_Fixed(), root );
bSend |= moderator.addJson("PumpMin", getHeaterInfo().getPump_Min(), root ); if(HeaterManager.getHeaterStyle() == 0) {
bSend |= moderator.addJson("PumpMax", getHeaterInfo().getPump_Max(), root ); bSend |= moderator.addJson("PumpMin", getHeaterInfo().getPump_Min(), root );
bSend |= moderator.addJson("PumpActual", getHeaterInfo().getPump_Actual(), root ); bSend |= moderator.addJson("PumpMax", getHeaterInfo().getPump_Max(), root );
bSend |= moderator.addJson("FanMin", getHeaterInfo().getFan_Min(), root ); bSend |= moderator.addJson("FanMin", getHeaterInfo().getFan_Min(), root );
bSend |= moderator.addJson("FanMax", getHeaterInfo().getFan_Max(), root ); bSend |= moderator.addJson("FanMax", getHeaterInfo().getFan_Max(), root );
bSend |= moderator.addJson("FanVoltage", HeaterManager.getFanVoltage(), root, 2500 );
bSend |= moderator.addJson("FanSensor", getHeaterInfo().getFan_Sensor(), root );
bSend |= moderator.addJson("SystemVoltage", getHeaterInfo().getSystemVoltage(), root );
bSend |= moderator.addJson("GlowVoltage", getGlowVolts(), root, 5000 );
bSend |= moderator.addJson("GlowCurrent", getGlowCurrent(), root, 5000 );
}
else {
bSend |= moderator.addJson("GlowCurrent", HeaterManager.getGlowPlugPower(), root, 5000 );
}
// bSend |= moderator.addJson("PumpActual", getHeaterInfo().getPump_Actual(), root );
bSend |= moderator.addJson("PumpActual", HeaterManager.getPumpRate(), root );
bSend |= moderator.addJson("FanRPM", getFanSpeed(), root, 2000 ); bSend |= moderator.addJson("FanRPM", getFanSpeed(), root, 2000 );
bSend |= moderator.addJson("FanVoltage", getHeaterInfo().getFan_Voltage(), root, 2500 ); // bSend |= moderator.addJson("FanVoltage", getHeaterInfo().getFan_Voltage(), root, 2500 );
bSend |= moderator.addJson("FanSensor", getHeaterInfo().getFan_Sensor(), root );
bSend |= moderator.addJson("InputVoltage", getBatteryVoltage(false), root, 10000 ); bSend |= moderator.addJson("InputVoltage", getBatteryVoltage(false), root, 10000 );
bSend |= moderator.addJson("SystemVoltage", getHeaterInfo().getSystemVoltage(), root );
bSend |= moderator.addJson("GlowVoltage", getGlowVolts(), root, 5000 );
bSend |= moderator.addJson("GlowCurrent", getGlowCurrent(), root, 5000 );
bSend |= moderator.addJson("BluewireStat", getBlueWireStatStr(), root ); bSend |= moderator.addJson("BluewireStat", getBlueWireStatStr(), root );
} }
@ -251,6 +266,7 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len)
humidity = int(humidity * 10 + 0.5) * 0.1f; // round to 0.1 resolution humidity = int(humidity * 10 + 0.5) * 0.1f; // round to 0.1 resolution
bSend |= moderator.addJson("Humidity", humidity, root, 30000); // BME280 ONLY bSend |= moderator.addJson("Humidity", humidity, root, 30000); // BME280 ONLY
} }
bSend |= moderator.addJson("SystemECUType", HeaterManager.getHeaterStyle(), root); // system ECU tyoe
if(bSend) { if(bSend) {
root.printTo(opStr, len); root.printTo(opStr, len);

View file

@ -34,6 +34,7 @@
#include "helpers.h" #include "helpers.h"
#include "../RTC/RTCStore.h" #include "../RTC/RTCStore.h"
#include "../Protocol/Protocol.h" #include "../Protocol/Protocol.h"
#include "../Protocol/HeaterManager.h"
// Concept of timer operation: // Concept of timer operation:
// //
@ -56,26 +57,32 @@
// The programmed timer temperature is not altered by the user adjusting the running // The programmed timer temperature is not altered by the user adjusting the running
// setting and the same setpoint will recur in the future when that timer runs again. // setting and the same setpoint will recur in the future when that timer runs again.
uint8_t CDemandManager::_setDegC = 22; int8_t CDemandManager::_setDegC = 22;
uint8_t CDemandManager::_setPumpHz = 22; int8_t CDemandManager::_setPumpHz = 22;
uint8_t int8_t
CDemandManager::getDegC() CDemandManager::getDegC()
{ {
return _setDegC; return _setDegC;
} }
uint8_t int8_t
CDemandManager::getPumpHz() CDemandManager::getPumpHz()
{ {
return _setPumpHz; // value lies in the typical range of 8-35 - interpolated by heater to real Hz if(HeaterManager.getHeaterStyle() == 0) {
return _setPumpHz; // value lies in the typical range of 8-35 - interpolated by heater to real Hz
}
else {
BOUNDSLIMIT(_setPumpHz, 0, 5);
return _setPumpHz;
}
} }
// set a new temperature setpoint, also saving it to non volatile RTC memory (battery backed RAM) // set a new temperature setpoint, also saving it to non volatile RTC memory (battery backed RAM)
void void
CDemandManager::setDegC(uint8_t newDegC) CDemandManager::setDegC(int8_t newDegC)
{ {
BOUNDSLIMIT(newDegC, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax); BOUNDSLIMIT(newDegC, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax);
@ -85,19 +92,24 @@ CDemandManager::setDegC(uint8_t newDegC)
// set a new pump setpoint, also saving it to non volatile RTC memory (battery backed RAM) // set a new pump setpoint, also saving it to non volatile RTC memory (battery backed RAM)
void void
CDemandManager::setPumpHz(uint8_t newDemand) CDemandManager::setPumpHz(int8_t newDemand)
{ {
// Pump demands use the same range as temperature demands :-) if(HeaterManager.getHeaterStyle() == 0) {
BOUNDSLIMIT(newDemand, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax); // Pump demands use the same range as temperature demands :-)
BOUNDSLIMIT(newDemand, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax);
}
else {
BOUNDSLIMIT(newDemand, 0, 5);
}
_setPumpHz = newDemand; _setPumpHz = newDemand;
RTC_Store.setDesiredPump(newDemand); RTC_Store.setDesiredPump(newDemand);
} }
// set a transient setpoint for use by prgrammed timer starts // set a transient setpoint for use by programmed timer starts
// setpoints only change if timer temperature is actually defined // setpoints only change if timer temperature is actually defined
void void
CDemandManager::setFromTimer(uint8_t timerDemand) CDemandManager::setFromTimer(int8_t timerDemand)
{ {
if(timerDemand) { if(timerDemand) {
_setPumpHz = timerDemand; _setPumpHz = timerDemand;
@ -154,20 +166,19 @@ CDemandManager::checkStart()
} }
// generic method adjust the active heter demand. // generic method adjust the active heater demand.
// thi may be Pump Hz or desired temeperature, dependent upon if thermostat mode is active // thi may be Pump Hz or desired temeperature, dependent upon if thermostat mode is active
bool bool
CDemandManager::setDemand(uint8_t newDemand) CDemandManager::setDemand(int8_t newDemand)
{ {
if(hasOEMcontroller()) if(hasOEMcontroller())
return false; return false;
// bounds operate over the same range for either mode
BOUNDSLIMIT(newDemand, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax);
// set and save the demand to NV storage // set and save the demand to NV storage
// note that we now maintain fixed Hz and Thermostat set points seperately // note that we now maintain fixed Hz and Thermostat set points seperately
if(isThermostat()) { if(isThermostat()) {
// bounds operate over the same range for either mode
BOUNDSLIMIT(newDemand, NVstore.getHeaterTuning().Tmin, NVstore.getHeaterTuning().Tmax);
setDegC(newDemand); setDegC(newDemand);
} }
else { else {
@ -183,7 +194,7 @@ CDemandManager::deltaDemand(int delta)
if(hasOEMcontroller()) if(hasOEMcontroller())
return false; return false;
uint8_t newDemand; int8_t newDemand;
if(isThermostat()) { if(isThermostat()) {
newDemand = getDegC() + delta; newDemand = getDegC() + delta;
setDegC(newDemand); setDegC(newDemand);
@ -239,7 +250,7 @@ CDemandManager::isThermostat()
} }
// generic get demand for Pump Hz or degC, as would be used in the value sent to the heater // generic get demand for Pump Hz or degC, as would be used in the value sent to the heater
uint8_t int8_t
CDemandManager::getDemand() CDemandManager::getDemand()
{ {
if(hasOEMcontroller()) { if(hasOEMcontroller()) {

View file

@ -38,8 +38,8 @@ struct sTimer;
class CDemandManager { class CDemandManager {
private: private:
static uint8_t _setDegC; static int8_t _setDegC;
static uint8_t _setPumpHz; static int8_t _setPumpHz;
public: public:
enum eStartCode { eStartOK=0, enum eStartCode { eStartOK=0,
@ -48,14 +48,14 @@ public:
eStartLVC=-3, eStartLVC=-3,
eStartLowFuel=-4 eStartLowFuel=-4
}; };
static uint8_t getDegC(); // absolute degC value to use static int8_t getDegC(); // absolute degC value to use
static uint8_t getPumpHz(); // absolute Pump Hz value to use - scaled to fit temp range static int8_t getPumpHz(); // absolute Pump Hz value to use - scaled to fit temp range
static uint8_t getDemand(); // can be pump Hz or degC, depending upon thermostat mode static int8_t getDemand(); // can be pump Hz or degC, depending upon thermostat mode
static void setDegC(uint8_t newDegC); // set and save absolute degC value to use static void setDegC(int8_t newDegC); // set and save absolute degC value to use
static void setPumpHz(uint8_t newDemand); // set and save absolute scaled pump Hz value to use static void setPumpHz(int8_t newDemand); // set and save absolute scaled pump Hz value to use
static bool setDemand(uint8_t newDemand); // set and save demand, according to thermostat mode static bool setDemand(int8_t newDemand); // set and save demand, according to thermostat mode
static bool deltaDemand(int delta); // nudge demand static bool deltaDemand(int delta); // nudge demand
static void setFromTimer(uint8_t newDemand); // set voltile degC and PumpHz, for timer starts static void setFromTimer(int8_t newDemand); // set voltile degC and PumpHz, for timer starts
static void reload(); // reload stored RTC values static void reload(); // reload stored RTC values
static eStartCode checkStart(); // test if start allowed static eStartCode checkStart(); // test if start allowed
static bool toggleThermostat(); static bool toggleThermostat();

View file

@ -24,6 +24,7 @@
#include "DebugPort.h" #include "DebugPort.h"
#include <driver/adc.h> #include <driver/adc.h>
#include <string.h> #include <string.h>
#include "../Protocol/433MHz.h"
bool bool
sNVStore::valid() sNVStore::valid()
@ -57,8 +58,28 @@ sNVStore::init()
CHeaterStorage::CHeaterStorage() CHeaterStorage::CHeaterStorage()
{ {
_calValues.init(); _calValues.init();
_semaphore = xSemaphoreCreateBinary();
giveSemaphore();
} }
CHeaterStorage::~CHeaterStorage()
{
vSemaphoreDelete(_semaphore);
}
void
CHeaterStorage::takeSemaphore()
{
xSemaphoreTake(_semaphore, portMAX_DELAY);
}
void
CHeaterStorage::giveSemaphore()
{
xSemaphoreGive(_semaphore);
}
float float
sHeaterTuning::getPmin() const sHeaterTuning::getPmin() const
{ {
@ -211,7 +232,7 @@ CHeaterStorage::setHourMeter(const sHourMeter& newVals)
// //
//#ifdef ESP32 //#ifdef ESP32
CESP32HeaterStorage::CESP32HeaterStorage() CESP32HeaterStorage::CESP32HeaterStorage() : CHeaterStorage()
{ {
init(); init();
} }
@ -245,6 +266,9 @@ void
CESP32HeaterStorage::doSave() CESP32HeaterStorage::doSave()
{ {
if(_bShouldSave) { if(_bShouldSave) {
takeSemaphore();
UHFremote.enableISR(false);
// portENTER_CRITICAL();
_bShouldSave = false; _bShouldSave = false;
DebugPort.println("Saving to NV storage"); DebugPort.println("Saving to NV storage");
_calValues.heaterTuning.save(); _calValues.heaterTuning.save();
@ -255,6 +279,9 @@ CESP32HeaterStorage::doSave()
_calValues.MQTT.save(); _calValues.MQTT.save();
_calValues.Credentials.save(); _calValues.Credentials.save();
_calValues.hourMeter.save(); _calValues.hourMeter.save();
// portEXIT_CRITICAL();
UHFremote.enableISR(true);
giveSemaphore();
} }
} }
@ -295,6 +322,7 @@ sHeaterTuning::load()
validatedLoad("probeSerial2", DS18B20probe[2].romCode.bytes, 8); validatedLoad("probeSerial2", DS18B20probe[2].romCode.bytes, 8);
validatedLoad("tempOffsetBME", BME280probe.offset, 0.0, -10.0, +10.0); validatedLoad("tempOffsetBME", BME280probe.offset, 0.0, -10.0, +10.0);
validatedLoad("probeBMEPrmy", BME280probe.bPrimary, 0, u8inBounds, 0, 1); validatedLoad("probeBMEPrmy", BME280probe.bPrimary, 0, u8inBounds, 0, 1);
validatedLoad("heaterStyle", heaterStyle, 0, u8inBounds, 0, 1);
preferences.end(); preferences.end();
// save(); // save();
@ -362,6 +390,7 @@ sHeaterTuning::save()
// preferences.putFloat("tempOffsetBME", BME280probe.offset); // preferences.putFloat("tempOffsetBME", BME280probe.offset);
saveFloat("tempOffsetBME", BME280probe.offset); saveFloat("tempOffsetBME", BME280probe.offset);
preferences.putUChar("probeBMEPrmy", BME280probe.bPrimary); preferences.putUChar("probeBMEPrmy", BME280probe.bPrimary);
preferences.putUChar("heaterStyle", heaterStyle);
/*// START TESTO /*// START TESTO
@ -514,6 +543,9 @@ sUserSettings::load()
validatedLoad("Clock12hr", clock12hr, 0, u8inBounds, 0, 1); validatedLoad("Clock12hr", clock12hr, 0, u8inBounds, 0, 1);
validatedLoad("holdPassword", holdPassword, 0, u8inBounds, 0, 1); validatedLoad("holdPassword", holdPassword, 0, u8inBounds, 0, 1);
validatedLoad("humidityStart", humidityStart, 0, u8inBounds, 0, 100); validatedLoad("humidityStart", humidityStart, 0, u8inBounds, 0, 100);
validatedLoad("UHFcode0", UHFcode[0], 0, 0, 0xffffffff);
validatedLoad("UHFcode1", UHFcode[1], 0, 0, 0xffffffff);
validatedLoad("UHFcode2", UHFcode[2], 0, 0, 0xffffffff);
preferences.end(); preferences.end();
} }
@ -554,6 +586,9 @@ sUserSettings::save()
preferences.putUChar("Clock12hr", clock12hr); preferences.putUChar("Clock12hr", clock12hr);
preferences.putUChar("holdPassword", holdPassword); preferences.putUChar("holdPassword", holdPassword);
preferences.putUChar("humidityStart", humidityStart); preferences.putUChar("humidityStart", humidityStart);
preferences.putULong("UHFcode0", UHFcode[0]);
preferences.putULong("UHFcode1", UHFcode[1]);
preferences.putULong("UHFcode2", UHFcode[2]);
preferences.end(); preferences.end();
} }

View file

@ -58,6 +58,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
uint16_t warnFuelUsage; uint16_t warnFuelUsage;
sDS18B20ProbeTuning DS18B20probe[3]; // [0],[1],[2] - Primary, Secondary, Tertiary sDS18B20ProbeTuning DS18B20probe[3]; // [0],[1],[2] - Primary, Secondary, Tertiary
sBM280tuning BME280probe; sBM280tuning BME280probe;
uint8_t heaterStyle;
bool valid() { bool valid() {
bool retval = true; bool retval = true;
@ -122,6 +123,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
memcpy(DS18B20probe[2].romCode.bytes, rhs.DS18B20probe[2].romCode.bytes, 8); memcpy(DS18B20probe[2].romCode.bytes, rhs.DS18B20probe[2].romCode.bytes, 8);
BME280probe.offset = rhs.BME280probe.offset; BME280probe.offset = rhs.BME280probe.offset;
BME280probe.bPrimary = rhs.BME280probe.bPrimary; BME280probe.bPrimary = rhs.BME280probe.bPrimary;
heaterStyle = rhs.heaterStyle;
return *this; return *this;
} }
float getPmin() const; float getPmin() const;
@ -326,6 +328,7 @@ struct sUserSettings : public CESP32_NVStorage {
uint8_t clock12hr; uint8_t clock12hr;
uint8_t holdPassword; uint8_t holdPassword;
uint8_t humidityStart; uint8_t humidityStart;
uint32_t UHFcode[3];
bool valid() { bool valid() {
bool retval = true; bool retval = true;
@ -347,7 +350,7 @@ struct sUserSettings : public CESP32_NVStorage {
retval &= HomeMenu.valid(); retval &= HomeMenu.valid();
retval &= JSON.valid(); retval &= JSON.valid();
return retval; return retval;
} };
void init() { void init() {
dimTime = 60000; dimTime = 60000;
menuTimeout = 60000; menuTimeout = 60000;
@ -375,6 +378,9 @@ struct sUserSettings : public CESP32_NVStorage {
clock12hr = 0; clock12hr = 0;
holdPassword = 0; holdPassword = 0;
humidityStart = 0; humidityStart = 0;
UHFcode[0] = 0;
UHFcode[1] = 0;
UHFcode[2] = 0;
}; };
void load(); void load();
void save(); void save();
@ -390,13 +396,7 @@ struct sUserSettings : public CESP32_NVStorage {
useThermostat = rhs.useThermostat; useThermostat = rhs.useThermostat;
wifiMode = rhs.wifiMode; wifiMode = rhs.wifiMode;
enableOTA = rhs.enableOTA; enableOTA = rhs.enableOTA;
GPIO.in1Mode = rhs.GPIO.in1Mode; GPIO = rhs.GPIO;
GPIO.in2Mode = rhs.GPIO.in2Mode;
GPIO.out1Mode = rhs.GPIO.out1Mode;
GPIO.out2Mode = rhs.GPIO.out2Mode;
GPIO.algMode = rhs.GPIO.algMode;
GPIO.thresh[0] = rhs.GPIO.thresh[0];
GPIO.thresh[1] = rhs.GPIO.thresh[1];
FrameRate = rhs.FrameRate; FrameRate = rhs.FrameRate;
cyclic = rhs.cyclic; cyclic = rhs.cyclic;
HomeMenu = rhs.HomeMenu; HomeMenu = rhs.HomeMenu;
@ -405,6 +405,9 @@ struct sUserSettings : public CESP32_NVStorage {
clock12hr = rhs.clock12hr; clock12hr = rhs.clock12hr;
holdPassword = rhs.holdPassword; holdPassword = rhs.holdPassword;
humidityStart = rhs.humidityStart; humidityStart = rhs.humidityStart;
UHFcode[0] = rhs.UHFcode[0];
UHFcode[1] = rhs.UHFcode[1];
UHFcode[2] = rhs.UHFcode[2];
return *this; return *this;
} }
}; };
@ -433,11 +436,12 @@ struct sNVStore {
class CHeaterStorage /*: public CESP32_NVStorage*/ { class CHeaterStorage /*: public CESP32_NVStorage*/ {
SemaphoreHandle_t _semaphore;
protected: protected:
sNVStore _calValues; sNVStore _calValues;
public: public:
CHeaterStorage(); CHeaterStorage();
virtual ~CHeaterStorage() {}; virtual ~CHeaterStorage();
// TODO: These are only here to allow building without fully // TODO: These are only here to allow building without fully
// fleshing out NV storage for Due, Mega etc // fleshing out NV storage for Due, Mega etc
@ -465,6 +469,8 @@ public:
void setUserSettings(const sUserSettings& info); void setUserSettings(const sUserSettings& info);
void setHeaterTuning(const sHeaterTuning& info); void setHeaterTuning(const sHeaterTuning& info);
bool setHourMeter(const sHourMeter& info); bool setHourMeter(const sHourMeter& info);
void takeSemaphore();
void giveSemaphore();
}; };

View file

@ -423,14 +423,14 @@ CBME280Sensor::getTemperature(float& tempReading, bool filtered)
return false; return false;
} }
long tDelta = millis() - _lastSampleTime; /* long tDelta = millis() - _lastSampleTime;
if(tDelta >= 0) { if(tDelta >= 0) {
_bme.takeForcedMeasurement(); _bme.takeForcedMeasurement();
float temperature = _bme.readTemperature(); float temperature = _bme.readTemperature();
update(temperature); update(temperature);
_lastSampleTime = millis() + 1000; _lastSampleTime = millis() + 1000;
DebugPort.println("Forced BME sensor reading"); DebugPort.println("Forced BME sensor reading");
} }*/
CSensor::getTemperature(tempReading, filtered); CSensor::getTemperature(tempReading, filtered);
// tempReading += NVstore.getHeaterTuning().BME280probe.offset;; // tempReading += NVstore.getHeaterTuning().BME280probe.offset;;
@ -461,11 +461,19 @@ CBME280Sensor::getHumidity(float& reading, bool fresh)
int int
CBME280Sensor::getAllReadings(bme280_readings& readings) CBME280Sensor::getAllReadings(bme280_readings& readings)
{ {
_bme.takeForcedMeasurement();
int retval = _bme.readAll(readings); int retval = _bme.readAll(readings);
_fAltitude = readings.altitude; _fAltitude = readings.altitude;
_fHumidity = readings.humidity; _fHumidity = readings.humidity;
update(readings.temperature); update(readings.temperature);
/* _bme.takeForcedMeasurement();
readings.temperature = _bme.readTemperature();
update(readings.temperature);
_fAltitude = readings.altitude = _bme.readAltitude(1013.25);
_fHumidity =readings.humidity = _bme.readHumidity();
int retval = 0x07; // temperature read OK*/
_lastSampleTime = millis() + 1000; _lastSampleTime = millis() + 1000;
return retval; return retval;

View file

@ -35,7 +35,8 @@
#include "../Utility/DebugPort.h" #include "../Utility/DebugPort.h"
#include "../Utility/NVStorage.h" #include "../Utility/NVStorage.h"
#include "../Utility/Moderator.h" #include "../Utility/Moderator.h"
#include "../Protocol/Protocol.h" // #include "../Protocol/Protocol.h"
#include "../Protocol/HeaterManager.h"
#include "../Utility/BTC_JSON.h" #include "../Utility/BTC_JSON.h"
#include "../Utility/TempSense.h" #include "../Utility/TempSense.h"
#include "../Utility/DemandManager.h" #include "../Utility/DemandManager.h"
@ -305,9 +306,12 @@ void pubTopic(const char* name, const char* payload)
void updateMQTT() void updateMQTT()
{ {
pubTopic("RunState", getHeaterInfo().getRunStateEx()); pubTopic("RunState", HeaterManager.getRunStateEx());
pubTopic("Run", getHeaterInfo().getRunStateEx() ? "1" : "0"); pubTopic("Run", HeaterManager.getRunStateEx() ? "1" : "0");
pubTopic("RunString", getHeaterInfo().getRunStateStr()); pubTopic("RunString", HeaterManager.getRunStateStr());
// pubTopic("RunState", getHeaterInfo().getRunStateEx());
// pubTopic("Run", getHeaterInfo().getRunStateEx() ? "1" : "0");
// pubTopic("RunString", getHeaterInfo().getRunStateStr());
float tidyTemp; float tidyTemp;
if(getTempSensor().getTemperature(0, tidyTemp)) { if(getTempSensor().getTemperature(0, tidyTemp)) {
@ -341,12 +345,17 @@ void updateMQTT()
} }
} }
pubTopic("TempDesired", CDemandManager::getDemand()); pubTopic("TempDesired", CDemandManager::getDemand());
pubTopic("TempBody", getHeaterInfo().getTemperature_HeatExchg()); pubTopic("TempBody", HeaterManager.getBodyTemp());
pubTopic("ErrorState", getHeaterInfo().getErrState()); pubTopic("ErrorState", HeaterManager.getErrState());
pubTopic("ErrorString", getHeaterInfo().getErrStateStrEx()); // verbose it up! pubTopic("ErrorString", HeaterManager.getErrStateStrEx()); // verbose it up!
// pubTopic("TempBody", getHeaterInfo().getTemperature_HeatExchg());
// pubTopic("ErrorState", getHeaterInfo().getErrState());
// pubTopic("ErrorString", getHeaterInfo().getErrStateStrEx()); // verbose it up!
pubTopic("Thermostat", CDemandManager::isThermostat()); pubTopic("Thermostat", CDemandManager::isThermostat());
pubTopic("PumpFixed", getHeaterInfo().getPump_Fixed() ); pubTopic("PumpFixed", HeaterManager.getPumpDemand() );
pubTopic("PumpActual", getHeaterInfo().getPump_Actual()); pubTopic("PumpActual", HeaterManager.getPumpRate());
// pubTopic("PumpFixed", getHeaterInfo().getPump_Fixed() );
// pubTopic("PumpActual", getHeaterInfo().getPump_Actual());
pubTopic("FanRPM", getFanSpeed()); pubTopic("FanRPM", getFanSpeed());
pubTopic("InputVoltage", getBatteryVoltage(false)); pubTopic("InputVoltage", getBatteryVoltage(false));
pubTopic("GlowVoltage", getGlowVolts()); pubTopic("GlowVoltage", getGlowVolts());
@ -356,9 +365,11 @@ void updateMQTT()
getGPIOinfo(info); getGPIOinfo(info);
pubTopic("GPanlg", info.algVal * 100 / 4096); pubTopic("GPanlg", info.algVal * 100 / 4096);
} }
pubTopic("FuelUsage", FuelGauge.Used_mL()); if(HeaterManager.getHeaterStyle() == 0) {
float fuelRate = getHeaterInfo().getPump_Actual() * NVstore.getHeaterTuning().pumpCal * 60 * 60; pubTopic("FuelUsage", FuelGauge.Used_mL());
pubTopic("FuelRate", fuelRate); float fuelRate = HeaterManager.getPumpRate() * NVstore.getHeaterTuning().pumpCal * 60 * 60;
pubTopic("FuelRate", fuelRate);
}
} }

View file

@ -24,37 +24,37 @@
#include "BTCConfig.h" #include "BTCConfig.h"
const uint8_t UART_Tx = 1; const gpio_num_t UART_Tx = GPIO_NUM_1;
const uint8_t LED_Pin = 2; const gpio_num_t LED_Pin = GPIO_NUM_2;
const uint8_t UART_Rx = 3; const gpio_num_t UART_Rx = GPIO_NUM_3;
const uint8_t HC05_KeyPin = 4; const gpio_num_t HC05_KeyPin = GPIO_NUM_4;
const uint8_t TxEnbPin = 5; const gpio_num_t TxEnbPin = GPIO_NUM_5;
const uint8_t Tx433MHz_pin = 12; // HSPI std pins const gpio_num_t Tx433MHz_pin = GPIO_NUM_12; // HSPI std pins
const uint8_t Rx433MHz_pin = 13; // " const gpio_num_t Rx433MHz_pin = GPIO_NUM_13; // "
const uint8_t GPIOout2_pin = 14; // " const gpio_num_t GPIOout2_pin = GPIO_NUM_14; // "
#if USE_JTAG == 1 #if USE_JTAG == 1
const uint8_t DS18B20_Pin = 33; const gpio_num_t DS18B20_Pin = GPIO_NUM_33;
#else #else
const uint8_t DS18B20_Pin = 15; const gpio_num_t DS18B20_Pin = GPIO_NUM_15;
#endif #endif
const uint8_t Rx1Pin = 16; const gpio_num_t Rx1Pin = GPIO_NUM_16;
const uint8_t Tx1Pin = 17; const gpio_num_t Tx1Pin = GPIO_NUM_17;
const uint8_t Tx2Pin = 18; const gpio_num_t Tx2Pin = GPIO_NUM_18;
const uint8_t Rx2Pin = 19; const gpio_num_t Rx2Pin = GPIO_NUM_19;
const uint8_t OLED_SDA_pin = 21; // I2C std pins const gpio_num_t OLED_SDA_pin = GPIO_NUM_21; // I2C std pins
const uint8_t OLED_SCL_pin = 22; // " const gpio_num_t OLED_SCL_pin = GPIO_NUM_22; // "
const uint8_t HC05_SensePin = 23; const gpio_num_t HC05_SensePin = GPIO_NUM_23;
const uint8_t GPIOin2_pin = 25; const gpio_num_t GPIOin2_pin = GPIO_NUM_25;
const uint8_t GPIOin1_pinV21V10 = 26; const gpio_num_t GPIOin1_pinV21V10 = GPIO_NUM_26;
const adc2_channel_t GPIOalg_pinINVALID = ADC2_CHANNEL_9; // GPIO 26 - Cannot use ADC2 with WiFi enabled!!! const adc2_channel_t GPIOalg_pinINVALID = ADC2_CHANNEL_9; // GPIO 26 - Cannot use ADC2 with WiFi enabled!!!
const uint8_t GPIOout1_pin = 27; const uint8_t GPIOout1_pin = GPIO_NUM_27;
const uint8_t keyUp_pin = 32; const gpio_num_t keyUp_pin = GPIO_NUM_32;
const uint8_t GPIOin1_pinV20 = 33; const gpio_num_t GPIOin1_pinV20 = GPIO_NUM_33;
const adc1_channel_t GPIOalg_pin = ADC1_CHANNEL_5; // GPIO 33 - OK with Wifi, ADC1 channel const adc1_channel_t GPIOalg_pin = ADC1_CHANNEL_5; // GPIO 33 - OK with Wifi, ADC1 channel
const uint8_t keyDown_pin = 34; // input only, no chip pullup const gpio_num_t keyDown_pin = GPIO_NUM_34; // input only, no chip pullup
const uint8_t keyCentre_pin = 35; // input only, no chip pullup const gpio_num_t keyCentre_pin = GPIO_NUM_35; // input only, no chip pullup
const uint8_t keyRight_pin = 36; // input only, no chip pullup const gpio_num_t keyRight_pin = GPIO_NUM_36; // input only, no chip pullup
const uint8_t keyLeft_pin = 39; // input only, no chip pullup const gpio_num_t keyLeft_pin = GPIO_NUM_39; // input only, no chip pullup