Added support for injecting Fixed Hz demands if a timer start has a defined temperature.
Uses normal range for fixed Hz.
This commit is contained in:
parent
4625f98cf3
commit
9839571893
|
@ -128,8 +128,8 @@
|
||||||
|
|
||||||
const int FirmwareRevision = 32;
|
const int FirmwareRevision = 32;
|
||||||
const int FirmwareSubRevision = 0;
|
const int FirmwareSubRevision = 0;
|
||||||
const int FirmwareMinorRevision = 3;
|
const int FirmwareMinorRevision = 4;
|
||||||
const char* FirmwareDate = "9 Apr 2020";
|
const char* FirmwareDate = "11 Apr 2020";
|
||||||
|
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
|
@ -155,7 +155,7 @@ void checkDebugCommands();
|
||||||
void manageCyclicMode();
|
void manageCyclicMode();
|
||||||
void manageFrostMode();
|
void manageFrostMode();
|
||||||
void manageHumidity();
|
void manageHumidity();
|
||||||
bool preemptCyclicMode();
|
int checkStartTemp();
|
||||||
void doStreaming();
|
void doStreaming();
|
||||||
void heaterOn();
|
void heaterOn();
|
||||||
void heaterOff();
|
void heaterOff();
|
||||||
|
@ -512,8 +512,6 @@ void setup() {
|
||||||
|
|
||||||
RTC_Store.begin();
|
RTC_Store.begin();
|
||||||
FuelGauge.init(RTC_Store.getFuelGauge());
|
FuelGauge.init(RTC_Store.getFuelGauge());
|
||||||
// demandDegC = RTC_Store.getDesiredTemp();
|
|
||||||
// demandPump = RTC_Store.getDesiredPump();
|
|
||||||
// bCyclicEngaged = RTC_Store.getCyclicEngaged();
|
// bCyclicEngaged = RTC_Store.getCyclicEngaged();
|
||||||
DebugPort.printf("Previous cyclic active = %d\r\n", RTC_Store.getCyclicEngaged()); // state flag required for cyclic mode to persist properly after a WD reboot :-)
|
DebugPort.printf("Previous cyclic active = %d\r\n", RTC_Store.getCyclicEngaged()); // state flag required for cyclic mode to persist properly after a WD reboot :-)
|
||||||
|
|
||||||
|
@ -521,7 +519,10 @@ void setup() {
|
||||||
pHourMeter->init(bESP32PowerUpInit || RTC_Store.getBootInit()); // ensure persistent memory variable are reset after powerup, or OTA update
|
pHourMeter->init(bESP32PowerUpInit || RTC_Store.getBootInit()); // ensure persistent memory variable are reset after powerup, or OTA update
|
||||||
RTC_Store.setBootInit(false);
|
RTC_Store.setBootInit(false);
|
||||||
|
|
||||||
reqDemand(RTC_Store.getDesiredTemp()); // bug fix: was not applying saved set point!
|
// bug fix: was not applying saved set points!
|
||||||
|
// reqDemand(RTC_Store.getDesiredTemp());
|
||||||
|
CTimerManager::setWorkingTemperature(RTC_Store.getDesiredTemp());
|
||||||
|
CTimerManager::setWorkingPumpHz(RTC_Store.getDesiredPump());
|
||||||
|
|
||||||
// Check for solo DS18B20
|
// Check for solo DS18B20
|
||||||
// store it's serial number as the primary sensor
|
// store it's serial number as the primary sensor
|
||||||
|
@ -1023,24 +1024,32 @@ void manageHumidity()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool preemptCyclicMode()
|
int checkStartTemp()
|
||||||
{
|
{
|
||||||
const sCyclicThermostat& cyclic = NVstore.getUserSettings().cyclic;
|
int stopDeltaT = 0;
|
||||||
if(cyclic.Stop) { // cyclic mode enabled, and user has started heater
|
int cyclicstop = NVstore.getUserSettings().cyclic.Stop;
|
||||||
int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over!
|
if(cyclicstop) { // cyclic mode enabled
|
||||||
float deltaT = getTemperatureSensor() - getDemandDegC();
|
stopDeltaT = cyclicstop + 1; // bump up by 1 degree - no point invoking at 1 deg over!
|
||||||
|
}
|
||||||
|
|
||||||
// check if over temp, skip straight to suspend
|
float deltaT = getTemperatureSensor() - getDemandDegC();
|
||||||
if(deltaT > stopDeltaT) {
|
|
||||||
|
if(deltaT > stopDeltaT) {
|
||||||
|
if(cyclicstop) {
|
||||||
DebugPort.printf("CYCLIC MODE: Skipping directly to suspend, deltaT > +%d\r\n", stopDeltaT);
|
DebugPort.printf("CYCLIC MODE: Skipping directly to suspend, deltaT > +%d\r\n", stopDeltaT);
|
||||||
heaterOff(); // over temp - request heater stop
|
heaterOff(); // over temp - request heater stop
|
||||||
return true;
|
return -2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// too warm - deny start
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void initBlueWireSerial()
|
void initBlueWireSerial()
|
||||||
{
|
{
|
||||||
// initialize serial port to interact with the "blue wire"
|
// initialize serial port to interact with the "blue wire"
|
||||||
|
@ -1071,6 +1080,12 @@ bool validateFrame(const CProtocol& frame, const char* name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return values:
|
||||||
|
// 0: OK
|
||||||
|
// -1: too warm
|
||||||
|
// -2: suspended
|
||||||
|
// -3: Low Voltage Cutout
|
||||||
|
// -4: Insufficent fuel
|
||||||
int requestOn(bool checkTemp)
|
int requestOn(bool checkTemp)
|
||||||
{
|
{
|
||||||
DebugPort.println("Start Request!");
|
DebugPort.println("Start Request!");
|
||||||
|
@ -1081,18 +1096,15 @@ int requestOn(bool checkTemp)
|
||||||
bool LVCOK = 2 != SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
|
bool LVCOK = 2 != SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
|
||||||
if(bHasHtrData && LVCOK) {
|
if(bHasHtrData && LVCOK) {
|
||||||
RTC_Store.setCyclicEngaged(true); // for cyclic mode
|
RTC_Store.setCyclicEngaged(true); // for cyclic mode
|
||||||
RTC_Store.setFrostOn(false); // cancel frost mode
|
RTC_Store.setFrostOn(false); // cancel frost mode
|
||||||
if(!preemptCyclicMode()) { // only start if below cyclic threshold when enabled
|
// only start if below appropriate temperature threshold, raised for cyclic mode
|
||||||
if(!checkTemp || getTemperatureSensor() < getDemandDegC()) { // skip start if warmer than desired
|
int denied = checkStartTemp();
|
||||||
heaterOn();
|
if(!checkTemp || !denied) {
|
||||||
return 0;
|
heaterOn();
|
||||||
}
|
return 0;
|
||||||
else {
|
|
||||||
return -1; // too warm
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -2; // immediate cyclic suspend
|
return denied;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1139,7 +1151,7 @@ bool reqDemand(uint8_t newDemand, bool save)
|
||||||
CTimerManager::setWorkingTemperature(newDemand);
|
CTimerManager::setWorkingTemperature(newDemand);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RTC_Store.setDesiredPump(newDemand);
|
CTimerManager::setWorkingPumpHz(newDemand);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenManager.reqUpdate();
|
ScreenManager.reqUpdate();
|
||||||
|
@ -1153,7 +1165,7 @@ bool reqDemandDelta(int delta)
|
||||||
newDemand = CTimerManager::getWorkingTemperature() + delta;
|
newDemand = CTimerManager::getWorkingTemperature() + delta;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newDemand = RTC_Store.getDesiredPump() + delta;
|
newDemand = CTimerManager::getWorkingPumpHz() + delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
return reqDemand(newDemand);
|
return reqDemand(newDemand);
|
||||||
|
@ -1268,7 +1280,7 @@ void setDemandDegC(uint8_t val)
|
||||||
|
|
||||||
uint8_t getDemandPump()
|
uint8_t getDemandPump()
|
||||||
{
|
{
|
||||||
return RTC_Store.getDesiredPump();
|
return CTimerManager::getWorkingPumpHz();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1278,10 +1290,12 @@ float getTemperatureDesired()
|
||||||
return getHeaterInfo().getHeaterDemand();
|
return getHeaterInfo().getHeaterDemand();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(getThermostatModeActive())
|
if(getThermostatModeActive()) {
|
||||||
return CTimerManager::getWorkingTemperature();
|
return CTimerManager::getWorkingTemperature();
|
||||||
else
|
}
|
||||||
return RTC_Store.getDesiredPump();
|
else {
|
||||||
|
return CTimerManager::getWorkingPumpHz(); // timer manager will return pump Hz, as demand value, not real Hz
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,19 @@
|
||||||
#include "../../lib/RTClib/RTClib.h"
|
#include "../../lib/RTClib/RTClib.h"
|
||||||
#include "../RTC/TimerManager.h"
|
#include "../RTC/TimerManager.h"
|
||||||
#include "fonts/Arial.h"
|
#include "fonts/Arial.h"
|
||||||
|
#include "../Utility/NVStorage.h"
|
||||||
|
|
||||||
const char* briefDOW[] = { "S", "M", "T", "W", "T", "F", "S" };
|
const char* briefDOW[] = { "S", "M", "T", "W", "T", "F", "S" };
|
||||||
|
|
||||||
|
float calcPumpHz(int desired) {
|
||||||
|
const sHeaterTuning& tuning = NVstore.getHeaterTuning();
|
||||||
|
|
||||||
|
float ratio = float(desired - tuning.Tmin) / float(tuning.Tmax - tuning.Tmin);
|
||||||
|
float offset = ratio * float(tuning.Pmax - tuning.Pmin);
|
||||||
|
float PumpHz = tuning.Pmin + offset;
|
||||||
|
return PumpHz / 10.f; // tuning is saved as Hz x10
|
||||||
|
}
|
||||||
|
|
||||||
CSetTimerScreen::CSetTimerScreen(C128x64_OLED& display, CScreenManager& mgr, int instance) : CUIEditScreen(display, mgr)
|
CSetTimerScreen::CSetTimerScreen(C128x64_OLED& display, CScreenManager& mgr, int instance) : CUIEditScreen(display, mgr)
|
||||||
{
|
{
|
||||||
_initUI();
|
_initUI();
|
||||||
|
@ -83,7 +93,7 @@ CSetTimerScreen::show()
|
||||||
else {
|
else {
|
||||||
// start
|
// start
|
||||||
xPos = 18;
|
xPos = 18;
|
||||||
yPos = 16;
|
yPos = 15;
|
||||||
_printMenuText(xPos, yPos, "On", false, eRightJustify);
|
_printMenuText(xPos, yPos, "On", false, eRightJustify);
|
||||||
_printMenuText(xPos+17, yPos, ":");
|
_printMenuText(xPos+17, yPos, ":");
|
||||||
xPos += 6;
|
xPos += 6;
|
||||||
|
@ -95,7 +105,7 @@ CSetTimerScreen::show()
|
||||||
|
|
||||||
// stop
|
// stop
|
||||||
xPos = 82;
|
xPos = 82;
|
||||||
yPos = 16;
|
yPos = 15;
|
||||||
_printMenuText(xPos, yPos, "Off", false, eRightJustify);
|
_printMenuText(xPos, yPos, "Off", false, eRightJustify);
|
||||||
_printMenuText(xPos+17, yPos, ":");
|
_printMenuText(xPos+17, yPos, ":");
|
||||||
xPos += 6;
|
xPos += 6;
|
||||||
|
@ -105,6 +115,13 @@ CSetTimerScreen::show()
|
||||||
sprintf(str, "%02d", _timerInfo.stop.min);
|
sprintf(str, "%02d", _timerInfo.stop.min);
|
||||||
_printMenuText(xPos, yPos, str, _rowSel==1 && _colSel==3);
|
_printMenuText(xPos, yPos, str, _rowSel==1 && _colSel==3);
|
||||||
|
|
||||||
|
yPos = 39;
|
||||||
|
{
|
||||||
|
CTransientFont AF(_display, &arialItalic_7ptFontInfo);
|
||||||
|
sprintf(str, "( %.1fHz )", calcPumpHz(_timerInfo.temperature));
|
||||||
|
_printMenuText(_display.xCentre()+5, yPos, str, false, eLeftJustify);
|
||||||
|
}
|
||||||
|
|
||||||
// control
|
// control
|
||||||
const char* msg;
|
const char* msg;
|
||||||
_printEnabledTimers();
|
_printEnabledTimers();
|
||||||
|
@ -118,23 +135,23 @@ CSetTimerScreen::show()
|
||||||
_printMenuText(xPos, yPos, msg, _rowSel==1 && _colSel==5, eRightJustify);
|
_printMenuText(xPos, yPos, msg, _rowSel==1 && _colSel==5, eRightJustify);
|
||||||
|
|
||||||
xPos = 18;
|
xPos = 18;
|
||||||
yPos = 40;
|
yPos = 41;
|
||||||
float fTemp = _timerInfo.temperature;
|
float fTemp = _timerInfo.temperature;
|
||||||
if(fTemp == 0) {
|
if(fTemp == 0) {
|
||||||
strcpy(str, "Current set ");
|
strcpy(str, "Current set ");
|
||||||
|
strcat(str, NVstore.getUserSettings().degF ? "`F" : "`C");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(NVstore.getUserSettings().degF) {
|
if(NVstore.getUserSettings().degF) {
|
||||||
fTemp = fTemp * 9 / 5 + 32;
|
fTemp = fTemp * 9 / 5 + 32;
|
||||||
sprintf(str, "%.0f", fTemp);
|
sprintf(str, "%.0f`F", fTemp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf(str, "%.0f", fTemp);
|
sprintf(str, "%.0f`C", fTemp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool degF = NVstore.getUserSettings().degF;
|
_printMenuText(_display.xCentre(), yPos, str, _rowSel==1 && _colSel==6, eRightJustify);
|
||||||
strcat(str, degF ? "`F" : "`C");
|
|
||||||
_printMenuText(_display.xCentre(), yPos, str, _rowSel==1 && _colSel==6, eCentreJustify);
|
|
||||||
|
|
||||||
|
|
||||||
// navigation line
|
// navigation line
|
||||||
|
@ -427,4 +444,5 @@ CSetTimerScreen::_showConflict(const char* str)
|
||||||
_printInverted(_display.xCentre(), 39, str, true, eCentreJustify);
|
_printInverted(_display.xCentre(), 39, str, true, eCentreJustify);
|
||||||
_printInverted(_display.xCentre(), 28, "Conflicts", true, eCentreJustify);
|
_printInverted(_display.xCentre(), 28, "Conflicts", true, eCentreJustify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -36,6 +36,16 @@ extern const uint8_t PROGMEM arial_8ptBoldBitmaps [];
|
||||||
extern const FONT_INFO arial_8ptBoldFontInfo;
|
extern const FONT_INFO arial_8ptBoldFontInfo;
|
||||||
extern const FONT_CHAR_INFO PROGMEM arial_8ptBoldDescriptors[];
|
extern const FONT_CHAR_INFO PROGMEM arial_8ptBoldDescriptors[];
|
||||||
|
|
||||||
|
// Font data for Arial 7pt Italic
|
||||||
|
extern const uint8_t PROGMEM arialItalic_7ptBitmaps [];
|
||||||
|
extern const FONT_INFO arialItalic_7ptFontInfo;
|
||||||
|
extern const FONT_CHAR_INFO PROGMEM arialItalic_7ptDescriptors[];
|
||||||
|
|
||||||
|
// Font data for Arial 8pt Italic
|
||||||
|
extern const uint8_t PROGMEM arialItalic_8ptBitmaps [];
|
||||||
|
extern const FONT_INFO arialItalic_8ptFontInfo;
|
||||||
|
extern const FONT_CHAR_INFO PROGMEM arialItalic_8ptDescriptors[];
|
||||||
|
|
||||||
// Font data for Arial 12pt
|
// Font data for Arial 12pt
|
||||||
extern const uint8_t PROGMEM arial_12ptBitmaps [];
|
extern const uint8_t PROGMEM arial_12ptBitmaps [];
|
||||||
extern const FONT_INFO arial_12ptFontInfo;
|
extern const FONT_INFO arial_12ptFontInfo;
|
||||||
|
|
|
@ -57,25 +57,6 @@ int CTxManage::m_nTxGatePin = 0;
|
||||||
// Sadly digitalWrite falls into this category, so use a FreeRTOS queue
|
// Sadly digitalWrite falls into this category, so use a FreeRTOS queue
|
||||||
// to push the end event handling into a non ISRL task
|
// to push the end event handling into a non ISRL task
|
||||||
|
|
||||||
static QueueHandle_t txGate_queue = NULL;
|
|
||||||
static int lclTxGatePin = 0;
|
|
||||||
|
|
||||||
// static function used for the tx gate termination
|
|
||||||
static void IRAM_ATTR GateTerminateCallback()
|
|
||||||
{
|
|
||||||
uint32_t gpio_num = lclTxGatePin;
|
|
||||||
xQueueSendFromISR(txGate_queue, &gpio_num, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TxGateConclude(void* arg)
|
|
||||||
{
|
|
||||||
uint32_t io_num;
|
|
||||||
for(;;) {
|
|
||||||
if(xQueueReceive(txGate_queue, &io_num, portMAX_DELAY)) {
|
|
||||||
digitalWrite(io_num, LOW); // terminate Tx Gate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CTxManage::CTxManage(int TxGatePin, HardwareSerial& serial) :
|
CTxManage::CTxManage(int TxGatePin, HardwareSerial& serial) :
|
||||||
m_BlueWireSerial(serial),
|
m_BlueWireSerial(serial),
|
||||||
|
@ -87,39 +68,32 @@ CTxManage::CTxManage(int TxGatePin, HardwareSerial& serial) :
|
||||||
m_bTxPending = false;
|
m_bTxPending = false;
|
||||||
m_nStartTime = 0;
|
m_nStartTime = 0;
|
||||||
m_nTxGatePin = TxGatePin;
|
m_nTxGatePin = TxGatePin;
|
||||||
lclTxGatePin = TxGatePin;
|
|
||||||
_rawCommand = 0;
|
_rawCommand = 0;
|
||||||
m_HWTimer = NULL;
|
m_HWTimer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static function used for the tx gate termination
|
// static function used for the tx gate termination
|
||||||
void CTxManage::GateTerminate()
|
// must use IRAM_ATTR being a call back called at ISRL
|
||||||
|
void IRAM_ATTR
|
||||||
|
CTxManage::callbackGateTerminate()
|
||||||
{
|
{
|
||||||
uint32_t gpio_num = m_nTxGatePin;
|
digitalWrite(m_nTxGatePin, LOW); // cancel Tx Gate
|
||||||
xQueueSendFromISR(txGate_queue, &gpio_num, NULL);
|
|
||||||
// digitalWrite(m_nTxGatePin, LOW); // default to receive mode
|
|
||||||
m_nStartTime = 0; // cancel, we are DONE
|
m_nStartTime = 0; // cancel, we are DONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CTxManage::begin()
|
void
|
||||||
|
CTxManage::begin()
|
||||||
{
|
{
|
||||||
pinMode(m_nTxGatePin, OUTPUT);
|
pinMode(m_nTxGatePin, OUTPUT);
|
||||||
digitalWrite(m_nTxGatePin, LOW); // default to receive mode
|
digitalWrite(m_nTxGatePin, LOW); // default to receive mode
|
||||||
|
|
||||||
//create a queue to handle gpio event from isr
|
|
||||||
txGate_queue = xQueueCreate(10, sizeof(uint32_t));
|
|
||||||
//start gpio task
|
|
||||||
xTaskCreate(TxGateConclude, "Tx Gate Conclude", 2048, NULL, configMAX_PRIORITIES-2, NULL);
|
|
||||||
|
|
||||||
// use a hardware timer to terminate the Tx gate shortly after the completion of the 24 byte transmit packet
|
// use a hardware timer to terminate the Tx gate shortly after the completion of the 24 byte transmit packet
|
||||||
m_HWTimer = timerBegin(2, 80, true);
|
m_HWTimer = timerBegin(2, 80, true);
|
||||||
//set time in uS of Tx gate from when actual tx data bytes are loaded
|
//set time in uS of Tx gate from when actual tx data bytes are loaded
|
||||||
// 240 bits @ 25000bps is 9.6ms, we'll use 9.7ms for a bit of tolerance
|
// 240 bits @ 25000bps is 9.6ms, we'll use 9.7ms for a bit of tolerance
|
||||||
timerAlarmWrite(m_HWTimer, 10000-300, false);
|
timerAlarmWrite(m_HWTimer, 10000-300, false);
|
||||||
// timerAttachInterrupt(m_HWTimer, &GateTerminate, true);
|
timerAttachInterrupt(m_HWTimer, &callbackGateTerminate, true);
|
||||||
timerAttachInterrupt(m_HWTimer, &GateTerminateCallback, true);
|
|
||||||
|
|
||||||
timerAlarmDisable(m_HWTimer); //disable interrupt for now
|
timerAlarmDisable(m_HWTimer); //disable interrupt for now
|
||||||
timerSetAutoReload(m_HWTimer, false);
|
timerSetAutoReload(m_HWTimer, false);
|
||||||
}
|
}
|
||||||
|
@ -193,6 +167,8 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
|
||||||
m_TxFrame.setFan_Max(NVstore.getHeaterTuning().Fmax);
|
m_TxFrame.setFan_Max(NVstore.getHeaterTuning().Fmax);
|
||||||
m_TxFrame.setPump_Min(NVstore.getHeaterTuning().getPmin());
|
m_TxFrame.setPump_Min(NVstore.getHeaterTuning().getPmin());
|
||||||
m_TxFrame.setPump_Max(NVstore.getHeaterTuning().getPmax());
|
m_TxFrame.setPump_Max(NVstore.getHeaterTuning().getPmax());
|
||||||
|
m_TxFrame.setTemperature_Min(NVstore.getHeaterTuning().Tmin); // Minimum settable temperature
|
||||||
|
m_TxFrame.setTemperature_Max(NVstore.getHeaterTuning().Tmax); // Maximum settable temperature
|
||||||
|
|
||||||
float altitude;
|
float altitude;
|
||||||
if(getTempSensor().getAltitude(altitude)) { // if a BME280 is fitted
|
if(getTempSensor().getAltitude(altitude)) { // if a BME280 is fitted
|
||||||
|
@ -200,7 +176,6 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_TxFrame.setAltitude(3500); // default height - yes it is weird, but that's what the simple controllers send!
|
m_TxFrame.setAltitude(3500); // default height - yes it is weird, but that's what the simple controllers send!
|
||||||
// m_TxFrame.setAltitude(0); // default height - yes it is weird, but that's what the simple controllers send!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float tActual = getTemperatureSensor();
|
float tActual = getTemperatureSensor();
|
||||||
|
@ -335,7 +310,6 @@ CTxManage::CheckTx(unsigned long timenow)
|
||||||
// Tx gate remains held high
|
// Tx gate remains held high
|
||||||
// it is then brought low by the timer alarm callback, which also cancels m_nStartTime
|
// it is then brought low by the timer alarm callback, which also cancels m_nStartTime
|
||||||
m_bTxPending = false;
|
m_bTxPending = false;
|
||||||
m_nStartTime = 0;
|
|
||||||
m_BlueWireSerial.write(m_TxFrame.Data, 24); // write native binary values
|
m_BlueWireSerial.write(m_TxFrame.Data, 24); // write native binary values
|
||||||
timerWrite(m_HWTimer, 0); //reset tx gate timeout
|
timerWrite(m_HWTimer, 0); //reset tx gate timeout
|
||||||
timerAlarmEnable(m_HWTimer); // timeout will cause cessation of the Tx gate
|
timerAlarmEnable(m_HWTimer); // timeout will cause cessation of the Tx gate
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
bool CheckTx(unsigned long timenow);
|
bool CheckTx(unsigned long timenow);
|
||||||
void begin();
|
void begin();
|
||||||
const CProtocol& getFrame() const { return m_TxFrame; };
|
const CProtocol& getFrame() const { return m_TxFrame; };
|
||||||
static void GateTerminate();
|
static void IRAM_ATTR callbackGateTerminate();
|
||||||
void queueSysUpdate(); // use to implant NV settings into heater
|
void queueSysUpdate(); // use to implant NV settings into heater
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -45,6 +45,7 @@ int CTimerManager::_activeDow = 0;
|
||||||
int CTimerManager::_nextTimer = 0;
|
int CTimerManager::_nextTimer = 0;
|
||||||
int CTimerManager::_nextStart = 0;
|
int CTimerManager::_nextStart = 0;
|
||||||
uint8_t CTimerManager::_workingTemperature = 22;
|
uint8_t CTimerManager::_workingTemperature = 22;
|
||||||
|
uint8_t CTimerManager::_workingPumpHz = 22;
|
||||||
bool CTimerManager::_timerChanged = false;
|
bool CTimerManager::_timerChanged = false;
|
||||||
|
|
||||||
#define SET_MAPS() { \
|
#define SET_MAPS() { \
|
||||||
|
@ -270,8 +271,10 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
||||||
// get timer settings
|
// get timer settings
|
||||||
int ID = (newID & 0xf) - 1;
|
int ID = (newID & 0xf) - 1;
|
||||||
NVstore.getTimerInfo(ID, timer);
|
NVstore.getTimerInfo(ID, timer);
|
||||||
if(timer.temperature)
|
if (timer.temperature) {
|
||||||
_workingTemperature = timer.temperature;
|
_workingTemperature = timer.temperature;
|
||||||
|
_workingPumpHz = timer.temperature;
|
||||||
|
}
|
||||||
DebugPort.printf("Start of timer interval, starting heater @ %dC\r\n", _workingTemperature);
|
DebugPort.printf("Start of timer interval, starting heater @ %dC\r\n", _workingTemperature);
|
||||||
requestOn();
|
requestOn();
|
||||||
_activeDow = dow; // dow when timer interval start was detected
|
_activeDow = dow; // dow when timer interval start was detected
|
||||||
|
@ -283,6 +286,7 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
|
||||||
requestOff();
|
requestOff();
|
||||||
retval = 2;
|
retval = 2;
|
||||||
_workingTemperature = RTC_Store.getDesiredTemp();
|
_workingTemperature = RTC_Store.getDesiredTemp();
|
||||||
|
_workingPumpHz = RTC_Store.getDesiredPump();
|
||||||
DebugPort.printf("End of timer interval, stopping heater & %dC\r\n", _workingTemperature);
|
DebugPort.printf("End of timer interval, stopping heater & %dC\r\n", _workingTemperature);
|
||||||
}
|
}
|
||||||
_activeTimer = newID;
|
_activeTimer = newID;
|
||||||
|
@ -423,7 +427,7 @@ CTimerManager::createOneShotMap(sTimer& timer, uint16_t* pTimerMap, uint16_t* pT
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concept of timer working temperature is that when a timer runs, it installs
|
// Concept of timer working temperature is that when a timer runs, it installs
|
||||||
// the programmed temeprature for that timer as the new set point.
|
// the programmed temperature for that timer as the new set point.
|
||||||
// When the timer stops, it reverts to the usual user set temperature.
|
// When the timer stops, it reverts to the usual user set temperature.
|
||||||
//
|
//
|
||||||
// BUT, if a timer is running, the working temperature is updated with the new demand
|
// BUT, if a timer is running, the working temperature is updated with the new demand
|
||||||
|
@ -438,6 +442,33 @@ CTimerManager::getWorkingTemperature()
|
||||||
void
|
void
|
||||||
CTimerManager::setWorkingTemperature(uint8_t newDegC)
|
CTimerManager::setWorkingTemperature(uint8_t newDegC)
|
||||||
{
|
{
|
||||||
_workingTemperature = newDegC;
|
if(getThermostatModeActive()) {
|
||||||
RTC_Store.setDesiredTemp(newDegC);
|
_workingTemperature = newDegC;
|
||||||
|
RTC_Store.setDesiredTemp(newDegC);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_workingPumpHz = newDegC;
|
||||||
|
RTC_Store.setDesiredPump(newDegC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Concept of timer working pump Hz is that when a timer runs, it installs
|
||||||
|
// the programmed temperature for that timer as the new set point.
|
||||||
|
// That is then converted by the heater into Hz
|
||||||
|
// When the timer stops, it reverts to the usual user set temperature.
|
||||||
|
//
|
||||||
|
// BUT, if a timer is running, the working temperature is updated with the new demand
|
||||||
|
// and the user temperature is also changed accordingly.
|
||||||
|
// The programmed timer temeprature is not altered and wil lrecur in the future when that time runs.
|
||||||
|
uint8_t
|
||||||
|
CTimerManager::getWorkingPumpHz()
|
||||||
|
{
|
||||||
|
return _workingPumpHz;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CTimerManager::setWorkingPumpHz(uint8_t newDemand)
|
||||||
|
{
|
||||||
|
_workingPumpHz = newDemand;
|
||||||
|
RTC_Store.setDesiredPump(newDemand);
|
||||||
}
|
}
|
|
@ -53,9 +53,12 @@ public:
|
||||||
static int setTimer(sTimer& timerInfo);
|
static int setTimer(sTimer& timerInfo);
|
||||||
static bool hasTimerChanged() { return _timerChanged; };
|
static bool hasTimerChanged() { return _timerChanged; };
|
||||||
static uint8_t getWorkingTemperature();
|
static uint8_t getWorkingTemperature();
|
||||||
|
static uint8_t getWorkingPumpHz();
|
||||||
static void setWorkingTemperature(uint8_t newDegC);
|
static void setWorkingTemperature(uint8_t newDegC);
|
||||||
|
static void setWorkingPumpHz(uint8_t newDemand);
|
||||||
private:
|
private:
|
||||||
static uint8_t _workingTemperature;
|
static uint8_t _workingTemperature;
|
||||||
|
static uint8_t _workingPumpHz;
|
||||||
static int _activeTimer;
|
static int _activeTimer;
|
||||||
static int _activeDow;
|
static int _activeDow;
|
||||||
static int _prevState;
|
static int _prevState;
|
||||||
|
|
|
@ -43,6 +43,8 @@ struct sBM280tuning {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sHeaterTuning : public CESP32_NVStorage {
|
struct sHeaterTuning : public CESP32_NVStorage {
|
||||||
|
const uint8_t Tmin = 8;
|
||||||
|
const uint8_t Tmax = 35;
|
||||||
uint8_t Pmin;
|
uint8_t Pmin;
|
||||||
uint8_t Pmax;
|
uint8_t Pmax;
|
||||||
uint16_t Fmin;
|
uint16_t Fmin;
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "../Protocol/Protocol.h"
|
#include "../Protocol/Protocol.h"
|
||||||
#include "../Utility/BTC_JSON.h"
|
#include "../Utility/BTC_JSON.h"
|
||||||
#include "../Utility/TempSense.h"
|
#include "../Utility/TempSense.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
|
||||||
extern void DecodeCmd(const char* cmd, String& payload);
|
extern void DecodeCmd(const char* cmd, String& payload);
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ char statusTopic[128];
|
||||||
|
|
||||||
#ifdef USE_RTOS_MQTTTIMER
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
TimerHandle_t mqttReconnectTimer = NULL;
|
TimerHandle_t mqttReconnectTimer = NULL;
|
||||||
|
QueueHandle_t mqttQueue = NULL;
|
||||||
#else
|
#else
|
||||||
unsigned long mqttReconnect = 0;
|
unsigned long mqttReconnect = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -84,6 +86,16 @@ void connectToMqtt() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
// timer callbacks are called from ISRL
|
||||||
|
// this code MUST run from IRAM, and then safest to pass the event down thru a queue to user code
|
||||||
|
void IRAM_ATTR callbackMQTTreconnect() {
|
||||||
|
BaseType_t awoken;
|
||||||
|
int flag = 1;
|
||||||
|
xQueueSendFromISR(mqttQueue, &flag, &awoken);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void onMqttConnect(bool sessionPresent)
|
void onMqttConnect(bool sessionPresent)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTOS_MQTTTIMER
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
@ -192,7 +204,10 @@ bool mqttInit()
|
||||||
#ifdef USE_RTOS_MQTTTIMER
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
#ifndef BLOCK_MQTT_RECON
|
#ifndef BLOCK_MQTT_RECON
|
||||||
if(mqttReconnectTimer==NULL)
|
if(mqttReconnectTimer==NULL)
|
||||||
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(20000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
|
// mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(20000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
|
||||||
|
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(20000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(callbackMQTTreconnect));
|
||||||
|
if(mqttQueue == NULL)
|
||||||
|
mqttQueue = xQueueCreate(10, 4);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
mqttReconnect = 0;
|
mqttReconnect = 0;
|
||||||
|
@ -242,7 +257,7 @@ bool mqttInit()
|
||||||
MQTTclient.onSubscribe(onMqttSubscribe);
|
MQTTclient.onSubscribe(onMqttSubscribe);
|
||||||
setCallbacks = true;
|
setCallbacks = true;
|
||||||
}
|
}
|
||||||
// connection takes pplace via delayed start method
|
// connection takes place via delayed start method
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -260,7 +275,7 @@ bool mqttPublishJSON(const char* str)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kickMQTT() {
|
/*void kickMQTT() {
|
||||||
if (WiFi.isConnected()) {
|
if (WiFi.isConnected()) {
|
||||||
if(NVstore.getMQTTinfo().enabled) {
|
if(NVstore.getMQTTinfo().enabled) {
|
||||||
#ifdef USE_RTOS_MQTTTIMER
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
@ -270,7 +285,7 @@ void kickMQTT() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void doMQTT()
|
void doMQTT()
|
||||||
{
|
{
|
||||||
|
@ -280,13 +295,18 @@ void doMQTT()
|
||||||
if(tDelta > 0) {
|
if(tDelta > 0) {
|
||||||
MQTTrestart = 0;
|
MQTTrestart = 0;
|
||||||
mqttInit();
|
mqttInit();
|
||||||
// connectToMqtt();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// most MQTT is managed via callbacks!!!
|
// most MQTT is managed via callbacks!!!
|
||||||
if(NVstore.getMQTTinfo().enabled) {
|
if(NVstore.getMQTTinfo().enabled) {
|
||||||
#ifndef USE_RTOS_MQTTTIMER
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
|
int flag;
|
||||||
|
if(xQueueReceive(mqttQueue, &flag, 0)) {
|
||||||
|
DebugPort.println("MQTT connect request via queue");
|
||||||
|
connectToMqtt();
|
||||||
|
}
|
||||||
|
#else
|
||||||
if(mqttReconnect) {
|
if(mqttReconnect) {
|
||||||
long tDelta = millis() - mqttReconnect;
|
long tDelta = millis() - mqttReconnect;
|
||||||
if(tDelta > 0) {
|
if(tDelta > 0) {
|
||||||
|
@ -299,6 +319,7 @@ void doMQTT()
|
||||||
#ifdef USE_RTOS_MQTTTIMER
|
#ifdef USE_RTOS_MQTTTIMER
|
||||||
#ifndef BLOCK_MQTT_RECON
|
#ifndef BLOCK_MQTT_RECON
|
||||||
if (!MQTTclient.connected() && WiFi.isConnected() && !xTimerIsTimerActive(mqttReconnectTimer)) {
|
if (!MQTTclient.connected() && WiFi.isConnected() && !xTimerIsTimerActive(mqttReconnectTimer)) {
|
||||||
|
DebugPort.println("Starting MQTT timer");
|
||||||
xTimerStart(mqttReconnectTimer, 0);
|
xTimerStart(mqttReconnectTimer, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@ bool mqttInit();
|
||||||
void doMQTT();
|
void doMQTT();
|
||||||
bool mqttPublishJSON(const char* str);
|
bool mqttPublishJSON(const char* str);
|
||||||
void connectToMqtt();
|
void connectToMqtt();
|
||||||
void kickMQTT();
|
//void kickMQTT();
|
||||||
bool isMQTTconnected();
|
bool isMQTTconnected();
|
||||||
const char* getTopicPrefix();
|
const char* getTopicPrefix();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue