Split PumpDemand and Temperature demands so Fixed Hz mode works cleanly, especially with Linear Hz thermostat and Cyclic mode.

Cyclic mode, if enabled, is now shown on detailed screen, bracketing its range
Shifted helpers.h into src/Utility - made far more logical sense!

Fancy pants slash screen :-D
This commit is contained in:
Ray Jones 2019-06-16 09:09:29 +10:00
parent a53d6eabd0
commit ce8299609b
47 changed files with 1248 additions and 172 deletions

View file

@ -97,7 +97,7 @@
#include "src/Protocol/Protocol.h"
#include "src/Protocol/TxManage.h"
#include "src/Protocol/SmartError.h"
#include "src/Protocol/helpers.h"
#include "src/Utility/helpers.h"
#include "src/Utility/NVStorage.h"
#include "src/Utility/DebugPort.h"
#include "src/Utility/UtilClasses.h"
@ -118,8 +118,8 @@
#define RX_DATA_TIMOUT 50
const int FirmwareRevision = 23;
const int FirmwareSubRevision = 1;
const char* FirmwareDate = "6 Jun 2019";
const int FirmwareSubRevision = 2;
const char* FirmwareDate = "16 Jun 2019";
#ifdef ESP32
@ -144,6 +144,8 @@ void checkDisplayUpdate();
void checkDebugCommands();
void manageCyclicMode();
void doStreaming();
void heaterOn();
void heaterOff();
// DS18B20 temperature sensor support
OneWire ds(15); // on pin 5 (a 4.7K resistor is necessary)
@ -376,6 +378,7 @@ void setup() {
NVstore.init();
NVstore.load();
initMQTTJSONmoderator(); // prevents JSON for MQTT unless requested
initTimerJSONmoderator(); // prevents JSON for timers unless requested
@ -423,7 +426,7 @@ void setup() {
TxManage.begin(); // ensure Tx enable pin is setup
// define defaults should OEM controller be missing
DefaultBTCParams.setTemperature_Desired(23);
DefaultBTCParams.setHeaterDemand(23);
DefaultBTCParams.setTemperature_Actual(22);
DefaultBTCParams.setSystemVoltage(12.0);
DefaultBTCParams.setPump_Min(1.6f);
@ -815,7 +818,7 @@ void manageCyclicMode()
const sCyclicThermostat& cyclic = NVstore.getCyclicMode();
if(cyclic.Stop && bUserON) { // cyclic mode enabled, and user has started heater
int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over!
float deltaT = fFilteredTemperature - getSetTemp();
float deltaT = fFilteredTemperature - getTemperatureDesired();
// DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT);
// ensure we cancel user ON mode if heater throws an error
@ -898,18 +901,6 @@ void heaterOff()
SmartError.inhibit();
}
void ToggleOnOff()
{
if(primaryHeaterData.getRunState()) {
DebugPort.println("ToggleOnOff: Heater OFF");
requestOff();
}
else {
DebugPort.println("ToggleOnOff: Heater ON");
requestOn();
}
}
bool reqTemp(unsigned char newTemp)
{
@ -923,9 +914,13 @@ bool reqTemp(unsigned char newTemp)
if(newTemp <= min)
newTemp = min;
// seta nd save the temperature to NV storage
// set and save the demand to NV storage
// note that we now maintain fixed Hz and Thermostat set points seperately
sUserSettings settings = NVstore.getUserSettings();
settings.desiredTemperature = newTemp;
if(getThermostatModeActive())
settings.demandDegC = newTemp;
else
settings.demandPump = newTemp;
NVstore.setUserSettings(settings);
NVstore.save();
@ -935,16 +930,15 @@ bool reqTemp(unsigned char newTemp)
bool reqTempDelta(int delta)
{
unsigned char newTemp = getSetTemp() + delta;
unsigned char newTemp;
if(getThermostatModeActive())
newTemp = NVstore.getUserSettings().demandDegC + delta;
else
newTemp = NVstore.getUserSettings().demandPump + delta;
return reqTemp(newTemp);
}
int getSetTemp()
{
return NVstore.getUserSettings().desiredTemperature;
}
bool reqThermoToggle()
{
return setThermostatMode(getThermostatModeActive() ? 0 : 1);
@ -1005,10 +999,10 @@ void reqPumpPrime(bool on)
float getTemperatureDesired()
{
if(bHasOEMController) {
return getHeaterInfo().getTemperature_Desired();
return getHeaterInfo().getHeaterDemand();
}
else {
return NVstore.getUserSettings().desiredTemperature;
return NVstore.getUserSettings().demandDegC;
}
}

File diff suppressed because one or more lines are too long

View file

@ -25,7 +25,7 @@
#include <Arduino.h>
#include "../Utility/UtilClasses.h"
#include "../Utility/Debugport.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
class CProtocol;

View file

@ -23,7 +23,7 @@
#include "../cfg/pins.h"
#include "../cfg/BTCConfig.h"
#include "../Protocol/Protocol.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/DebugPort.h"
// Bluetooth access via HC-05 Module, using a UART
@ -248,7 +248,7 @@ CBluetoothHC05::foldbackDesiredTemp()
StaticJsonBuffer<32> jsonBuffer; // create a JSON buffer on the stack
JsonObject& root = jsonBuffer.createObject(); // create object to add JSON commands to
if(foldbackModerator.addJson("TempDesired", getSetTemp(), root)) {
if(foldbackModerator.addJson("TempDesired", getTemperatureDesired(), root)) {
char opStr[32];
root.printTo(opStr);
send(opStr);

View file

@ -25,9 +25,10 @@
#include "fonts/Icons.h"
#include "BasicScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/UtilClasses.h"
#include "../Utility/NVStorage.h"
#include "../Protocol/Protocol.h"
#define MAXIFONT tahoma_24ptFontInfo

View file

@ -21,10 +21,11 @@
#include "ClockScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "fonts/Tahoma16.h"
#include "fonts/Tahoma24.h"
#include "../RTC/Clock.h"
#include "../Protocol/Protocol.h"
///////////////////////////////////////////////////////////////////////////
//

View file

@ -26,7 +26,7 @@
#include "DetailedScreen.h"
#include "../Wifi/BTCWifi.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Protocol/Protocol.h"
#include "../Utility/NVStorage.h"
@ -91,16 +91,21 @@ CDetailedScreen::show()
}
float desiredT = 0;
if((runstate && (runstate <= 5)) || _showTarget) {
float fPump = 0;
if((runstate && (runstate <= 5)) || (runstate == 9) || _showTarget) { // state 9 = manufactured "heating glow plug"
if(getThermostatModeActive())
desiredT = getTemperatureDesired();
else
desiredT = -getHeaterInfo().getPump_Fixed();
else {
fPump = getHeaterInfo().getPump_Fixed();
if(NVstore.getUserSettings().cyclic.isEnabled())
desiredT = getTemperatureDesired();
}
}
float fTemp = getTemperatureSensor();
showThermometer(desiredT, // read values from most recently sent [BTC] frame
fTemp);
fTemp,
fPump);
_animateRPM = false;
_animatePump = false;
@ -263,55 +268,75 @@ CDetailedScreen::keyHandler(uint8_t event)
#define TEMP_YPOS(A) ((20 - int(A)) + 27) // 26 is location of 20deg tick
void
CDetailedScreen::showThermometer(float desired, float actual)
CDetailedScreen::showThermometer(float fDesired, float fActual, float fPump)
{
char msg[16];
// draw bulb design
_drawBitmap(X_BULB, Y_BULB, AmbientThermometerIconInfo, WHITE);
if(actual > 0) {
if(fActual > 0) {
// draw mercury
int yPos = Y_BULB + TEMP_YPOS(actual);
int yPos = Y_BULB + TEMP_YPOS(fActual);
_display.drawLine(X_BULB + 3, yPos, X_BULB + 3, Y_BULB + 42, WHITE);
_display.drawLine(X_BULB + 4, yPos, X_BULB + 4, Y_BULB + 42, WHITE);
}
// print actual temperature
if(actual > -80) {
#ifdef MINI_TEMPLABEL
if(fActual > -80) {
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
if(NVstore.getUserSettings().degF) {
actual = actual * 9 / 5 + 32;
sprintf(msg, "%.1f`F", actual);
fActual = fActual * 9 / 5 + 32;
sprintf(msg, "%.1f`F", fActual);
}
else {
sprintf(msg, "%.1f`C", actual);
sprintf(msg, "%.1f`C", fActual);
}
#else
sprintf(msg, "%.1f", actual);
#endif
_printMenuText(0, Y_BASELINE, msg);
}
else {
_printInverted(1, Y_BASELINE-2, "N/A", true);
}
// draw cyclic bracket (if enabled)
if(NVstore.getUserSettings().cyclic.isEnabled() && (fDesired != 0)) {
int max = fDesired + NVstore.getUserSettings().cyclic.Stop + 1;
int min = fDesired + NVstore.getUserSettings().cyclic.Start; // stored as a negative value!
// convert to screen coordinates
max = Y_BULB + TEMP_YPOS(max);
min = Y_BULB + TEMP_YPOS(min);
int xOfs = 8;
// ####
_drawBitmap(X_BULB + xOfs, max, ThermoPtrHighIconInfo); // ##
// #
_display.drawFastVLine(X_BULB + xOfs + 3, max, (min-max), WHITE); // #
// ##
_drawBitmap(X_BULB + xOfs, min-2, ThermoPtrLowIconInfo); // ####
}
// draw target setting
if(desired) {
_drawBitmap(X_TARGET_ICON, Y_TARGET_ICON, TargetIconInfo); // set indicator against bulb
// may be suppressed if not in normal start or run state
if((fDesired != 0) || (fPump != 0)) {
_drawBitmap(X_TARGET_ICON, Y_TARGET_ICON, TargetIconInfo); // draw target icon
char msg[16];
if(desired > 0) {
int yPos = Y_BULB + TEMP_YPOS(desired) - 2;
_drawBitmap(X_BULB-1, yPos, ThermoPtrIconInfo); // set indicator against bulb
if(fPump == 0) {
int yPos = Y_BULB + TEMP_YPOS(fDesired) - 2; // 2 offsets mid height of icon
_drawBitmap(X_BULB-1, yPos, ThermoPtrIconInfo); // set closed indicator against bulb
if(NVstore.getUserSettings().degF) {
desired = desired * 9 / 5 + 32;
sprintf(msg, "%.0f`F", desired);
fDesired = fDesired * 9 / 5 + 32;
sprintf(msg, "%.0f`F", fDesired);
}
else {
sprintf(msg, "%.0f`C", desired);
sprintf(msg, "%.0f`C", fDesired);
}
}
else {
sprintf(msg, "%.1fHz", -desired);
if(fDesired) {
int yPos = Y_BULB + TEMP_YPOS(fDesired) - 2;
_drawBitmap(X_BULB-1, yPos, ThermoOpenPtrIconInfo); // set open style indicator against bulb
}
sprintf(msg, "%.1fHz", fPump);
}
#ifdef MINI_TARGETLABEL
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font

View file

@ -41,7 +41,7 @@ class CDetailedScreen : public CScreenHeader
unsigned long _showTarget;
void showRunState();
void showThermometer(float desired, float actual);
void showThermometer(float desired, float actual, float pump);
void showBodyThermometer(int actual);
void showGlowPlug(float power);
void showFan(int RPM);

View file

@ -30,9 +30,11 @@
#include "FuelMixtureScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Wifi/BTCWifi.h"
#include "../utility/debugPort.h"
#include "../Utility/macros.h"
#include "../Protocol/Protocol.h"
CFuelMixtureScreen::CFuelMixtureScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)

View file

@ -22,7 +22,7 @@
#include "128x64OLED.h"
#include "GPIOScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/UtilClasses.h"
#include "../Utility/NVStorage.h"
#include "../Utility/GPIO.h"

View file

@ -22,8 +22,10 @@
#include "128x64OLED.h"
#include "HeaterSettingsScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/UtilClasses.h"
#include "../Utility/macros.h"
#include "../Protocol/Protocol.h"
///////////////////////////////////////////////////////////////////////////
//

View file

@ -22,7 +22,7 @@
#include "128x64OLED.h"
#include "HomeMenuSelScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/UtilClasses.h"
#include "../Utility/NVStorage.h"
#include "../Utility/GPIO.h"

View file

@ -30,8 +30,8 @@
#include "InheritSettingsScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
// #include "../Wifi/BTCWifi.h"
#include "../Utility/helpers.h"
#include "../Protocol/Protocol.h"
CInheritSettingsScreen::CInheritSettingsScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)

View file

@ -22,7 +22,7 @@
#include "128x64OLED.h"
#include "OtherOptionsScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/UtilClasses.h"
#include "../Utility/NVStorage.h"
#include "../Utility/GPIO.h"

View file

@ -30,9 +30,9 @@
#include "PasswordScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Wifi/BTCWifi.h"
#include "fonts/Arial.h"
#include "../Utility/macros.h"
CPasswordScreen::CPasswordScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreenHeader(display, mgr)

View file

@ -21,8 +21,8 @@
#include "PrimingScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/NVStorage.h"
#include "../Protocol/Protocol.h"
///////////////////////////////////////////////////////////////////////////
//

View file

@ -22,7 +22,7 @@
#include <Arduino.h>
#include "ScreenHeader.h"
#include "../Protocol/Protocol.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Wifi/BTCWifi.h"
#include "../Bluetooth/BluetoothAbstract.h"
#include "../Utility/NVStorage.h"

View file

@ -42,10 +42,11 @@
#include <Wire.h>
#include "../cfg/pins.h"
#include "../cfg/BTCConfig.h"
#include "../protocol/helpers.h"
#include "keypad.h"
#include "fonts/Icons.h"
#include "fonts/MiniFont.h"
#include "fonts/MidiFont.h"
#include "../Protocol/Protocol.h"
////////////////////////////////////////////////////////////////////////////////////////////////
@ -57,7 +58,7 @@
// Identifier: DieselSplash
// Draw Mode: Horizontal
//
const unsigned char DieselSplash [] PROGMEM = {
/*const unsigned char DieselSplash [] PROGMEM = {
// 'Splash3, 128x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -124,6 +125,77 @@ const unsigned char DieselSplash [] PROGMEM = {
0x00, 0x02, 0x28, 0x44, 0x21, 0x2b, 0x42, 0x50, 0x80, 0x21, 0x4a, 0x51, 0x09, 0x54, 0x20, 0x00,
0x00, 0x02, 0x28, 0x33, 0x21, 0xc5, 0x42, 0x4c, 0x80, 0x1e, 0x32, 0x4d, 0x06, 0x53, 0x20, 0x00
};
*/
const unsigned char DieselSplash [] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // #
0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ####### ##
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xC4, 0x00, 0x03, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # ##### # ## #
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # # ##
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x03, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # # ## #
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ### # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ##
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // #
0x00, 0x30, 0x03, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ## ## ## #
0x00, 0x30, 0x07, 0x86, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ## #### ## ##
0x00, 0x78, 0x0E, 0xC6, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // #### ### ## ## ##
0x00, 0x78, 0x0C, 0xC6, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // #### ## ## ## ##
0x00, 0xD8, 0x0C, 0x0C, 0x0E, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x1C, // ## ## ## ## ### ## ## ### ### ###
0x00, 0xCC, 0x18, 0x0C, 0x1F, 0x06, 0x3B, 0x1C, 0x00, 0x30, 0x31, 0xCC, 0x00, 0x1F, 0x06, 0x38, // ## ## ## ## ##### ## ### ## ### ## ## ### ## ##### ## ###
0x01, 0x8C, 0x18, 0xFF, 0xF3, 0x06, 0x73, 0x3E, 0x18, 0x30, 0x33, 0x8C, 0xF0, 0x33, 0x06, 0x70, // ## ## ## ############ ## ## ### ## ##### ## ## ## ### ## #### ## ## ## ###
0x03, 0x8C, 0x3F, 0x8C, 0x33, 0x0E, 0xC3, 0x66, 0x38, 0x30, 0x76, 0x0D, 0xF8, 0x33, 0x0E, 0xC0, // ### ## ####### ## ## ## ### ## ## ## ## ### ## ### ## ## ###### ## ## ### ##
0x03, 0x0C, 0x3E, 0x0C, 0x36, 0x17, 0x83, 0xC6, 0x58, 0x70, 0xBC, 0x0F, 0xB8, 0x76, 0x17, 0x80, // ## ## ##### ## ## ## # #### #### ## # ## ### # #### ##### ### ### ## # ####
0x07, 0xFE, 0x18, 0x0C, 0x3C, 0x27, 0x03, 0x86, 0x98, 0x71, 0x38, 0x0F, 0x18, 0xBC, 0x27, 0x00, // ########## ## ## #### # ### ### ## # ## ### # ### #### ## # #### # ###
0x0F, 0xCE, 0x18, 0x18, 0x30, 0x47, 0x03, 0x8F, 0x18, 0xDE, 0x38, 0x0E, 0x19, 0x30, 0x47, 0x00, // ###### ### ## ## ## # ### ### #### ## ## #### ### ### ## # ## # ###
0x1C, 0x07, 0x18, 0x18, 0x31, 0x86, 0x03, 0x1E, 0x19, 0x8C, 0x30, 0x0E, 0x1E, 0x31, 0x86, 0x00, // ### ### ## ## ## ## ## ## #### ## ## ## ## ### #### ## ## ##
0x38, 0x03, 0x18, 0x18, 0x3F, 0x06, 0x03, 0x38, 0x1F, 0x00, 0x30, 0x0C, 0x0C, 0x3F, 0x06, 0x00, // ### ## ## ## ###### ## ## ### ##### ## ## ## ###### ##
0x30, 0x01, 0x98, 0x18, 0x1E, 0x04, 0x01, 0xF0, 0x0C, 0x00, 0x20, 0x00, 0x00, 0x1E, 0x04, 0x00, // ## ## ## ## #### # ##### ## # #### #
0x20, 0x01, 0xB0, 0x30, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // # ## ## ## ##
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ##
0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ###
0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x21, 0x24, 0x00, // ### ## # # # # #
0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x20, 0x24, 0x00, // ## # # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x19, 0x28, 0xCA, 0x30, 0xE1, 0xC9, 0x06, 0x39, 0x25, 0x20, // ## ## # # # ## # # ## ### ### # # ## ### # # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x25, 0x69, 0x2D, 0x49, 0x21, 0x29, 0x09, 0x29, 0x49, 0x20, // # # # # # ## # # # ## # # # # # # # # # # # # # # # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x45, 0xAB, 0xC8, 0xF2, 0x22, 0x29, 0x10, 0x4A, 0x49, 0x20, // # # # # ## # # #### # #### # # # # # # # # # # # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x45, 0xB2, 0x08, 0x82, 0x22, 0x2A, 0x10, 0x4A, 0x49, 0x40, // # # # # ## ## # # # # # # # # # # # # # # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x49, 0x22, 0x50, 0x92, 0x42, 0x44, 0x11, 0x4A, 0x48, 0x80, // # # # # # # # # # # # # # # # # # # # # # # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x31, 0x21, 0x90, 0x61, 0x81, 0x84, 0x0E, 0x4A, 0x6C, 0x80, // ### ## # # ## # ## ## ## # ### # # # ## ## #
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, // # # #
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ##
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
};
CScreenManager::CScreenManager()
@ -173,14 +245,16 @@ CScreenManager::begin(bool bNoClock)
// replace adafruit splash screen
_pDisplay->clearDisplay();
_pDisplay->drawBitmap(0, 0, DieselSplash, 128, 64, WHITE);
_pDisplay->setCursor(90, 50);
CTransientFont AF(*_pDisplay, &miniFontInfo); // temporarily use a mini font
_pDisplay->setCursor(90, 56);
CTransientFont AF(*_pDisplay, &segoeUI_Italic_7ptFontInfo); // temporarily use a midi font
_pDisplay->setTextColor(WHITE);
_pDisplay->print(getVersionStr());
// Show initial display buffer contents on the screen --
_pDisplay->display();
delay(2000);
DebugPort.println("Creating Screens");
std::vector<CScreen*> menuloop;

View file

@ -30,9 +30,9 @@
#include "SetClockScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "fonts/Arial.h"
#include "../RTC/Clock.h"
#include "../Utility/macros.h"
CSetClockScreen::CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreenHeader(display, mgr)

View file

@ -30,7 +30,7 @@
#include "SetTimerScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/NVStorage.h"
#include <RTClib.h>
#include "../RTC/TimerManager.h"

View file

@ -30,8 +30,10 @@
#include "SettingsScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Wifi/BTCWifi.h"
#include "../Utility/macros.h"
#include "../Protocol/Protocol.h"
static const int Line3 = 20; // system voltage
static const int Line2 = 30; // fan sensor

View file

@ -22,7 +22,7 @@
#include "128x64OLED.h"
#include "ThermostatModeScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/UtilClasses.h"
#include "fonts/Icons.h"
#include "../Utility/NVStorage.h"

View file

@ -30,7 +30,7 @@
#include "TimerChartScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/NVStorage.h"
#include <RTClib.h>
#include "fonts/MiniFont.h"

View file

@ -22,7 +22,7 @@
#include "128x64OLED.h"
#include "VersionInfoScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/UtilClasses.h"
#include "../Utility/NVStorage.h"
#include "../Utility/GPIO.h"

View file

@ -21,7 +21,7 @@
#include "WiFiScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Wifi/BTCWifi.h"
#include "../Utility/NVstorage.h"

View file

@ -142,6 +142,32 @@ const unsigned char thermoPtr [] PROGMEM = {
};
const BITMAP_INFO ThermoPtrIconInfo(3, 5, thermoPtr);
// 'ThermoPtr', 3x5px
const unsigned char thermoOpenPtr [] PROGMEM = {
0x80, // #
0x40, // #
0x20, // #
0x40, // #
0x80 // #
};
const BITMAP_INFO ThermoOpenPtrIconInfo(3, 5, thermoOpenPtr);
// 'ThermoPtrHigh', 4x3px
const unsigned char thermoPtrHigh [] PROGMEM = {
0xf0, // ####
0x30, // ##
0x10 // #
};
const BITMAP_INFO ThermoPtrHighIconInfo(4, 3, thermoPtrHigh);
// 'ThermoPtrLow', 4x3px
const unsigned char thermoPtrLow [] PROGMEM = {
0x10, // #
0x30, // ##
0xf0 // ####
};
const BITMAP_INFO ThermoPtrLowIconInfo(4, 3, thermoPtrLow);
// 'Bluetooth icon', 6x11px
const unsigned char BTicon [] PROGMEM = {
0x20, // #

View file

@ -27,6 +27,9 @@ extern const BITMAP_INFO AmbientThermometerIconInfo;
// 'ThermoPtr', 3x5px
extern const BITMAP_INFO ThermoPtrIconInfo;
extern const BITMAP_INFO ThermoOpenPtrIconInfo;
extern const BITMAP_INFO ThermoPtrHighIconInfo;
extern const BITMAP_INFO ThermoPtrLowIconInfo;
// 'Bluetooth icon', 6x11px
extern const BITMAP_INFO BluetoothIconInfo;

View file

@ -0,0 +1,41 @@
/*
* 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 Segoe UI 8pt
extern const uint8_t PROGMEM segoeUI_8ptBitmaps [] PROGMEM;
extern const FONT_INFO segoeUI_8ptFontInfo ;
extern const FONT_CHAR_INFO PROGMEM segoeUI_8ptDescriptors[] PROGMEM;
extern const uint8_t PROGMEM segoeUI_Italic_8ptBitmaps [] PROGMEM;
extern const FONT_INFO segoeUI_Italic_8ptFontInfo ;
extern const FONT_CHAR_INFO PROGMEM segoeUI_Italic_8ptDescriptors[] PROGMEM;
// Font data for Segoe UI 7pt
extern const uint8_t PROGMEM segoeUI_7ptBitmaps [];
extern const FONT_INFO segoeUI_7ptFontInfo;
extern const FONT_CHAR_INFO PROGMEM segoeUI_7ptDescriptors[];
extern const uint8_t PROGMEM segoeUI_Italic_7ptBitmaps [];
extern const FONT_INFO segoeUI_Italic_7ptFontInfo;
extern const FONT_CHAR_INFO PROGMEM segoeUI_Italic_7ptDescriptors[];

View file

@ -0,0 +1,796 @@
/*
* 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 "MidiFont.h"
//
// Font data for Segoe UI 8pt
//
// Character bitmaps for Segoe UI 8pt
const uint8_t PROGMEM segoeUI_8ptBitmaps [] =
{
// @0 ' ' (2 pixels wide)
0x00, 0x00, //
0x00, 0x00, //
// @4 '-' (3 pixels wide)
0x08, // #
0x08, // #
0x08, // #
// @7 '.' (1 pixels wide)
0x03, // ##
// @8 '0' (6 pixels wide)
0x3E, // #####
0xC3, // ## ##
0x81, // # #
0x81, // # #
0xC3, // ## ##
0x7C, // #####
// @14 '1' (3 pixels wide)
0x40, // #
0x40, // #
0xFF, // ########
// @17 '2' (4 pixels wide)
0x43, // # ##
0x85, // # # #
0x89, // # # #
0x71, // ### #
// @21 '3' (4 pixels wide)
0x81, // # #
0x91, // # # #
0x91, // # # #
0x6E, // ## ###
// @25 '4' (6 pixels wide)
0x0C, // ##
0x14, // # #
0x24, // # #
0xC4, // ## #
0xFF, // ########
0x04, // #
// @31 '5' (4 pixels wide)
0xF1, // #### #
0x91, // # # #
0x91, // # # #
0x8E, // # ###
// @35 '6' (5 pixels wide)
0x3E, // #####
0x51, // # # #
0x91, // # # #
0x91, // # # #
0x8E, // # ###
// @40 '7' (4 pixels wide)
0x80, // #
0x87, // # ###
0xB8, // # ###
0xC0, // ##
// @44 '8' (5 pixels wide)
0x6E, // ## ###
0x91, // # # #
0x91, // # # #
0x91, // # # #
0x6E, // ## ###
// @49 '9' (5 pixels wide)
0x71, // ### #
0x89, // # # #
0x89, // # # #
0x8A, // # # #
0x7C, // #####
// @54 ':' (1 pixels wide)
0xCC, // ## ##
// @55 'C' (5 pixels wide)
0x3C, // ####
0x42, // # #
0x81, // # #
0x81, // # #
0x81, // # #
// @60 'F' (4 pixels wide)
0xFF, // ########
0x90, // # #
0x90, // # #
0x90, // # #
// @64 '`' (2 pixels wide)
0x80, // #
0x40, // #
};
// Character descriptors for Segoe UI 8pt
// { [Char width in bits], [Char height in bits], [Offset into segoeUI_8ptCharBitmaps in bytes] }
const FONT_CHAR_INFO PROGMEM segoeUI_8ptDescriptors[] =
{
{2, 13, 0}, // ' '
{0, 0, 0}, // '!'
{0, 0, 0}, // '"'
{0, 0, 0}, // '#'
{0, 0, 0}, // '$'
{0, 0, 0}, // '%'
{0, 0, 0}, // '&'
{0, 0, 0}, // '''
{0, 0, 0}, // '('
{0, 0, 0}, // ')'
{0, 0, 0}, // '*'
{0, 0, 0}, // '+'
{0, 0, 0}, // ','
{3, 8, 4}, // '-'
{1, 8, 7}, // '.'
{0, 0, 0}, // '/'
{6, 8, 8}, // '0'
{3, 8, 14}, // '1'
{4, 8, 17}, // '2'
{4, 8, 21}, // '3'
{6, 8, 25}, // '4'
{4, 8, 31}, // '5'
{5, 8, 35}, // '6'
{4, 8, 40}, // '7'
{5, 8, 44}, // '8'
{5, 8, 49}, // '9'
{1, 6, 54}, // ':'
{0, 0, 0}, // ';'
{0, 0, 0}, // '<'
{0, 0, 0}, // '='
{0, 0, 0}, // '>'
{0, 0, 0}, // '?'
{0, 0, 0}, // '@'
{0, 0, 0}, // 'A'
{0, 0, 0}, // 'B'
{5, 8, 55}, // 'C'
{0, 0, 0}, // 'D'
{0, 0, 0}, // 'E'
{4, 8, 60}, // 'F'
{0, 0, 0}, // 'G'
{0, 0, 0}, // 'H'
{0, 0, 0}, // 'I'
{0, 0, 0}, // 'J'
{0, 0, 0}, // 'K'
{0, 0, 0}, // 'L'
{0, 0, 0}, // 'M'
{0, 0, 0}, // 'N'
{0, 0, 0}, // 'O'
{0, 0, 0}, // 'P'
{0, 0, 0}, // 'Q'
{0, 0, 0}, // 'R'
{0, 0, 0}, // 'S'
{0, 0, 0}, // 'T'
{0, 0, 0}, // 'U'
{0, 0, 0}, // 'V'
{0, 0, 0}, // 'W'
{0, 0, 0}, // 'X'
{0, 0, 0}, // 'Y'
{0, 0, 0}, // 'Z'
{0, 0, 0}, // '['
{0, 0, 0}, // '\'
{0, 0, 0}, // ']'
{0, 0, 0}, // '^'
{0, 0, 0}, // '_'
{2, 2, 64}, // '`'
};
// Font information for Segoe UI 8pt
const FONT_INFO segoeUI_8ptFontInfo =
{
13, // Character height
' ', // Start character
'`', // End character
1, // Width, in pixels, of space character
segoeUI_8ptDescriptors, // Character descriptor array
segoeUI_8ptBitmaps, // Character bitmap array
};
// Character bitmaps for Segoe UI 8pt
const uint8_t PROGMEM segoeUI_Italic_8ptBitmaps [] =
{
// @0 ' ' (2 pixels wide)
0x00, 0x00, //
0x00, 0x00, //
// @4 '-' (3 pixels wide)
0x08, // #
0x08, // #
0x08, // #
// @7 '.' (1 pixels wide)
0x3, // ##
// @8 '0' (6 pixels wide)
0x0C, // ##
0x33, // ## ##
0xC1, // ## #
0x81, // # #
0x86, // # ##
0x78, // ####
// @14 '1' (3 pixels wide)
0x41, // # #
0x7E, // ######
0xC0, // ##
// @17 '2' (6 pixels wide)
0x03, // ##
0x05, // # #
0x85, // # # #
0x89, // # # #
0x91, // # # #
0x60, // ##
// @23 '3' (6 pixels wide)
0x01, // #
0x01, // #
0x91, // # # #
0x91, // # # #
0xAE, // # # ###
0x40, // #
// @29 '4' (6 pixels wide)
0x04, // #
0x0C, // ##
0x14, // # #
0x67, // ## ###
0xFC, // ######
0x84, // # #
// @35 '5' (6 pixels wide)
0x01, // #
0x31, // ## #
0xD1, // ## # #
0x91, // # # #
0x8E, // # ###
0x80, // #
// @41 '6' (5 pixels wide)
0x3F, // ######
0x51, // # # #
0x91, // # # #
0x9E, // # ####
0x80, // #
// @46 '7' (5 pixels wide)
0x01, // #
0x86, // # ##
0x98, // # ##
0xA0, // # #
0xC0, // ##
// @51 '8' (6 pixels wide)
0x06, // ##
0x2B, // # # ##
0xD1, // ## # #
0x91, // # # #
0x9E, // # ####
0x60, // ##
// @57 '9' (6 pixels wide)
0x01, // #
0x71, // ### #
0x89, // # # #
0x8B, // # # ##
0x96, // # # ##
0x78, // ####
// @63 ':' (2 pixels wide)
0x0C, // ##
0xC0, // ##
// @65 'C' (6 pixels wide)
0x3E, // #####
0x43, // # ##
0x81, // # #
0x81, // # #
0x81, // # #
0x80, // #
// @71 'F' (6 pixels wide)
0x01, // #
0x1E, // ####
0xE8, // ### #
0x88, // # #
0x88, // # #
0x80, // #
// @77 '`' (1 pixels wide)
0x80, // #
};
// Character descriptors for Segoe UI 8pt
// { [Char width in bits], [Char height in bits], [Offset into segoeUI_8ptCharBitmaps in bytes] }
const FONT_CHAR_INFO PROGMEM segoeUI_Italic_8ptDescriptors[] =
{
{2, 13, 0}, // ' '
{0, 0, 0}, // '!'
{0, 0, 0}, // '"'
{0, 0, 0}, // '#'
{0, 0, 0}, // '$'
{0, 0, 0}, // '%'
{0, 0, 0}, // '&'
{0, 0, 0}, // '''
{0, 0, 0}, // '('
{0, 0, 0}, // ')'
{0, 0, 0}, // '*'
{0, 0, 0}, // '+'
{0, 0, 0}, // ','
{3, 8, 4}, // '-'
{1, 8, 7}, // '.'
{0, 0, 0}, // '/'
{6, 8, 8}, // '0'
{3, 8, 14}, // '1'
{6, 8, 17}, // '2'
{6, 8, 23}, // '3'
{6, 8, 29}, // '4'
{6, 8, 35}, // '5'
{5, 8, 41}, // '6'
{5, 8, 46}, // '7'
{6, 8, 51}, // '8'
{6, 8, 57}, // '9'
{2, 6, 63}, // ':'
{0, 0, 0}, // ';'
{0, 0, 0}, // '<'
{0, 0, 0}, // '='
{0, 0, 0}, // '>'
{0, 0, 0}, // '?'
{0, 0, 0}, // '@'
{0, 0, 0}, // 'A'
{0, 0, 0}, // 'B'
{6, 8, 65}, // 'C'
{0, 0, 0}, // 'D'
{0, 0, 0}, // 'E'
{6, 8, 71}, // 'F'
{0, 0, 0}, // 'G'
{0, 0, 0}, // 'H'
{0, 0, 0}, // 'I'
{0, 0, 0}, // 'J'
{0, 0, 0}, // 'K'
{0, 0, 0}, // 'L'
{0, 0, 0}, // 'M'
{0, 0, 0}, // 'N'
{0, 0, 0}, // 'O'
{0, 0, 0}, // 'P'
{0, 0, 0}, // 'Q'
{0, 0, 0}, // 'R'
{0, 0, 0}, // 'S'
{0, 0, 0}, // 'T'
{0, 0, 0}, // 'U'
{0, 0, 0}, // 'V'
{0, 0, 0}, // 'W'
{0, 0, 0}, // 'X'
{0, 0, 0}, // 'Y'
{0, 0, 0}, // 'Z'
{0, 0, 0}, // '['
{0, 0, 0}, // '\'
{0, 0, 0}, // ']'
{0, 0, 0}, // '^'
{0, 0, 0}, // '_'
{1, 1, 77}, // '`'
};
//
// Font information for Segoe UI 8pt
const FONT_INFO segoeUI_Italic_8ptFontInfo =
{
13, // Character height
' ', // Start character
'`', // End character
1, // Width, in pixels, of space character
segoeUI_Italic_8ptDescriptors, // Character descriptor array
segoeUI_Italic_8ptBitmaps, // Character bitmap array
};
//
// Font data for Segoe UI 7pt
//
// Character bitmaps for Segoe UI 7pt
const uint8_t PROGMEM segoeUI_7ptBitmaps [] =
{
// @0 ' ' (2 pixels wide)
0x00, 0x00, //
0x00, 0x00, //
// @4 '-' (2 pixels wide)
0x08, // #
0x08, // #
// @6 '.' (1 pixels wide)
0x02, // #
// @7 '0' (5 pixels wide)
0x7C, // #####
0x82, // # #
0x82, // # #
0x82, // # #
0x7C, // #####
// @12 '1' (2 pixels wide)
0x40, // #
0xFE, // #######
// @14 '2' (4 pixels wide)
0x46, // # ##
0x8A, // # # #
0x92, // # # #
0x62, // ## #
// @18 '3' (4 pixels wide)
0x82, // # #
0x92, // # # #
0x92, // # # #
0x6C, // ## ##
// @22 '4' (5 pixels wide)
0x0C, // ##
0x34, // ## #
0x44, // # #
0xFE, // #######
0x04, // #
// @27 '5' (4 pixels wide)
0xF2, // #### #
0x92, // # # #
0x92, // # # #
0x8C, // # ##
// @31 '6' (5 pixels wide)
0x3C, // ####
0x62, // ## #
0xA2, // # # #
0xA2, // # # #
0x9C, // # ###
// @36 '7' (4 pixels wide)
0x80, // #
0x86, // # ##
0xB8, // # ###
0xC0, // ##
// @40 '8' (5 pixels wide)
0x6C, // ## ##
0x92, // # # #
0x92, // # # #
0x92, // # # #
0x6C, // ## ##
// @45 '9' (5 pixels wide)
0x72, // ### #
0x8A, // # # #
0x8A, // # # #
0x8E, // # ###
0x78, // ####
// @50 ':' (1 pixels wide)
0x88, // # #
// @51 'C' (5 pixels wide)
0x3C, // ####
0x46, // # ##
0x82, // # #
0x82, // # #
0x82, // # #
// @56 'F' (3 pixels wide)
0xFE, // #######
0x90, // # #
0x90, // # #
// @59 'V' (6 pixels wide)
0xC0, // ##
0x38, // ###
0x06, // ##
0x0E, // ###
0x70, // ###
0x80, // #
// @65 '`' (2 pixels wide)
0x80, // #
0x40, // #
};
// Character descriptors for Segoe UI 7pt
// { [Char width in bits], [Char height in bits], [Offset into segoeUI_7ptCharBitmaps in bytes] }
const FONT_CHAR_INFO PROGMEM segoeUI_7ptDescriptors[] =
{
{2, 12, 0}, // ' '
{0, 0, 0}, // '!'
{0, 0, 0}, // '"'
{0, 0, 0}, // '#'
{0, 0, 0}, // '$'
{0, 0, 0}, // '%'
{0, 0, 0}, // '&'
{0, 0, 0}, // '''
{0, 0, 0}, // '('
{0, 0, 0}, // ')'
{0, 0, 0}, // '*'
{0, 0, 0}, // '+'
{0, 0, 0}, // ','
{2, 5, 4}, // '-'
{1, 7, 6}, // '.'
{0, 0, 0}, // '/'
{5, 7, 7}, // '0'
{2, 7, 12}, // '1'
{4, 7, 14}, // '2'
{4, 7, 18}, // '3'
{5, 7, 22}, // '4'
{4, 7, 27}, // '5'
{5, 7, 31}, // '6'
{4, 7, 36}, // '7'
{5, 7, 40}, // '8'
{5, 7, 45}, // '9'
{1, 5, 50}, // ':'
{0, 0, 0}, // ';'
{0, 0, 0}, // '<'
{0, 0, 0}, // '='
{0, 0, 0}, // '>'
{0, 0, 0}, // '?'
{0, 0, 0}, // '@'
{0, 0, 0}, // 'A'
{0, 0, 0}, // 'B'
{5, 7, 51}, // 'C'
{0, 0, 0}, // 'D'
{0, 0, 0}, // 'E'
{3, 7, 56}, // 'F'
{0, 0, 0}, // 'G'
{0, 0, 0}, // 'H'
{0, 0, 0}, // 'I'
{0, 0, 0}, // 'J'
{0, 0, 0}, // 'K'
{0, 0, 0}, // 'L'
{0, 0, 0}, // 'M'
{0, 0, 0}, // 'N'
{0, 0, 0}, // 'O'
{0, 0, 0}, // 'P'
{0, 0, 0}, // 'Q'
{0, 0, 0}, // 'R'
{0, 0, 0}, // 'S'
{0, 0, 0}, // 'T'
{0, 0, 0}, // 'U'
{6, 7, 59}, // 'V'
{0, 0, 0}, // 'W'
{0, 0, 0}, // 'X'
{0, 0, 0}, // 'Y'
{0, 0, 0}, // 'Z'
{0, 0, 0}, // '['
{0, 0, 0}, // '\'
{0, 0, 0}, // ']'
{0, 0, 0}, // '^'
{0, 0, 0}, // '_'
{2, 2, 65}, // '`'
};
// Font information for Segoe UI 7pt
const FONT_INFO segoeUI_7ptFontInfo =
{
12, // Character height
' ', // Start character
'`', // End character
1,
segoeUI_7ptDescriptors, // Character descriptor array
segoeUI_7ptBitmaps, // Character bitmap array
};
//
// Font data for Segoe UI 7pt
//
// Character bitmaps for Segoe UI 7pt
const uint8_t PROGMEM segoeUI_Italic_7ptBitmaps [] =
{
// @0 ' ' (2 pixels wide)
0x00, 0x00, //
0x00, 0x00, //
// @4 '-' (2 pixels wide)
0x08, // #
0x08, // #
// @6 '.' (1 pixels wide)
0x02, // #
// @7 '0' (5 pixels wide)
0x1C, // ###
0x62, // ## #
0x82, // # #
0x8C, // # ##
0x70, // ###
// @12 '1' (2 pixels wide)
0x5E, // # ####
0xE0, // ###
// @14 '2' (5 pixels wide)
0x06, // ##
0x46, // # ##
0x8A, // # # #
0x92, // # # #
0x60, // ##
// @19 '3' (5 pixels wide)
0x02, // #
0x12, // # #
0x92, // # # #
0xAC, // # # ##
0x40, // #
// @24 '4' (5 pixels wide)
0x18, // ##
0x28, // # #
0x48, // # #
0xFC, // ######
0x88, // # #
// @29 '5' (5 pixels wide)
0x06, // ##
0x72, // ### #
0x92, // # # #
0x9C, // # ###
0x80, // #
// @34 '6' (4 pixels wide)
0x7E, // ######
0xA2, // # # #
0xBE, // # #####
0x80, // #
// @38 '7' (4 pixels wide)
0x86, // # ##
0x98, // # ##
0xA0, // # #
0xC0, // ##
// @42 '8' (5 pixels wide)
0x0C, // ##
0x6A, // ## # #
0x92, // # # #
0x9E, // # ####
0x60, // ##
// @47 '9' (5 pixels wide)
0x02, // #
0x72, // ### #
0x92, // # # #
0x9C, // # ###
0x70, // ###
// @52 ':' (2 pixels wide)
0x08, // #
0x80, // #
// @54 'C' (5 pixels wide)
0x7C, // #####
0xC2, // ## #
0x82, // # #
0x82, // # #
0x80, // #
// @59 'F' (5 pixels wide)
0x06, // ##
0x78, // ####
0x90, // # #
0x90, // # #
0x80, // #
// @64 'V' (5 pixels wide)
0xFC, // ######
0x06, // ##
0x18, // ##
0x20, // #
0xC0, // ##
// @69 '`' (2 pixels wide)
0x80, // #
0x40, // #
};
// Character descriptors for Segoe UI 7pt
// { [Char width in bits], [Char height in bits], [Offset into segoeUI_7ptCharBitmaps in bytes] }
const FONT_CHAR_INFO PROGMEM segoeUI_Italic_7ptDescriptors[] =
{
{2, 12, 0}, // ' '
{0, 0, 0}, // '!'
{0, 0, 0}, // '"'
{0, 0, 0}, // '#'
{0, 0, 0}, // '$'
{0, 0, 0}, // '%'
{0, 0, 0}, // '&'
{0, 0, 0}, // '''
{0, 0, 0}, // '('
{0, 0, 0}, // ')'
{0, 0, 0}, // '*'
{0, 0, 0}, // '+'
{0, 0, 0}, // ','
{2, 5, 4}, // '-'
{1, 7, 6}, // '.'
{0, 0, 0}, // '/'
{5, 7, 7}, // '0'
{2, 7, 12}, // '1'
{5, 7, 14}, // '2'
{5, 7, 19}, // '3'
{5, 6, 24}, // '4'
{5, 7, 29}, // '5'
{4, 7, 34}, // '6'
{4, 7, 38}, // '7'
{5, 7, 42}, // '8'
{5, 7, 47}, // '9'
{2, 5, 52}, // ':'
{0, 0, 0}, // ';'
{0, 0, 0}, // '<'
{0, 0, 0}, // '='
{0, 0, 0}, // '>'
{0, 0, 0}, // '?'
{0, 0, 0}, // '@'
{0, 0, 0}, // 'A'
{0, 0, 0}, // 'B'
{5, 7, 54}, // 'C'
{0, 0, 0}, // 'D'
{0, 0, 0}, // 'E'
{5, 7, 59}, // 'F'
{0, 0, 0}, // 'G'
{0, 0, 0}, // 'H'
{0, 0, 0}, // 'I'
{0, 0, 0}, // 'J'
{0, 0, 0}, // 'K'
{0, 0, 0}, // 'L'
{0, 0, 0}, // 'M'
{0, 0, 0}, // 'N'
{0, 0, 0}, // 'O'
{0, 0, 0}, // 'P'
{0, 0, 0}, // 'Q'
{0, 0, 0}, // 'R'
{0, 0, 0}, // 'S'
{0, 0, 0}, // 'T'
{0, 0, 0}, // 'U'
{5, 7, 64}, // 'V'
{0, 0, 0}, // 'W'
{0, 0, 0}, // 'X'
{0, 0, 0}, // 'Y'
{0, 0, 0}, // 'Z'
{0, 0, 0}, // '['
{0, 0, 0}, // '\'
{0, 0, 0}, // ']'
{0, 0, 0}, // '^'
{0, 0, 0}, // '_'
{2, 2, 69}, // '`'
};
// Font information for Segoe UI 7pt
const FONT_INFO segoeUI_Italic_7ptFontInfo =
{
12, // Character height
' ', // Start character
'`', // End character
1,
segoeUI_Italic_7ptDescriptors, // Character descriptor array
segoeUI_Italic_7ptBitmaps, // Character bitmap array
};

View file

@ -22,8 +22,9 @@
#include <Arduino.h>
#include "Protocol.h"
#include "../Utility/DebugPort.h"
#include "helpers.h"
#include "../Utility/helpers.h"
#include "../cfg/BTCConfig.h"
#include "../Utility/macros.h"
unsigned short
@ -252,7 +253,7 @@ CProtocol::Init(int FrameMode)
Controller.Len = 22;
Controller.Command = 0; // NOP
setTemperature_Actual(18); // 1degC / digit
setTemperature_Desired(20); // 1degC / digit
setHeaterDemand(20); // 1degC / digit
setPump_Min(1.4f); // Hz
setPump_Max(4.3f); // Hz
setFan_Min(1450); // 1RPM / digit

View file

@ -34,7 +34,7 @@ public:
unsigned char Len; // [1] always 0x16 == 22
unsigned char Command; // [2] transient commands: 00: NOP, 0xa0 START, 0x05: STOP
unsigned char ActualTemperature; // [3] 1degC / digit
unsigned char DesiredTemperature; // [4] 1degC / digit
unsigned char DesiredDemand; // [4] typ. 1degC / digit, but also gets used for Fixed Hx demand too!
unsigned char MinPumpFreq; // [5] 0.1Hz/digit
unsigned char MaxPumpFreq; // [6] 0.1Hz/digit
unsigned char MinFanRPM_MSB; // [7] 16 bit - big endian MSB
@ -175,11 +175,11 @@ public:
float getPump_Fixed() const { return float(Heater.FixedPumpFreq) * 0.1f; }; // Fixed mode pump frequency
void setPump_Prime(bool on) { Controller.Prime = on ? 0x5A : 0; };
// temperature set/get
void setTemperature_Desired(unsigned char degC) { Controller.DesiredTemperature = degC; };
void setHeaterDemand(unsigned char degC) { Controller.DesiredDemand = degC; };
void setTemperature_Min(unsigned char degC) { Controller.MinTemperature = degC; };
void setTemperature_Max(unsigned char degC) { Controller.MaxTemperature = degC; };
void setTemperature_Actual(unsigned char degC) { Controller.ActualTemperature = degC; };
unsigned char getTemperature_Desired() const { return Controller.DesiredTemperature; };
unsigned char getHeaterDemand() const { return Controller.DesiredDemand; };
unsigned char getTemperature_Min() const { return Controller.MinTemperature; };
unsigned char getTemperature_Max() const { return Controller.MaxTemperature; };
unsigned char getTemperature_Actual() const { return Controller.ActualTemperature; };
@ -224,7 +224,7 @@ public:
const char* getErrStateStrEx() const;
float getBattVoltage() const { return Heater.getVoltage_Supply(); };
bool isThermostat() const { return Controller.isThermostat(); };
float getTemperature_Desired() const { return float(Controller.getTemperature_Desired()); };
float getHeaterDemand() const { return float(Controller.getHeaterDemand()); };
float getTemperature_HeatExchg() const { return float(Heater.getTemperature_HeatExchg()); };
float getTemperature_Min() const { return float(Controller.getTemperature_Min()); };
float getTemperature_Max() const { return float(Controller.getTemperature_Max()); };
@ -247,5 +247,6 @@ public:
void reportFrames(bool isOEM);
};
extern const CProtocolPackage& getHeaterInfo();
#endif

View file

@ -21,7 +21,7 @@
#include "TxManage.h"
#include "../Utility/NVStorage.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
//#define DEBUG_THERMOSTAT
@ -125,15 +125,21 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
m_TxFrame.setPump_Max(NVstore.getHeaterTuning().getPmax());
float tActual = getTemperatureSensor();
uint8_t u8Temp = (uint8_t)(tActual);
uint8_t u8Temp = (uint8_t)(tActual + 0.5);
m_TxFrame.setTemperature_Actual(u8Temp); // use current temp, for now
m_TxFrame.setTemperature_Desired(NVstore.getUserSettings().desiredTemperature);
m_TxFrame.setHeaterDemand(NVstore.getUserSettings().demandDegC);
m_TxFrame.setThermostatModeProtocol(1); // assume using thermostat control for now
if(NVstore.getUserSettings().ThermostatMethod) {
if(!getThermostatModeActive()) {
m_TxFrame.setThermostatModeProtocol(0); // not using any form of thermostat control
m_TxFrame.setHeaterDemand(NVstore.getUserSettings().demandPump); // set fixed Hz demand instead
m_TxFrame.setTemperature_Actual(0); // must force actual to 0 for Hz mode
}
else if(NVstore.getUserSettings().ThermostatMethod) {
uint8_t ThermoMode = NVstore.getUserSettings().ThermostatMethod; // get the METHOD of thermostat control
float Window = NVstore.getUserSettings().ThermostatWindow;
float tCurrent = getTemperatureSensor();
float tDesired = float(NVstore.getUserSettings().desiredTemperature);
float tDesired = float(NVstore.getUserSettings().demandDegC);
float tDelta = tCurrent - tDesired;
float fTemp;
#ifdef DEBUG_THERMOSTAT
@ -157,11 +163,11 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
u8Temp = (uint8_t)(tActual + 0.5); // use rounded actual unless within window
if(fabs(tDelta) < Window) {
// hold at desired if inside window
u8Temp = NVstore.getUserSettings().desiredTemperature;
u8Temp = NVstore.getUserSettings().demandDegC;
}
else if(fabs(tDelta) <= 1.0) {
// force outside if delta is <= 1 but greater than window
u8Temp = NVstore.getUserSettings().desiredTemperature + ((tDelta > 0) ? 1 : -1);
u8Temp = NVstore.getUserSettings().demandDegC + ((tDelta > 0) ? 1 : -1);
}
m_TxFrame.setTemperature_Actual(u8Temp);
#ifdef DEBUG_THERMOSTAT
@ -185,7 +191,7 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
UPPERLIMIT(fTemp, m_TxFrame.getTemperature_Max());
// apply modifed desired temperature (works in conjunction with thermostatmode = 0!)
u8Temp = (uint8_t)(fTemp + 0.5);
m_TxFrame.setTemperature_Desired(u8Temp);
m_TxFrame.setHeaterDemand(u8Temp);
m_TxFrame.setThermostatModeProtocol(0); // direct heater to use Hz Mode
m_TxFrame.setTemperature_Actual(0); // must force actual to 0 for Hz mode
#ifdef DEBUG_THERMOSTAT
@ -194,10 +200,6 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
break;
}
}
else {
m_TxFrame.setThermostatModeProtocol(0); // not using any form of thermostat control
m_TxFrame.setTemperature_Actual(0); // must force actual to 0 for Hz mode
}
// m_TxFrame.setThermostatMode(NVstore.getThermostatMode());
m_TxFrame.Controller.OperatingVoltage = NVstore.getHeaterTuning().sysVoltage;

View file

@ -20,7 +20,7 @@
*/
#include "BTCDateTime.h"
#include "../Protocol/helpers.h"
#include "../Utility/macros.h"
const char*
BTCDateTime::dowStr() const

View file

@ -25,7 +25,7 @@
#include "TimerManager.h"
#include <Wire.h>
#include <RTClib.h>
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../Utility/NVStorage.h"
#include "../Utility/DebugPort.h"

View file

@ -32,7 +32,7 @@
#include "TimerManager.h"
#include "Clock.h"
#include "../Utility/NVStorage.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
uint8_t CTimerManager::weekTimerIDs[7][CTimerManager::_dayMinutes]; // b[7] = repeat flag, b[3..0] = timer ID

View file

@ -22,6 +22,7 @@
#include <Arduino.h>
#include "Timers.h"
#include "../Utility/NVStorage.h"
#include "../Utility/macros.h"
#include "BTCDateTime.h"
@ -32,7 +33,7 @@ void decodeJSONTimerDays(const char* ipStr)
if(2 == sscanf(ipStr, "%d %31s", &timerIdx, dayInfo)) {
dayInfo[31] = 0;
timerIdx--;
if(timerIdx >= 0 && timerIdx < 14) {
if(INBOUNDS(timerIdx, 0, 13)) {
sTimer timer;
NVstore.getTimerInfo(timerIdx, timer);
unsigned char days = 0;
@ -59,7 +60,7 @@ void decodeJSONTimerTime(int stop, const char* ipStr)
int timerIdx;
if(3 == sscanf(ipStr, "%d %d:%d", &timerIdx, &hour, &min)) {
timerIdx--;
if(timerIdx >= 0 && timerIdx < 14) {
if(INBOUNDS(timerIdx, 0, 13)) {
sTimer timer;
NVstore.getTimerInfo(timerIdx, timer);
if(stop) {
@ -81,7 +82,7 @@ void decodeJSONTimerNumeric(int valID, const char* ipStr)
int timerIdx;
if(2 == sscanf(ipStr, "%d %d", &timerIdx, &value)) {
timerIdx--;
if(timerIdx >= 0 && timerIdx < 14) {
if(INBOUNDS(timerIdx, 0, 13)) {
sTimer timer;
NVstore.getTimerInfo(timerIdx, timer);
switch(valID) {
@ -99,7 +100,7 @@ void decodeTimerTemp(const char* ipStr)
int timerIdx;
if(2 == sscanf(ipStr, "%d %d", &timerIdx, &degC)) {
timerIdx--;
if(timerIdx >= 0 && timerIdx < 14) {
if(INBOUNDS(timerIdx, 0, 13)) {
sTimer timer;
NVstore.getTimerInfo(timerIdx, timer);
timer.temperature = degC;

View file

@ -23,6 +23,7 @@
#define __BTC_TIMERS_H__
#include "../Utility/NVCore.h"
#include "../Utility/macros.h"
struct sHourMin {
@ -73,12 +74,12 @@ struct sTimer : public CESP32_NVStorage {
}
bool valid() {
bool retval = true;
retval &= (start.hour >= 0 && start.hour < 24);
retval &= (start.min >= 0 && start.min < 60);
retval &= (stop.hour >= 0 && stop.hour < 24);
retval &= (stop.min >= 0 && stop.min < 60);
retval &= INBOUNDS(start.hour, 0, 23);
retval &= INBOUNDS(start.min, 0, 59);
retval &= INBOUNDS(stop.hour, 0, 23);
retval &= INBOUNDS(stop.min, 0, 59);
retval &= repeat <= 2;
retval &= (temperature >= 8 && temperature <= 35);
retval &= INBOUNDS(temperature, 8, 35);
return retval;
}
void load();

View file

@ -21,7 +21,6 @@
#include "BTC_JSON.h"
#include "DebugPort.h"
#include "../Protocol/helpers.h"
#include "NVstorage.h"
#include "../RTC/BTCDateTime.h"
#include "../RTC/Timers.h"
@ -29,6 +28,8 @@
#include "../Bluetooth/BluetoothAbstract.h"
#include "../WiFi/BTCWebServer.h"
#include "../cfg/BTCConfig.h"
#include "macros.h"
#include "../Protocol/Protocol.h"
char defaultJSONstr[64];
@ -104,7 +105,7 @@ void interpretJsonCommand(char* pLine)
else if(strcmp("ThermostatWindow", it->key) == 0) {
sUserSettings settings = NVstore.getUserSettings();
float val = it->value.as<float>();
if(val >= 0.2f && val <= 10.f)
if(INBOUNDS(val, 0.2f, 10.f))
settings.ThermostatWindow = val;
NVstore.setUserSettings(settings);
}
@ -215,13 +216,23 @@ void interpretJsonCommand(char* pLine)
else if(strcmp("GPin2", it->key) == 0) {
simulateGPIOin(it->value.as<unsigned char>() ? 0x02 : 0x00); // simulate key 2 press
}
}
else if(strcmp("JSONloose", it->key) == 0) {
sUserSettings us = NVstore.getUserSettings();
uint8_t loose = it->value.as<unsigned char>() ? 0x01 : 0x00;
us.JSON.LF = loose;
us.JSON.padding = loose;
us.JSON.singleElement = loose;
NVstore.setUserSettings(us);
NVstore.save();
resetJSONmoderator();
}
}
}
void validateTimer(int ID)
{
ID--; // supplied as +1
if(!(ID >= 0 && ID < 14))
if(!INBOUNDS(ID, 0, 13))
return;
timerConflict = CTimerManager::conflictTest(ID); // check targeted timer against other timers
@ -293,20 +304,6 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len)
return bSend;
}
/*bool makeJSONStringGPIO(const sGPIO& GPIOinfo, char* opStr, int len)
{
StaticJsonBuffer<800> jsonBuffer; // create a JSON buffer on the stack
JsonObject& root = jsonBuffer.createObject(); // create object to add JSON commands to
bool bSend = GPIOmoderator.addJson(GPIOinfo, root);
if(bSend) {
root.printTo(opStr, len);
}
return bSend;
}*/
// the way the JSON timer strings are crafted, we have to iterate over each timer's parameters
// individually, the JSON name is always the same for each timer, the payload IDs the specific
// timer
@ -441,9 +438,9 @@ void updateJSONclients(bool report)
DebugPort.printf("JSON send: %s\r\n", jsonStr);
sendWebServerString( jsonStr );
std::string expand = jsonStr;
Expand(expand);
getBluetoothClient().send( expand.c_str() );
std::string expand = jsonStr;
Expand(expand);
getBluetoothClient().send( expand.c_str() );
}
// report MQTT params
@ -502,11 +499,26 @@ void initTimerJSONmoderator()
void Expand(std::string& str)
{
size_t pos = str.find(",\"");
while(pos != std::string::npos) {
str.replace(pos, 2, "}\n{\"");
pos = str.find(",\"");
const sUserSettings& userOptions = NVstore.getUserSettings();
if(userOptions.JSON.singleElement) {
size_t pos = str.find(",\"");
while(pos != std::string::npos) {
if(userOptions.JSON.LF)
str.replace(pos, 2, "}\n{\""); // converts {"name":value,"name2":value"} to {"name":value}\n{"name2":value}
else
str.replace(pos, 2, "}{\""); // converts {"name":value,"name2":value"} to {"name":value}{"name2":value}
pos = str.find(",\"");
}
if(userOptions.JSON.padding) { // converts {"name":value} to {"name": value}
pos = str.find("\":");
while(pos != std::string::npos) {
str.replace(pos, 2, "\": ");
pos = str.find("\":", pos+1);
}
}
if(userOptions.JSON.LF)
str.append("\n");
}
str.append("\n");
}

View file

@ -20,9 +20,10 @@
*/
#include "GPIO.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include <driver/adc.h>
#include "DebugPort.h"
#include "../Protocol/Protocol.h"
const int BREATHINTERVAL = 45;
const int FADEAMOUNT = 3;

View file

@ -21,7 +21,7 @@
#include "Moderator.h"
#include "DebugPort.h"
//#include "NVStorage.h"
#include "../Utility/helpers.h"
CTimerModerator::CTimerModerator()
{
@ -89,7 +89,7 @@ CTimerModerator::reset()
void
CTimerModerator::reset(int timer)
{
if(timer >= 0 && timer < 14) {
if(INBOUNDS(timer, 0, 13)) {
Memory[timer].start.hour = -1; // force full update
Memory[timer].stop.hour = -1; // force full update
Memory[timer].enabled = 0xff; // invalid combination - force full update

View file

@ -126,12 +126,12 @@ CESP32_NVStorage::validatedLoad(const char* key, float& val, float defVal, float
bool u8inBounds(uint8_t test, uint8_t minLim, uint8_t maxLim)
{
return (test >= minLim) && (test <= maxLim);
return INBOUNDS(test, minLim, maxLim);
}
bool s8inBounds(int8_t test, int8_t minLim, int8_t maxLim)
{
return (test >= minLim) && (test <= maxLim);
return INBOUNDS(test, minLim, maxLim);
}
bool u8Match2(uint8_t test, uint8_t test1, uint8_t test2)
@ -141,6 +141,6 @@ bool u8Match2(uint8_t test, uint8_t test1, uint8_t test2)
bool u16inBounds(uint16_t test, uint16_t minLim, uint16_t maxLim)
{
return (test >= minLim) && (test <= maxLim);
return INBOUNDS(test, minLim, maxLim);
}

View file

@ -97,7 +97,7 @@ sHeaterTuning::setSysVoltage(float fVal)
void
CHeaterStorage::getTimerInfo(int idx, sTimer& timerInfo)
{
if(idx >= 0 && idx < 14) {
if(INBOUNDS(idx, 0, 13)) {
timerInfo = _calValues.timer[idx];
}
}
@ -105,7 +105,7 @@ CHeaterStorage::getTimerInfo(int idx, sTimer& timerInfo)
void
CHeaterStorage::setTimerInfo(int idx, const sTimer& timerInfo)
{
if(idx >= 0 && idx < 14) {
if(INBOUNDS(idx, 0, 13)) {
_calValues.timer[idx] = timerInfo;
}
}
@ -322,7 +322,8 @@ sUserSettings::load()
validatedLoad("menuTimeout", menuTimeout, 60000, 0, 300000);
validatedLoad("degF", degF, 0, u8inBounds, 0, 1);
validatedLoad("thermostat", useThermostat, 1, u8inBounds, 0, 1);
validatedLoad("setTemperature", desiredTemperature, 22, u8inBounds, 0, 40);
validatedLoad("demandDegC", demandDegC, 22, u8inBounds, 8, 35);
validatedLoad("demandPump", demandPump, 22, u8inBounds, 8, 35);
validatedLoad("thermoMethod", ThermostatMethod, 0, u8inBounds, 0, 255);
// catch and migrate old combined method & window
if(ThermostatMethod & 0xFC) {
@ -344,6 +345,9 @@ sUserSettings::load()
validatedLoad("MenuonStart", HomeMenu.onStart, 0, u8inBounds, 0, 3);
validatedLoad("MenuonStop", HomeMenu.onStop, 0, u8inBounds, 0, 3);
validatedLoad("FrameRate", FrameRate, 1000, u16inBounds, 300, 1500);
validatedLoad("JSONsingle", JSON.singleElement, 0, u8inBounds, 0, 1);
validatedLoad("JSONLF", JSON.LF, 0, u8inBounds, 0, 1);
validatedLoad("JSONpad", JSON.padding, 0, u8inBounds, 0, 1);
preferences.end();
}
@ -355,7 +359,8 @@ sUserSettings::save()
preferences.putLong("dimTime", dimTime);
preferences.putLong("menuTimeout", menuTimeout);
preferences.putUChar("thermostat", useThermostat);
preferences.putUChar("setTemperature", desiredTemperature);
preferences.putUChar("demandDegC", demandDegC);
preferences.putUChar("demandPump", demandPump);
preferences.putUChar("degF", degF);
preferences.putUChar("thermoMethod", ThermostatMethod);
preferences.putFloat("thermoWindow", ThermostatWindow);
@ -370,6 +375,9 @@ sUserSettings::save()
preferences.putUChar("MenuonStart", HomeMenu.onStart);
preferences.putUChar("MenuonStop", HomeMenu.onStop);
preferences.putUShort("FrameRate", FrameRate);
preferences.putUChar("JSONsingle", JSON.singleElement);
preferences.putUChar("JSONLF", JSON.LF);
preferences.putUChar("JSONpad", JSON.padding);
preferences.end();
}

View file

@ -24,6 +24,7 @@
#include "GPIO.h"
#include "NVCore.h"
#include "../Utility/helpers.h"
#include "../RTC/Timers.h" // for sTimer
@ -48,7 +49,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
retval &= Fmax < 6000;
retval &= sysVoltage == 120 || sysVoltage == 240;
retval &= fanSensor == 1 || fanSensor == 2;
retval &= glowDrive >= 1 && glowDrive <= 6;
retval &= INBOUNDS(glowDrive, 1, 6);
return retval;
};
void init() {
@ -108,8 +109,8 @@ struct sCyclicThermostat {
int8_t Start;
bool valid() {
bool retval = true;
retval &= Start >= -10 && Start <= 0;
retval &= Stop >= 0 && Stop <= 10;
retval &= INBOUNDS(Start, -10, 0);
retval &= INBOUNDS(Stop, 0, 10);
return retval;
}
void init() {
@ -126,6 +127,32 @@ struct sCyclicThermostat {
}
};
struct sJSONoptions {
int8_t singleElement;
int8_t LF;
int8_t padding;
bool valid() {
bool retval = true;
retval &= singleElement <= 1;
retval &= LF <= 1;
retval &= padding <= 1;
return retval;
}
void init() {
singleElement = 0;
LF = 0;
padding = 0;
}
sJSONoptions& operator=(const sJSONoptions& rhs) {
singleElement = rhs.singleElement;
LF = rhs.LF;
padding = rhs.padding;
return *this;
}
};
struct sCredentials : public CESP32_NVStorage {
char SSID[32];
char APpassword[32];
@ -181,7 +208,8 @@ struct sMQTTparams : public CESP32_NVStorage {
struct sUserSettings : public CESP32_NVStorage {
long dimTime;
long menuTimeout;
uint8_t desiredTemperature;
uint8_t demandDegC;
uint8_t demandPump;
uint8_t degF;
uint8_t ThermostatMethod; // 0: standard heater, 1: Narrow Hysterisis, 2:Managed Hz mode
float ThermostatWindow;
@ -192,29 +220,33 @@ struct sUserSettings : public CESP32_NVStorage {
sCyclicThermostat cyclic;
sHomeMenuActions HomeMenu;
sGPIOparams GPIO;
sJSONoptions JSON;
bool valid() {
bool retval = true;
retval &= (dimTime >= -600000) && (dimTime < 600000); // +/- 10 mins
retval &= (menuTimeout >= 0) && (menuTimeout < 300000); // 5 mins
retval &= desiredTemperature < 40;
retval &= INBOUNDS(dimTime, -600000, 600000); // +/- 10 mins
retval &= INBOUNDS(menuTimeout, 0, 300000); // 5 mins
retval &= INBOUNDS(demandDegC, 8, 35);
retval &= INBOUNDS(demandPump, 8, 35);
retval &= (degF == 0) || (degF == 1);
retval &= (ThermostatMethod & 0x03) < 3; // only modes 0, 1 or 2
retval &= (ThermostatWindow >= 0.2f) && (ThermostatWindow <= 10.f);
retval &= INBOUNDS(ThermostatWindow, 0.2f, 10.f);
retval &= useThermostat < 2;
retval &= (enableWifi == 0) || (enableWifi == 1);
retval &= (enableOTA == 0) || (enableOTA == 1);
retval &= GPIO.inMode < 4;
retval &= GPIO.outMode < 3;
retval &= (FrameRate >= 300) && (FrameRate <= 1500);
retval &= INBOUNDS(FrameRate, 300, 1500);
retval &= cyclic.valid();
retval &= HomeMenu.valid();
retval &= JSON.valid();
return retval;
}
void init() {
dimTime = 60000;
menuTimeout = 60000;
desiredTemperature = 23;
demandDegC = 22;
demandPump = 22;
degF = 0;
ThermostatMethod = 0;
ThermostatWindow = 1.0;
@ -227,13 +259,15 @@ struct sUserSettings : public CESP32_NVStorage {
FrameRate = 1000;
cyclic.init();
HomeMenu.init();
JSON.init();
};
void load();
void save();
sUserSettings& operator=(const sUserSettings& rhs) {
dimTime = rhs.dimTime;
menuTimeout = rhs.menuTimeout;
desiredTemperature = rhs.desiredTemperature;
demandDegC = rhs.demandDegC;
demandPump = rhs.demandPump;
degF = rhs.degF;
ThermostatMethod = rhs.ThermostatMethod;
ThermostatWindow = rhs.ThermostatWindow;
@ -246,6 +280,7 @@ struct sUserSettings : public CESP32_NVStorage {
FrameRate = rhs.FrameRate;
cyclic = rhs.cyclic;
HomeMenu = rhs.HomeMenu;
JSON = rhs.JSON;
return *this;
}
};

View file

@ -23,13 +23,11 @@
#ifndef __BTC_HELPERS_H__
#define __BTC_HELPERS_H__
#include "Protocol.h"
#include "../Utility/UtilClasses.h"
#include "UtilClasses.h"
struct sGPIO;
extern void ToggleOnOff();
extern void requestOn();
extern void requestOff();
extern bool reqTempDelta(int delta);
@ -40,7 +38,6 @@ extern bool getThermostatModeActive(); // OEM: actual mode from blue wire, BTC
extern void reqPumpPrime(bool on);
float getTemperatureDesired(); // OEM: the advertised value, BTC our setpoint
extern float getTemperatureSensor();
extern int getSetTemp();
extern void setPumpMin(float);
extern void setPumpMax(float);
extern void setFanMin(short);
@ -52,7 +49,6 @@ extern void setTime(const char* newTime);
extern void setGlowDrive(unsigned char val);
extern void saveNV();
extern void setSystemVoltage(float val);
extern const CProtocolPackage& getHeaterInfo();
extern void interpretJsonCommand(char* pLine);
extern void resetWebModerator();
extern void resetJSONmoderator();
@ -82,13 +78,4 @@ extern void setDegFMode(bool state);
extern void ShowOTAScreen(int percent=0, eOTAmodes updateType=eOTAnormal);
#define LOWERLIMIT(A, B) if((A) < (B)) (A) = (B)
#define UPPERLIMIT(A, B) if((A) > (B)) (A) = (B)
#define WRAPUPPERLIMIT(A, B, C) if((A) > (B)) (A) = (C)
#define WRAPLOWERLIMIT(A, B, C) if((A) < (B)) (A) = (C)
#define WRAPLIMITS(A, B, C) if((A) < (B)) (A) = (C) ; if((A) > (C)) (A) = (B)
#define INBOUNDS(TST, MIN, MAX) (((TST) >= (MIN)) && ((tst) <= (MAX)))
#endif

View file

@ -0,0 +1,33 @@
/*
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2018 James Clark
*
* 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 __MACROS_H__
#define __MACROS_H__
#define LOWERLIMIT(A, B) if((A) < (B)) (A) = (B)
#define UPPERLIMIT(A, B) if((A) > (B)) (A) = (B)
#define WRAPUPPERLIMIT(A, B, C) if((A) > (B)) (A) = (C)
#define WRAPLOWERLIMIT(A, B, C) if((A) < (B)) (A) = (C)
#define WRAPLIMITS(A, B, C) if((A) < (B)) (A) = (C) ; if((A) > (C)) (A) = (B)
#define INBOUNDS(TST, MIN, MAX) (((TST) >= (MIN)) && ((TST) <= (MAX)))
#endif

View file

@ -25,7 +25,7 @@
#include "BTCWebServer.h"
#include "../Utility/DebugPort.h"
#include "../Protocol/TxManage.h"
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
#include "../cfg/pins.h"
#include "../cfg/BTCConfig.h"
#include "Index.h"

View file

@ -25,7 +25,7 @@
#include <SPIFFS.h>
#endif
#include "../Libraries/esp32FOTA/src/esp32fota.h" // local copy used due to a couple of issues
#include "../Protocol/helpers.h"
#include "../Utility/helpers.h"
esp32FOTA FOTA("afterburner-fota-http", int(getVersion()*1000));