Added setting screen to select the thermostat mode and window size
This commit is contained in:
parent
2fc020ae6c
commit
d8c050b165
195
Arduino/BTCDieselHeater/src/OLED/ExperimentalSettingsScreen.cpp
Normal file
195
Arduino/BTCDieselHeater/src/OLED/ExperimentalSettingsScreen.cpp
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "128x64OLED.h"
|
||||
#include "ExperimentalSettingsScreen.h"
|
||||
#include "KeyPad.h"
|
||||
#include "../Protocol/helpers.h"
|
||||
#include "../Utility/UtilClasses.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CExperimentalSettingsScreen
|
||||
//
|
||||
// This screen provides control over experimental features
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const int Line3 = 14;
|
||||
static const int Line2 = 27;
|
||||
static const int Line1 = 40;
|
||||
static const int Column = 75;
|
||||
|
||||
static const int plugPowers[] = { 35, 40, 45, 80, 85, 90};
|
||||
|
||||
CExperimentalSettingsScreen::CExperimentalSettingsScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
|
||||
{
|
||||
_initUI();
|
||||
_window = 10;
|
||||
_thermoMode = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CExperimentalSettingsScreen::onSelect()
|
||||
{
|
||||
CPasswordScreen::onSelect();
|
||||
_initUI();
|
||||
_window = NVstore.getThermostatMethodWindow();
|
||||
_thermoMode = NVstore.getThermostatMethodMode();
|
||||
}
|
||||
|
||||
void
|
||||
CExperimentalSettingsScreen::_initUI()
|
||||
{
|
||||
_rowSel = 0;
|
||||
_animateCount = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
CExperimentalSettingsScreen::show()
|
||||
{
|
||||
char msg[20];
|
||||
_display.clearDisplay();
|
||||
|
||||
if(!CPasswordScreen::show()) { // for showing "saving settings"
|
||||
|
||||
if(_rowSel == 4) {
|
||||
_printInverted(_display.xCentre(), 0, " Saving Settings ", true, eCentreJustify);
|
||||
_printMenuText(_display.xCentre(), 35, "Press UP to", false, eCentreJustify);
|
||||
_printMenuText(_display.xCentre(), 43, "confirm save", false, eCentreJustify);
|
||||
}
|
||||
else {
|
||||
_printInverted(_display.xCentre(), 0, " Experimental ", true, eCentreJustify);
|
||||
_printMenuText(67, Line2, "Thermostat:", false, eRightJustify);
|
||||
_printMenuText(67, Line1, "Window:", false, eRightJustify);
|
||||
sprintf(msg, "%.1f", _window);
|
||||
_printMenuText(Column, Line1, msg, _rowSel == 1);
|
||||
switch(_thermoMode) {
|
||||
case 1:
|
||||
_printMenuText(Column, Line2, "Deadband", _rowSel == 2);
|
||||
break;
|
||||
case 2:
|
||||
_printMenuText(Column, Line2, "Linear Hz", _rowSel == 2);
|
||||
break;
|
||||
default:
|
||||
_printMenuText(Column, Line2, "Standard", _rowSel == 2);
|
||||
break;
|
||||
}
|
||||
// navigation line
|
||||
int yPos = 53;
|
||||
int xPos = _display.xCentre();
|
||||
_printMenuText(xPos, yPos, "exit", _rowSel == 0, eCentreJustify);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CExperimentalSettingsScreen::keyHandler(uint8_t event)
|
||||
{
|
||||
if(event & keyPressed) {
|
||||
// press LEFT to select previous screen
|
||||
if(event & key_Left) {
|
||||
switch(_rowSel) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
_adjust(-1);
|
||||
break;
|
||||
case 4:
|
||||
_rowSel = 0; // abort save
|
||||
break;
|
||||
}
|
||||
}
|
||||
// press RIGHT to select next screen
|
||||
if(event & key_Right) {
|
||||
switch(_rowSel) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
_adjust(+1);
|
||||
break;
|
||||
case 4:
|
||||
_rowSel = 0; // abort save
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(event & key_Down) {
|
||||
_rowSel--;
|
||||
LOWERLIMIT(_rowSel, 0);
|
||||
}
|
||||
// UP press
|
||||
if(event & key_Up) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
_rowSel++;
|
||||
UPPERLIMIT(_rowSel, 2);
|
||||
break;
|
||||
case 4: // confirmed save
|
||||
_showStoringMessage();
|
||||
NVstore.setThermostatMethodMode(_thermoMode);
|
||||
NVstore.setThermostatMethodWindow(_window);
|
||||
saveNV();
|
||||
_rowSel = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// CENTRE press
|
||||
if(event & key_Centre) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_ScreenManager.selectExperimentalScreen(false);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
_rowSel = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CExperimentalSettingsScreen::_adjust(int dir)
|
||||
{
|
||||
switch(_rowSel) {
|
||||
case 1: // window
|
||||
_window += (dir * 0.1);
|
||||
UPPERLIMIT(_window, 6.3);
|
||||
LOWERLIMIT(_window, 0.2);
|
||||
break;
|
||||
case 2: // thermostat mode
|
||||
_thermoMode += dir;
|
||||
ROLLLOWERLIMIT(_thermoMode, 0, 2);
|
||||
ROLLUPPERLIMIT(_thermoMode, 2, 0);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __EXPERIMENTALSETTINGSSCREEN_H__
|
||||
#define __EXPERIMENTALSETTINGSSCREEN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "PasswordScreen.h"
|
||||
|
||||
class C128x64_OLED;
|
||||
class CScreenManager;
|
||||
|
||||
class CExperimentalSettingsScreen : public CPasswordScreen
|
||||
{
|
||||
int _rowSel;
|
||||
void _adjust(int dir);
|
||||
float _window;
|
||||
int _thermoMode;
|
||||
int _animateCount;
|
||||
void _initUI();
|
||||
public:
|
||||
CExperimentalSettingsScreen(C128x64_OLED& display, CScreenManager& mgr);
|
||||
bool show();
|
||||
bool keyHandler(uint8_t event);
|
||||
void onSelect();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -10,6 +10,7 @@
|
|||
#include "RebootScreen.h"
|
||||
#include "HeaterSettingsScreen.h"
|
||||
#include "SettingsScreen.h"
|
||||
#include "ExperimentalSettingsScreen.h"
|
||||
#include "TimerChartScreen.h"
|
||||
#include "InheritSettingsScreen.h"
|
||||
#include <Wire.h>
|
||||
|
@ -105,6 +106,7 @@ CScreenManager::CScreenManager()
|
|||
_bReqUpdate = false;
|
||||
_bSetTimeScreenActive = false;
|
||||
_bInheritScreenActive = false;
|
||||
_bExperimentalScreenActive = false;
|
||||
_DimTime = millis() + 60000;
|
||||
_pRebootScreen = NULL;
|
||||
}
|
||||
|
@ -182,6 +184,7 @@ CScreenManager::begin(bool bNoClock)
|
|||
_TuningScreens.push_back(new CHeaterSettingsScreen(*_pDisplay, *this)); // tuning
|
||||
_SetTimeScreen = new CSetClockScreen(*_pDisplay, *this); // clock set
|
||||
_InheritScreen = new CInheritSettingsScreen(*_pDisplay, *this); // inherit OEM settings
|
||||
_ExperimentalScreen = new CExperimentalSettingsScreen(*_pDisplay, *this); // experimental settings
|
||||
|
||||
#if RTC_USE_DS3231==0 && RTC_USE_DS1307==0 && RTC_USE_PCF8523==0
|
||||
_rootMenuScreen = 6; // bring up clock set screen first if using millis based RTC!
|
||||
|
@ -209,6 +212,7 @@ CScreenManager::checkUpdate()
|
|||
selectSetTimeScreen(false);
|
||||
selectSettingsScreen(false);
|
||||
selectInheritScreen(false);
|
||||
selectExperimentalScreen(false);
|
||||
// sticky screens are Detailed Control, Basic Control, or Clock.
|
||||
// otherwise return to Basic Control screen
|
||||
if(_rootMenuScreen > 2) {
|
||||
|
@ -235,6 +239,11 @@ CScreenManager::checkUpdate()
|
|||
_bReqUpdate = false;
|
||||
return true;
|
||||
}
|
||||
else if(_bExperimentalScreenActive) {
|
||||
_ExperimentalScreen->show();
|
||||
_bReqUpdate = false;
|
||||
return true;
|
||||
}
|
||||
else if(_tuningScreen >= 0) {
|
||||
_TuningScreens[_tuningScreen]->show();
|
||||
_bReqUpdate = false;
|
||||
|
@ -267,6 +276,7 @@ CScreenManager::animate()
|
|||
if(_tuningScreen >= 0) return _TuningScreens[_tuningScreen]->animate();
|
||||
if(_bSetTimeScreenActive) return _SetTimeScreen->animate();
|
||||
if(_bInheritScreenActive) return _InheritScreen->animate();
|
||||
if(_bExperimentalScreenActive) return _ExperimentalScreen->animate();
|
||||
if(_timerScreen >= 0) return _TimerScreens[_timerScreen]->animate();
|
||||
if(_rootMenuScreen >= 0) return _RootScreens[_rootMenuScreen]->animate();
|
||||
return false;
|
||||
|
@ -284,6 +294,7 @@ CScreenManager::_enterScreen()
|
|||
{
|
||||
if(_bSetTimeScreenActive) _SetTimeScreen->onSelect();
|
||||
else if(_bInheritScreenActive) _InheritScreen->onSelect();
|
||||
else if(_bExperimentalScreenActive) _ExperimentalScreen->onSelect();
|
||||
else if(_timerScreen >= 0) _TimerScreens[_timerScreen]->onSelect();
|
||||
else if(_tuningScreen >= 0) _TuningScreens[_tuningScreen]->onSelect();
|
||||
else if(_rootMenuScreen >= 0) _RootScreens[_rootMenuScreen]->onSelect();
|
||||
|
@ -296,6 +307,7 @@ CScreenManager::_leaveScreen()
|
|||
{
|
||||
if(_bSetTimeScreenActive) _SetTimeScreen->onExit();
|
||||
else if(_bInheritScreenActive) _InheritScreen->onExit();
|
||||
else if(_bExperimentalScreenActive) _ExperimentalScreen->onExit();
|
||||
else if(_timerScreen >= 0) _TimerScreens[_timerScreen]->onExit();
|
||||
else if(_tuningScreen >= 0) _TuningScreens[_tuningScreen]->onExit();
|
||||
else if(_rootMenuScreen >= 0) _RootScreens[_rootMenuScreen]->onExit();
|
||||
|
@ -304,7 +316,7 @@ CScreenManager::_leaveScreen()
|
|||
void
|
||||
CScreenManager::nextScreen()
|
||||
{
|
||||
if(_bSetTimeScreenActive || _bInheritScreenActive) {
|
||||
if(_bSetTimeScreenActive || _bInheritScreenActive || _bExperimentalScreenActive) {
|
||||
}
|
||||
else if(_timerScreen >= 0) {
|
||||
_leaveScreen();
|
||||
|
@ -329,7 +341,7 @@ CScreenManager::nextScreen()
|
|||
void
|
||||
CScreenManager::prevScreen()
|
||||
{
|
||||
if(_bSetTimeScreenActive || _bInheritScreenActive) {
|
||||
if(_bSetTimeScreenActive || _bInheritScreenActive || _bExperimentalScreenActive) {
|
||||
}
|
||||
else if(_timerScreen >=0) {
|
||||
_leaveScreen();
|
||||
|
@ -365,6 +377,7 @@ CScreenManager::keyHandler(uint8_t event)
|
|||
// call key handler for active screen
|
||||
if(_bSetTimeScreenActive) _SetTimeScreen->keyHandler(event);
|
||||
else if(_bInheritScreenActive) _InheritScreen->keyHandler(event);
|
||||
else if(_bExperimentalScreenActive) _ExperimentalScreen->keyHandler(event);
|
||||
else if(_tuningScreen >= 0) _TuningScreens[_tuningScreen]->keyHandler(event);
|
||||
else if(_timerScreen >= 0) _TimerScreens[_timerScreen]->keyHandler(event);
|
||||
else if(_rootMenuScreen >= 0) _RootScreens[_rootMenuScreen]->keyHandler(event);
|
||||
|
@ -378,6 +391,7 @@ CScreenManager::_cancelBranchScreens()
|
|||
_tuningScreen = -1;
|
||||
_bSetTimeScreenActive = false;
|
||||
_bInheritScreenActive = false;
|
||||
_bExperimentalScreenActive = false;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -416,6 +430,16 @@ CScreenManager::selectInheritScreen(bool show)
|
|||
_enterScreen();
|
||||
}
|
||||
|
||||
void
|
||||
CScreenManager::selectExperimentalScreen(bool show)
|
||||
{
|
||||
_leaveScreen();
|
||||
_cancelBranchScreens();
|
||||
_bExperimentalScreenActive = show;
|
||||
_enterScreen();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CScreenManager::showRebootMsg(const char* content[2], long delayTime)
|
||||
{
|
||||
|
|
|
@ -36,12 +36,14 @@ class CScreenManager {
|
|||
std::vector<CScreen*> _TuningScreens;
|
||||
CScreen* _SetTimeScreen;
|
||||
CScreen* _InheritScreen;
|
||||
CScreen* _ExperimentalScreen;
|
||||
C128x64_OLED* _pDisplay;
|
||||
int _rootMenuScreen;
|
||||
int _timerScreen;
|
||||
int _tuningScreen;
|
||||
bool _bSetTimeScreenActive;
|
||||
bool _bInheritScreenActive;
|
||||
bool _bExperimentalScreenActive;
|
||||
unsigned long _DimTime;
|
||||
bool _bReqUpdate;
|
||||
void _enterScreen();
|
||||
|
@ -64,6 +66,7 @@ public:
|
|||
void selectSetTimeScreen(bool show);
|
||||
void selectSettingsScreen(bool show);
|
||||
void selectInheritScreen(bool show);
|
||||
void selectExperimentalScreen(bool show);
|
||||
};
|
||||
|
||||
#endif // __SCREEN_MANAGER_H__
|
||||
|
|
|
@ -175,6 +175,10 @@ CSettingsScreen::keyHandler(uint8_t event)
|
|||
_getPassword();
|
||||
}
|
||||
}
|
||||
// press DOWN
|
||||
if(event & key_Down) {
|
||||
_ScreenManager.selectExperimentalScreen(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ScreenManager.reqUpdate();
|
||||
|
|
27
Arduino/BTCDieselHeater/src/OLED/fonts/MicroFont.h
Normal file
27
Arduino/BTCDieselHeater/src/OLED/fonts/MicroFont.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include "FontTypes.h"
|
||||
|
||||
// Font data for Mini Font, a 3x5 font
|
||||
extern const uint8_t microFontBitmaps[] PROGMEM; // stored in program flash memory
|
||||
extern const FONT_CHAR_INFO microFontDescriptors[] PROGMEM; // stored in program flash memory
|
||||
extern const FONT_INFO microFontInfo;
|
||||
|
111
Arduino/BTCDieselHeater/src/OLED/fonts/microfont.cpp
Normal file
111
Arduino/BTCDieselHeater/src/OLED/fonts/microfont.cpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MicroFont.h"
|
||||
//
|
||||
// Font data for a 3x5 font
|
||||
// Hand carved by Ray Jones, based upon The Dot Factory font tool output structures
|
||||
//
|
||||
|
||||
// Character bitmaps for a 3x4 font
|
||||
const uint8_t microFontBitmaps[] PROGMEM =
|
||||
{
|
||||
// @1 '0' (3 pixels wide)
|
||||
0x60, // ##
|
||||
0x81, // # #
|
||||
0x60, // ##
|
||||
|
||||
// @4 '1' (3 pixels wide)
|
||||
0x80, // #
|
||||
0xf0, // ####
|
||||
0x00, //
|
||||
|
||||
// @7 '2' (3 pixels wide)
|
||||
0xb0, // # ##
|
||||
0xd0, // ## #
|
||||
0x00, //
|
||||
|
||||
// @10 '3' (3 pixels wide)
|
||||
0x90, // # #
|
||||
0xb0, // # ##
|
||||
0xf0, // ####
|
||||
|
||||
// @13 '4' (3 pixels wide)
|
||||
0x60, // ##
|
||||
0xb0, // # ##
|
||||
0x00, //
|
||||
|
||||
// @16 '5' (3 pixels wide)
|
||||
0xd0, // ## #
|
||||
0xb0, // # ##
|
||||
0x00, //
|
||||
|
||||
// @19 '6' (3 pixels wide)
|
||||
0xf0, // ####
|
||||
0x30, // ##
|
||||
0x00, //
|
||||
|
||||
// @22 '7' (3 pixels wide)
|
||||
0x80, // #
|
||||
0xf0, // ####
|
||||
0x00, //
|
||||
|
||||
// @25 '8' (3 pixels wide)
|
||||
0xf8, // #####
|
||||
0xa8, // # # #
|
||||
0xF8, // #####
|
||||
|
||||
// @28 '9' (3 pixels wide)
|
||||
0xc0, // ##
|
||||
0xf0, // ####
|
||||
0x00, //
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Character descriptors for a 3x5 font
|
||||
// { [Char width in bits], [Char height in bits], [Offset into tahoma_16ptCharBitmaps in bytes] }
|
||||
const FONT_CHAR_INFO miniFontDescriptors[] PROGMEM =
|
||||
{
|
||||
{3, 5, 1}, // '0'
|
||||
{3, 5, 4}, // '1'
|
||||
{3, 5, 7}, // '2'
|
||||
{3, 5, 10}, // '3'
|
||||
{3, 5, 13}, // '4'
|
||||
{3, 5, 16}, // '5'
|
||||
{3, 5, 19}, // '6'
|
||||
{3, 5, 22}, // '7'
|
||||
{3, 5, 25}, // '8'
|
||||
{3, 5, 28}, // '9'
|
||||
};
|
||||
|
||||
// Font information for Mini Font, a 3x5 font
|
||||
// easier to leave in RAM, not that big anyway
|
||||
const FONT_INFO microFontInfo =
|
||||
{
|
||||
4, // Character height
|
||||
'0', // Start character
|
||||
'9', // End character
|
||||
1, // Width, in pixels, of space character
|
||||
microFontDescriptors, // Character descriptor array
|
||||
microFontBitmaps, // Character bitmap array
|
||||
};
|
||||
|
|
@ -23,6 +23,9 @@
|
|||
#include "../Utility/NVStorage.h"
|
||||
#include "../Protocol/helpers.h"
|
||||
|
||||
//#define DEBUG_THERMOSTAT
|
||||
|
||||
|
||||
extern void DebugReportFrame(const char* hdr, const CProtocol&, const char* ftr);
|
||||
|
||||
// CTxManage is used to send a data frame to the blue wire
|
||||
|
@ -126,15 +129,19 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
|
|||
|
||||
if(NVstore.getThermostatMode()) {
|
||||
uint8_t ThermoMode = NVstore.getThermostatMethodMode(); // get the METHOD of thermostat control
|
||||
float Hysteresis = NVstore.getThermostatMethodHysteresis();
|
||||
float Window = NVstore.getThermostatMethodWindow();
|
||||
float tCurrent = getTemperatureSensor();
|
||||
float tDesired = float(NVstore.getDesiredTemperature());
|
||||
float tDelta = tCurrent - tDesired;
|
||||
float fTemp;
|
||||
#ifdef DEBUG_THERMOSTAT
|
||||
DebugPort.print("Hysteresis = "); DebugPort.print(Hysteresis); DebugPort.print(" tCurrent = "); DebugPort.print(tCurrent); DebugPort.print(" tDesired = "); DebugPort.print(tDesired); DebugPort.print(" tDelta = "); DebugPort.println(tDelta);
|
||||
DebugPort.print("Window = "); DebugPort.print(Window); DebugPort.print(" tCurrent = "); DebugPort.print(tCurrent); DebugPort.print(" tDesired = "); DebugPort.print(tDesired); DebugPort.print(" tDelta = "); DebugPort.println(tDelta);
|
||||
#endif
|
||||
Window /= 2;
|
||||
switch(ThermoMode) {
|
||||
|
||||
case 0: // conventional heater controlled thermostat mode
|
||||
case 3: // conventional heater controlled thermostat mode
|
||||
m_TxFrame.setThermostatModeProtocol(1); // using heater thermostat control
|
||||
u8Temp = (uint8_t)(tActual + 0.5);
|
||||
m_TxFrame.setTemperature_Actual(u8Temp);
|
||||
|
@ -142,38 +149,40 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
|
|||
DebugPort.print("Conventional thermostat mode: tActual = "); DebugPort.println(u8Temp);
|
||||
#endif
|
||||
break;
|
||||
case 1: // heater controlled thermostat mode - BUT actual temp is tweaked via a changed hysteresis
|
||||
|
||||
case 1: // heater controlled thermostat mode - BUT actual temp is tweaked via a changed window
|
||||
m_TxFrame.setThermostatModeProtocol(1); // using heater thermostat control
|
||||
u8Temp = (uint8_t)(tActual + 0.5); // use rounded actual unless within hysteresis window
|
||||
if(fabs(tDelta) < Hysteresis) {
|
||||
// hold at desired if inside hysteresis
|
||||
u8Temp = (uint8_t)(tActual + 0.5); // use rounded actual unless within window
|
||||
if(fabs(tDelta) < Window) {
|
||||
// hold at desired if inside window
|
||||
u8Temp = NVstore.getDesiredTemperature();
|
||||
}
|
||||
else if(fabs(tDelta) <= 1.0) {
|
||||
// force outside if delta is <= 1 but greater than hysteresis
|
||||
// force outside if delta is <= 1 but greater than window
|
||||
u8Temp = NVstore.getDesiredTemperature() + ((tDelta > 0) ? 1 : -1);
|
||||
}
|
||||
m_TxFrame.setTemperature_Actual(u8Temp);
|
||||
#ifdef DEBUG_THERMOSTAT
|
||||
DebugPort.print("Heater hysteresis thermostat mode: tActual = "); DebugPort.println(u8Temp);
|
||||
DebugPort.print("Heater controlled windowed thermostat mode: tActual = "); DebugPort.println(u8Temp);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 2: // BTC controlled thermostat mode
|
||||
// map Hysteresis to a Hz value,
|
||||
// map linear deviation within thermostat window to a Hz value,
|
||||
// Hz mode however uses the desired temperature field, somewhere between 8 - 35 for min/max
|
||||
// so create a desired "temp" according the the current hystersis
|
||||
tDelta /= Hysteresis; // convert tDelta to fraction of hysteresis (CAUTION - may be > +-1 !)
|
||||
tDelta /= Window; // convert tDelta to fraction of window (CAUTION - may be > +-1 !)
|
||||
#ifdef DEBUG_THERMOSTAT
|
||||
DebugPort.print("Controller hysteresis thermostat mode: Fraction = "); DebugPort.print(tDelta);
|
||||
DebugPort.print("Linear window thermostat mode: Fraction = "); DebugPort.print(tDelta);
|
||||
#endif
|
||||
Hysteresis = (m_TxFrame.getTemperature_Max() + m_TxFrame.getTemperature_Min()) * 0.5; // midpoint - tDelta = 0 hinges here
|
||||
tDelta *= (m_TxFrame.getTemperature_Max() - Hysteresis); // linear offset from setpoint
|
||||
Hysteresis -= tDelta; // lower Hz when over temp, higher Hz when under!
|
||||
fTemp = (m_TxFrame.getTemperature_Max() + m_TxFrame.getTemperature_Min()) * 0.5; // midpoint - tDelta = 0 hinges here
|
||||
tDelta *= (m_TxFrame.getTemperature_Max() - fTemp); // linear offset from setpoint
|
||||
fTemp -= tDelta; // lower Hz when over temp, higher Hz when under!
|
||||
// bounds limit - recall original tDelta was NOT managed prior!
|
||||
LOWERLIMIT(Hysteresis, m_TxFrame.getTemperature_Min());
|
||||
UPPERLIMIT(Hysteresis, m_TxFrame.getTemperature_Max());
|
||||
LOWERLIMIT(fTemp, m_TxFrame.getTemperature_Min());
|
||||
UPPERLIMIT(fTemp, m_TxFrame.getTemperature_Max());
|
||||
// apply modifed desired temperature (works in conjunction with thermostatmode = 0!)
|
||||
u8Temp = (uint8_t)(Hysteresis + 0.5);
|
||||
u8Temp = (uint8_t)(fTemp + 0.5);
|
||||
m_TxFrame.setTemperature_Desired(u8Temp);
|
||||
m_TxFrame.setThermostatModeProtocol(0); // direct heater to use Hz Mode
|
||||
m_TxFrame.setTemperature_Actual(0); // must force actual to 0 for Hz mode
|
||||
|
|
|
@ -50,7 +50,7 @@ sNVStore::init()
|
|||
timer[i].init();
|
||||
}
|
||||
DimTime = 60000; // 1 minute
|
||||
ThermostatMethod = 10 << 2; // 1 degree hysteresis, normal thermostat
|
||||
ThermostatMethod = 10 << 2; // 1 degree window, normal thermostat
|
||||
Heater.init();
|
||||
}
|
||||
|
||||
|
@ -102,9 +102,9 @@ CHeaterStorage::getThermostatMethodMode()
|
|||
}
|
||||
|
||||
float
|
||||
CHeaterStorage::getThermostatMethodHysteresis()
|
||||
CHeaterStorage::getThermostatMethodWindow()
|
||||
{
|
||||
return float((_calValues.ThermostatMethod >> 2) & 0x3f) * 0.05f; // top 5 bits / 10, then / 2
|
||||
return float((_calValues.ThermostatMethod >> 2) & 0x3f) * 0.1f; // top 5 bits / 10, then / 2
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -148,12 +148,12 @@ CHeaterStorage::setThermostatMode(unsigned char val)
|
|||
void
|
||||
CHeaterStorage::setThermostatMethodMode(unsigned char val)
|
||||
{
|
||||
_calValues.ThermostatMethod &= 0xF3;
|
||||
_calValues.ThermostatMethod &= ~0x03;
|
||||
_calValues.ThermostatMethod |= (val & 0x03);
|
||||
}
|
||||
|
||||
void
|
||||
CHeaterStorage::setThermostatMethodHysteresis(float val)
|
||||
CHeaterStorage::setThermostatMethodWindow(float val)
|
||||
{
|
||||
_calValues.ThermostatMethod &= 0x03;
|
||||
int nVal = int(val * 10 + 0.5);
|
||||
|
@ -363,7 +363,6 @@ CESP32HeaterStorage::loadUI()
|
|||
validatedLoad("dimTime", _calValues.DimTime, 60000, s32inBounds, 0, 600000);
|
||||
validatedLoad("degF", _calValues.degF, 0, u8inBounds, 0, 1);
|
||||
validatedLoad("thermoMethod", _calValues.ThermostatMethod, (10 << 2), u8inBounds, 0, 2, 0x03);
|
||||
// validatedLoad("thermoMethod", _calValues.ThermostatMethod, (10 << 2) + 0, u8inBounds, 0, 2); // TESTO!!!!
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public:
|
|||
unsigned char getDesiredTemperature();
|
||||
unsigned char getThermostatMode();
|
||||
unsigned char getThermostatMethodMode();
|
||||
float getThermostatMethodHysteresis();
|
||||
float getThermostatMethodWindow();
|
||||
unsigned char getSysVoltage();
|
||||
unsigned char getFanSensor();
|
||||
unsigned char getGlowDrive();
|
||||
|
@ -119,7 +119,7 @@ public:
|
|||
void setDesiredTemperature(unsigned char val);
|
||||
void setThermostatMode(unsigned char val);
|
||||
void setThermostatMethodMode(unsigned char val);
|
||||
void setThermostatMethodHysteresis(float val);
|
||||
void setThermostatMethodWindow(float val);
|
||||
void setSystemVoltage(float fVal);
|
||||
void setFanSensor(unsigned char val);
|
||||
void setGlowDrive(unsigned char val);
|
||||
|
|
Loading…
Reference in a new issue