Merge branch 'FuelGauge'
4
.gitignore
vendored
|
@ -21,3 +21,7 @@ Arduino/Afterburner/src/*
|
|||
/Releases
|
||||
/webdev
|
||||
/case
|
||||
/DieselHeaterV2.PcbDoc
|
||||
/StandardResponse.txt
|
||||
/HeaterHack-Tested.zip
|
||||
/OTA_COM.txt
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include "src/Utility/helpers.h"
|
||||
#include "src/Utility/NVStorage.h"
|
||||
#include "src/Utility/DebugPort.h"
|
||||
#include "src/Utility/macros.h"
|
||||
#include "src/Utility/UtilClasses.h"
|
||||
#include "src/Utility/BTC_JSON.h"
|
||||
#include "src/Utility/BTC_GPIO.h"
|
||||
|
@ -446,6 +447,10 @@ void setup() {
|
|||
FilteredSamples.Fan.setRounding(10);
|
||||
FilteredSamples.Fan.setAlpha(0.7);
|
||||
FilteredSamples.AmbientTemp.reset(-100.0);
|
||||
FilteredSamples.FastipVolts.setRounding(0.1);
|
||||
FilteredSamples.FastipVolts.setAlpha(0.7);
|
||||
FilteredSamples.FastGlowAmps.setRounding(0.01);
|
||||
FilteredSamples.FastGlowAmps.setAlpha(0.7);
|
||||
|
||||
RTC_Store.begin();
|
||||
FuelGauge.init(RTC_Store.getFuelGauge());
|
||||
|
@ -792,9 +797,24 @@ void loop()
|
|||
|
||||
ScreenManager.reqUpdate();
|
||||
}
|
||||
|
||||
if(bHasHtrData) {
|
||||
// apply exponential mean to the anlogue readings for some smoothing
|
||||
updateFilteredData();
|
||||
FuelGauge.Integrate(HeaterFrame2.getPump_Actual());
|
||||
|
||||
// integrate fuel pump activity for fuel gauge
|
||||
FuelGauge.Integrate(getHeaterInfo().getPump_Actual());
|
||||
|
||||
// test for low volts shutdown during normal run
|
||||
if(INBOUNDS(getHeaterInfo().getRunState(), 1, 5)) { // check for Low Voltage Cutout
|
||||
SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
|
||||
}
|
||||
|
||||
// trap being in state 0 with a heater error - cancel user on memory to avoid unexpected cyclic restarts
|
||||
if(RTC_Store.getCyclicEngaged() && (getHeaterInfo().getRunState() == 0) && (getHeaterInfo().getErrState() > 1)) {
|
||||
DebugPort.println("Forcing cyclic cancel due to error induced shutdown");
|
||||
RTC_Store.setCyclicEngaged(false);
|
||||
}
|
||||
}
|
||||
updateJSONclients(bReportJSONData);
|
||||
CommState.set(CommStates::Idle);
|
||||
|
@ -822,7 +842,7 @@ void manageCyclicMode()
|
|||
const sCyclicThermostat& cyclic = NVstore.getUserSettings().cyclic;
|
||||
if(cyclic.Stop && RTC_Store.getCyclicEngaged()) { // cyclic mode enabled, and user has started heater
|
||||
int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over!
|
||||
float deltaT = FilteredSamples.AmbientTemp.getValue() - getDemandDegC();
|
||||
float deltaT = getTemperatureSensor() - getDemandDegC();
|
||||
// DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT);
|
||||
|
||||
// ensure we cancel user ON mode if heater throws an error
|
||||
|
@ -883,9 +903,11 @@ bool validateFrame(const CProtocol& frame, const char* name)
|
|||
|
||||
void requestOn()
|
||||
{
|
||||
if(SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue())) {
|
||||
heaterOn();
|
||||
RTC_Store.setCyclicEngaged(true); // for cyclic mode
|
||||
}
|
||||
}
|
||||
|
||||
void requestOff()
|
||||
{
|
||||
|
@ -1041,7 +1063,7 @@ float getTemperatureDesired()
|
|||
|
||||
float getTemperatureSensor()
|
||||
{
|
||||
return FilteredSamples.AmbientTemp.getValue();
|
||||
return FilteredSamples.AmbientTemp.getValue() + NVstore.getHeaterTuning().tempOfs;
|
||||
}
|
||||
|
||||
void setPumpMin(float val)
|
||||
|
@ -1449,11 +1471,14 @@ void simulateGPIOin(uint8_t newKey)
|
|||
GPIOin.simulateKey(newKey);
|
||||
}
|
||||
|
||||
float getBatteryVoltage()
|
||||
float getBatteryVoltage(bool fast)
|
||||
{
|
||||
#ifdef RAW_SAMPLES
|
||||
return getHeaterInfo().getBattVoltage();
|
||||
#else
|
||||
if(fast)
|
||||
return FilteredSamples.FastipVolts.getValue();
|
||||
else
|
||||
return FilteredSamples.ipVolts.getValue();
|
||||
#endif
|
||||
}
|
||||
|
@ -1487,13 +1512,16 @@ float getFanSpeed()
|
|||
|
||||
void updateFilteredData()
|
||||
{
|
||||
FilteredSamples.ipVolts.update(HeaterFrame2.getVoltage_Supply());
|
||||
FilteredSamples.GlowVolts.update(HeaterFrame2.getGlowPlug_Voltage());
|
||||
FilteredSamples.GlowAmps.update(HeaterFrame2.getGlowPlug_Current());
|
||||
FilteredSamples.Fan.update(HeaterFrame2.getFan_Actual());
|
||||
FilteredSamples.ipVolts.update(getHeaterInfo().getBattVoltage());
|
||||
FilteredSamples.GlowVolts.update(getHeaterInfo().getGlow_Voltage());
|
||||
FilteredSamples.GlowAmps.update(getHeaterInfo().getGlow_Current());
|
||||
FilteredSamples.Fan.update(getHeaterInfo().getFan_Actual());
|
||||
FilteredSamples.FastipVolts.update(getHeaterInfo().getBattVoltage());
|
||||
FilteredSamples.FastGlowAmps.update(getHeaterInfo().getGlow_Current());
|
||||
}
|
||||
|
||||
int sysUptime()
|
||||
{
|
||||
return Clock.get().secondstime() - BootTime;
|
||||
}
|
||||
|
||||
|
|
10
Partitions.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
PLATFORMIO MIN_SPIFFS PARTITION ARDUINO MIN_SPIFFS PARTITION
|
||||
|
||||
# Name, Type, SubType, Offset, Size, Flags # Name, Type, SubType, Offset, Size, Flags
|
||||
Same nvs, data, nvs, 0x9000, 0x5000, nvs, data, nvs, 0x9000, 0x5000,
|
||||
Same otadata, data, ota, 0xe000, 0x2000, otadata, data, ota, 0xe000, 0x2000,
|
||||
Same app0, app, ota_0, 0x10000, 0x1E0000, app0, app, ota_0, 0x10000, 0x1E0000,
|
||||
Same app1, app, ota_1, 0x1F0000,0x1E0000, app1, app, ota_1, 0x1F0000,0x1E0000,
|
||||
Diff eeprom, data, 0x99, 0x3D0000,0x1000, spiffs, data, spiffs, 0x3D0000,0x30000,
|
||||
Diff spiffs, data, spiffs, 0x3D1000,0x2F000,
|
|
@ -51,15 +51,15 @@ Working so far:
|
|||
Web browser upload new binary to controller (AP or STA mode)
|
||||
Direct discovery and download of updates from internet server (STA mode)
|
||||
* Factory default menu option
|
||||
* "Fuel gauge" - Integrates pump frequency, assumes a repeatable dose of fuel per pump stroke.
|
||||
* Low voltage cut out, definable threshold - auto adjusts for cable voltage drop during start
|
||||
* Temperature probe offset to correct adverse readings.
|
||||
|
||||
|
||||
To be implemented
|
||||
--------------------------
|
||||
* 433MHz Rx stream, 433MHz Tx stream connections. This would allow external timer units for example, or analogue temperature demand (which is still only 1 degree resolution with standard heater thermostat).
|
||||
* Low voltage cut out
|
||||
* Temperature probe offset or mapping to correct adverse readings.
|
||||
* MQTT pub/sub
|
||||
* "fuel gauge" - Integrate pump frequency, assuming a repeatable dose of fuel per pump cycle...
|
||||
* Regular Hot Burn cycle (DPF mode!)
|
||||
* Hour meter - run time, glow time
|
||||
* list under construction.....
|
||||
|
|
Before Width: | Height: | Size: 102 B After Width: | Height: | Size: 198 B |
BIN
icons/DegC.bmp
Normal file
After Width: | Height: | Size: 262 B |
BIN
icons/DegF.bmp
Normal file
After Width: | Height: | Size: 226 B |
Before Width: | Height: | Size: 126 B After Width: | Height: | Size: 110 B |
BIN
icons/FuelIconSmall.bmp
Normal file
After Width: | Height: | Size: 154 B |
BIN
icons/Reset.bmp
Normal file
After Width: | Height: | Size: 238 B |
BIN
icons/ThermostatC.bmp
Normal file
After Width: | Height: | Size: 274 B |
BIN
icons/ThermostatF.bmp
Normal file
After Width: | Height: | Size: 274 B |
BIN
icons/ThermostatHz.bmp
Normal file
After Width: | Height: | Size: 274 B |
|
@ -11,6 +11,7 @@
|
|||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
lib_extra_dirs = ~/Documents/Arduino/libraries
|
||||
;lib_dir = src/Afterburner/src
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
@ -22,5 +23,6 @@ upload_flags =
|
|||
monitor_speed = 115200
|
||||
extra_scripts = post:add_CRC.py
|
||||
; replace shitty Arduino millis with a linear time version
|
||||
build_flags = -Wl,--wrap,millis
|
||||
build_flags =
|
||||
-Wl,--wrap,millis
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include "src/Utility/helpers.h"
|
||||
#include "src/Utility/NVStorage.h"
|
||||
#include "src/Utility/DebugPort.h"
|
||||
#include "src/Utility/macros.h"
|
||||
#include "src/Utility/UtilClasses.h"
|
||||
#include "src/Utility/BTC_JSON.h"
|
||||
#include "src/Utility/BTC_GPIO.h"
|
||||
|
@ -446,6 +447,10 @@ void setup() {
|
|||
FilteredSamples.Fan.setRounding(10);
|
||||
FilteredSamples.Fan.setAlpha(0.7);
|
||||
FilteredSamples.AmbientTemp.reset(-100.0);
|
||||
FilteredSamples.FastipVolts.setRounding(0.1);
|
||||
FilteredSamples.FastipVolts.setAlpha(0.7);
|
||||
FilteredSamples.FastGlowAmps.setRounding(0.01);
|
||||
FilteredSamples.FastGlowAmps.setAlpha(0.7);
|
||||
|
||||
RTC_Store.begin();
|
||||
FuelGauge.init(RTC_Store.getFuelGauge());
|
||||
|
@ -792,9 +797,24 @@ void loop()
|
|||
|
||||
ScreenManager.reqUpdate();
|
||||
}
|
||||
|
||||
if(bHasHtrData) {
|
||||
// apply exponential mean to the anlogue readings for some smoothing
|
||||
updateFilteredData();
|
||||
FuelGauge.Integrate(HeaterFrame2.getPump_Actual());
|
||||
|
||||
// integrate fuel pump activity for fuel gauge
|
||||
FuelGauge.Integrate(getHeaterInfo().getPump_Actual());
|
||||
|
||||
// test for low volts shutdown during normal run
|
||||
if(INBOUNDS(getHeaterInfo().getRunState(), 1, 5)) { // check for Low Voltage Cutout
|
||||
SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
|
||||
}
|
||||
|
||||
// trap being in state 0 with a heater error - cancel user on memory to avoid unexpected cyclic restarts
|
||||
if(RTC_Store.getCyclicEngaged() && (getHeaterInfo().getRunState() == 0) && (getHeaterInfo().getErrState() > 1)) {
|
||||
DebugPort.println("Forcing cyclic cancel due to error induced shutdown");
|
||||
RTC_Store.setCyclicEngaged(false);
|
||||
}
|
||||
}
|
||||
updateJSONclients(bReportJSONData);
|
||||
CommState.set(CommStates::Idle);
|
||||
|
@ -822,7 +842,7 @@ void manageCyclicMode()
|
|||
const sCyclicThermostat& cyclic = NVstore.getUserSettings().cyclic;
|
||||
if(cyclic.Stop && RTC_Store.getCyclicEngaged()) { // cyclic mode enabled, and user has started heater
|
||||
int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over!
|
||||
float deltaT = FilteredSamples.AmbientTemp.getValue() - getDemandDegC();
|
||||
float deltaT = getTemperatureSensor() - getDemandDegC();
|
||||
// DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT);
|
||||
|
||||
// ensure we cancel user ON mode if heater throws an error
|
||||
|
@ -883,9 +903,11 @@ bool validateFrame(const CProtocol& frame, const char* name)
|
|||
|
||||
void requestOn()
|
||||
{
|
||||
if(SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue())) {
|
||||
heaterOn();
|
||||
RTC_Store.setCyclicEngaged(true); // for cyclic mode
|
||||
}
|
||||
}
|
||||
|
||||
void requestOff()
|
||||
{
|
||||
|
@ -1041,7 +1063,7 @@ float getTemperatureDesired()
|
|||
|
||||
float getTemperatureSensor()
|
||||
{
|
||||
return FilteredSamples.AmbientTemp.getValue();
|
||||
return FilteredSamples.AmbientTemp.getValue() + NVstore.getHeaterTuning().tempOfs;
|
||||
}
|
||||
|
||||
void setPumpMin(float val)
|
||||
|
@ -1449,11 +1471,14 @@ void simulateGPIOin(uint8_t newKey)
|
|||
GPIOin.simulateKey(newKey);
|
||||
}
|
||||
|
||||
float getBatteryVoltage()
|
||||
float getBatteryVoltage(bool fast)
|
||||
{
|
||||
#ifdef RAW_SAMPLES
|
||||
return getHeaterInfo().getBattVoltage();
|
||||
#else
|
||||
if(fast)
|
||||
return FilteredSamples.FastipVolts.getValue();
|
||||
else
|
||||
return FilteredSamples.ipVolts.getValue();
|
||||
#endif
|
||||
}
|
||||
|
@ -1487,13 +1512,16 @@ float getFanSpeed()
|
|||
|
||||
void updateFilteredData()
|
||||
{
|
||||
FilteredSamples.ipVolts.update(HeaterFrame2.getVoltage_Supply());
|
||||
FilteredSamples.GlowVolts.update(HeaterFrame2.getGlowPlug_Voltage());
|
||||
FilteredSamples.GlowAmps.update(HeaterFrame2.getGlowPlug_Current());
|
||||
FilteredSamples.Fan.update(HeaterFrame2.getFan_Actual());
|
||||
FilteredSamples.ipVolts.update(getHeaterInfo().getBattVoltage());
|
||||
FilteredSamples.GlowVolts.update(getHeaterInfo().getGlow_Voltage());
|
||||
FilteredSamples.GlowAmps.update(getHeaterInfo().getGlow_Current());
|
||||
FilteredSamples.Fan.update(getHeaterInfo().getFan_Actual());
|
||||
FilteredSamples.FastipVolts.update(getHeaterInfo().getBattVoltage());
|
||||
FilteredSamples.FastGlowAmps.update(getHeaterInfo().getGlow_Current());
|
||||
}
|
||||
|
||||
int sysUptime()
|
||||
{
|
||||
return Clock.get().secondstime() - BootTime;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ CBasicScreen::CBasicScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreen
|
|||
bool
|
||||
CBasicScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
char msg[20];
|
||||
int xPos, yPos;
|
||||
|
|
|
@ -43,10 +43,11 @@ CClockScreen::CClockScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreen
|
|||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
CClockScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
const BTCDateTime& now = Clock.get();
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/FuelGauge.h"
|
||||
|
||||
extern CFuelGauge FuelGauge;
|
||||
|
||||
|
||||
#define MINIFONT miniFontInfo
|
||||
|
||||
|
@ -84,7 +82,7 @@ CDetailedScreen::CDetailedScreen(C128x64_OLED& display, CScreenManager& mgr) : C
|
|||
bool
|
||||
CDetailedScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
int runstate = getHeaterInfo().getRunStateEx();
|
||||
int errstate = getHeaterInfo().getErrState();
|
||||
|
|
48
src/Afterburner/src/OLED/FuelCalScreen.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 __FUELCALSCREEN_H__
|
||||
#define __FUELCALSCREEN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "PasswordScreen.h"
|
||||
|
||||
class C128x64_OLED;
|
||||
class CScreenManager;
|
||||
|
||||
class CFuelCalScreen : public CPasswordScreen
|
||||
{
|
||||
int _rowSel;
|
||||
void _adjust(int dir);
|
||||
float _mlPerStroke;
|
||||
float _tOfs;
|
||||
uint8_t _LVC;
|
||||
int _animateCount;
|
||||
void _initUI();
|
||||
public:
|
||||
CFuelCalScreen(C128x64_OLED& display, CScreenManager& mgr);
|
||||
bool show();
|
||||
bool animate();
|
||||
bool keyHandler(uint8_t event);
|
||||
void onSelect();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -34,6 +34,7 @@
|
|||
#include "../Utility/DebugPort.h"
|
||||
#include "../Utility/macros.h"
|
||||
#include "../Protocol/Protocol.h"
|
||||
#include "fonts/Icons.h"
|
||||
|
||||
|
||||
CFuelMixtureScreen::CFuelMixtureScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
|
||||
|
@ -47,6 +48,12 @@ CFuelMixtureScreen::onSelect()
|
|||
CPasswordScreen::onSelect();
|
||||
_initUI();
|
||||
|
||||
_load();
|
||||
}
|
||||
|
||||
void
|
||||
CFuelMixtureScreen::_load()
|
||||
{
|
||||
adjPump[0] = getHeaterInfo().getPump_Min();
|
||||
adjPump[1] = getHeaterInfo().getPump_Max();
|
||||
adjFan[0] = getHeaterInfo().getFan_Min();
|
||||
|
@ -58,6 +65,7 @@ CFuelMixtureScreen::_initUI()
|
|||
{
|
||||
_rowSel = 0;
|
||||
_colSel = 0;
|
||||
_animateCount = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -67,34 +75,40 @@ CFuelMixtureScreen::show()
|
|||
int xPos, yPos;
|
||||
const int col3 = _display.width() - border;
|
||||
|
||||
_display.clearDisplay();
|
||||
_display.fillRect(70, 0, 58, 64, BLACK); // scrub variables
|
||||
_display.fillRect(0, 50, 128, 14, BLACK); // scrub footer
|
||||
|
||||
if(!CPasswordScreen::show()) {
|
||||
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if(_animateCount == -1) {
|
||||
_animateCount = 0;
|
||||
_display.clearDisplay();
|
||||
}
|
||||
// Pump Minimum adjustment
|
||||
yPos = border + 36;
|
||||
_printMenuText(80, yPos, "Min", false, eRightJustify);
|
||||
sprintf(str, "%.1f", adjPump[0]);
|
||||
_printMenuText(65, yPos, "Min", false, eRightJustify);
|
||||
sprintf(str, "%.1f Hz", adjPump[0]);
|
||||
_printMenuText(col3, yPos, str, _rowSel == 1, eRightJustify);
|
||||
// Pump Maximum adjustment
|
||||
yPos = border + 24;
|
||||
_printMenuText(80, yPos, "Pump Hz Max", false, eRightJustify);
|
||||
sprintf(str, "%.1f", adjPump[1]);
|
||||
_printMenuText(65, yPos, "Max", false, eRightJustify);
|
||||
sprintf(str, "%.1f Hz", adjPump[1]);
|
||||
_printMenuText(col3, yPos, str, _rowSel == 2, eRightJustify);
|
||||
// Fan Minimum adjustment
|
||||
yPos = border + 12;
|
||||
_printMenuText(80, yPos, "Min", false, eRightJustify);
|
||||
sprintf(str, "%d", adjFan[0]);
|
||||
_printMenuText(65, yPos, "Min", false, eRightJustify);
|
||||
sprintf(str, "%d RPM", adjFan[0]);
|
||||
_printMenuText(col3, yPos, str, _rowSel == 3, eRightJustify);
|
||||
// Fan Maximum adjustment
|
||||
yPos = border;
|
||||
_printMenuText(80, yPos, "Fan RPM Max", false, eRightJustify);
|
||||
sprintf(str, "%d", adjFan[1]);
|
||||
_printMenuText(65, yPos, "Max", false, eRightJustify);
|
||||
sprintf(str, "%d RPM", adjFan[1]);
|
||||
_printMenuText(col3, yPos, str, _rowSel == 4, eRightJustify);
|
||||
// navigation line
|
||||
yPos = 53;
|
||||
|
@ -128,6 +142,29 @@ CFuelMixtureScreen::show()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CFuelMixtureScreen::animate()
|
||||
{
|
||||
if(_animateCount >= 0) {
|
||||
|
||||
int xPos = 20;
|
||||
int yPos = 5;
|
||||
int yFuel = 30;
|
||||
_display.fillRect(xPos, yPos, FanIcon1Info.width, FanIcon1Info.height, BLACK);
|
||||
_display.fillRect(xPos+5, yFuel, FuelIconInfo.width, FuelIconInfo.height + 4, BLACK);
|
||||
_drawBitmap(xPos+5, yFuel+_animateCount, FuelIconInfo);
|
||||
switch(_animateCount) {
|
||||
case 0: _drawBitmap(xPos, yPos, FanIcon1Info); break;
|
||||
case 1: _drawBitmap(xPos, yPos, FanIcon2Info); break;
|
||||
case 2: _drawBitmap(xPos, yPos, FanIcon3Info); break;
|
||||
case 3: _drawBitmap(xPos, yPos, FanIcon4Info); break;
|
||||
}
|
||||
|
||||
_animateCount++;
|
||||
WRAPUPPERLIMIT(_animateCount, 3, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CFuelMixtureScreen::keyHandler(uint8_t event)
|
||||
|
@ -143,6 +180,8 @@ CFuelMixtureScreen::keyHandler(uint8_t event)
|
|||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
_animateCount = -1;
|
||||
_display.clearDisplay();
|
||||
_rowSel = 5; // enter save confirm mode
|
||||
break;
|
||||
case 5:
|
||||
|
@ -204,6 +243,8 @@ CFuelMixtureScreen::keyHandler(uint8_t event)
|
|||
UPPERLIMIT(_rowSel, 4);
|
||||
break;
|
||||
case 5:
|
||||
_display.clearDisplay();
|
||||
_animateCount = -1;
|
||||
_showStoringMessage();
|
||||
setPumpMin(adjPump[0]);
|
||||
setPumpMax(adjPump[1]);
|
||||
|
@ -233,6 +274,9 @@ CFuelMixtureScreen::keyHandler(uint8_t event)
|
|||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
|
||||
if(_rowSel == 0) {
|
||||
_load(); // dispose of any changes, re-obtain current settings
|
||||
}
|
||||
|
||||
if(event & keyRepeat) {
|
||||
switch(_rowSel) {
|
||||
|
|
|
@ -33,12 +33,15 @@ class CFuelMixtureScreen : public CPasswordScreen {
|
|||
uint16_t adjFan[2];
|
||||
int _rowSel;
|
||||
int _colSel;
|
||||
int _animateCount;
|
||||
void _adjustSetting(int dir);
|
||||
void _initUI();
|
||||
void _load();
|
||||
|
||||
public:
|
||||
CFuelMixtureScreen(C128x64_OLED& display, CScreenManager& mgr);
|
||||
bool show();
|
||||
bool animate();
|
||||
bool keyHandler(uint8_t event);
|
||||
void onSelect();
|
||||
};
|
||||
|
|
|
@ -291,12 +291,6 @@ CGPIOInfoScreen::CGPIOInfoScreen(C128x64_OLED& display, CScreenManager& mgr) : C
|
|||
_keyRepeatCount = -1;
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOInfoScreen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOInfoScreen::_initUI()
|
||||
{
|
||||
|
@ -305,7 +299,7 @@ CGPIOInfoScreen::_initUI()
|
|||
bool
|
||||
CGPIOInfoScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
char msg[16];
|
||||
|
||||
_display.writeFillRect(49, 18, 30, 12, WHITE);
|
||||
|
|
|
@ -53,7 +53,6 @@ public:
|
|||
CGPIOInfoScreen(C128x64_OLED& display, CScreenManager& mgr);
|
||||
bool show();
|
||||
bool keyHandler(uint8_t event);
|
||||
void onSelect();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,10 +21,13 @@
|
|||
|
||||
#include "128x64OLED.h"
|
||||
#include "HeaterSettingsScreen.h"
|
||||
#include "FuelCalScreen.h"
|
||||
#include "KeyPad.h"
|
||||
#include "../Utility/helpers.h"
|
||||
#include "../Utility/macros.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
#include "../Protocol/Protocol.h"
|
||||
#include "fonts/Icons.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -246,3 +249,280 @@ CHeaterSettingsScreen::_adjust(int dir)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CFuelCalScreen::CFuelCalScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
|
||||
{
|
||||
_initUI();
|
||||
_mlPerStroke = 0.02;
|
||||
_LVC = 115;
|
||||
_tOfs = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CFuelCalScreen::onSelect()
|
||||
{
|
||||
CPasswordScreen::onSelect();
|
||||
_initUI();
|
||||
_mlPerStroke = NVstore.getHeaterTuning().pumpCal;
|
||||
_LVC = NVstore.getHeaterTuning().lowVolts;
|
||||
_tOfs = NVstore.getHeaterTuning().tempOfs;
|
||||
}
|
||||
|
||||
void
|
||||
CFuelCalScreen::_initUI()
|
||||
{
|
||||
_rowSel = 0;
|
||||
_animateCount = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
CFuelCalScreen::show()
|
||||
{
|
||||
char msg[20];
|
||||
const int col = 90;
|
||||
|
||||
_display.fillRect(0, 50, 128, 14, BLACK);
|
||||
_display.fillRect(col-border, Line3-border, 128-(col-1), 64-Line3-border, BLACK);
|
||||
|
||||
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 {
|
||||
if(_animateCount < 0) {
|
||||
_display.clearDisplay();
|
||||
_animateCount = 0;
|
||||
}
|
||||
_printInverted(_display.xCentre(), 0, " Special Features ", true, eCentreJustify);
|
||||
// fuel calibration
|
||||
int yPos = Line1;
|
||||
_printMenuText(col, yPos, "mL/stroke : ", false, eRightJustify);
|
||||
sprintf(msg, "%.03f", _mlPerStroke);
|
||||
_printMenuText(col, yPos, msg, _rowSel == 1);
|
||||
// low voltage cutout
|
||||
yPos = Line2;
|
||||
_printMenuText(col, yPos, "L.V.C. < ", false, eRightJustify);
|
||||
if(_LVC)
|
||||
sprintf(msg, "%.1fV", float(_LVC) * 0.1);
|
||||
else
|
||||
strcpy(msg, "OFF");
|
||||
_printMenuText(col, yPos, msg, _rowSel == 2);
|
||||
// temp offset
|
||||
yPos = Line3;
|
||||
_printMenuText(col, yPos, "\367C offset : ", false, eRightJustify);
|
||||
sprintf(msg, "%+.1f", _tOfs);
|
||||
_printMenuText(col, yPos, msg, _rowSel == 3);
|
||||
// navigation line
|
||||
yPos = 53;
|
||||
int xPos = _display.xCentre();
|
||||
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_printMenuText(xPos, yPos, " \021 Exit \020 ", true, eCentreJustify);
|
||||
break;
|
||||
default:
|
||||
_display.drawFastHLine(0, 52, 128, WHITE);
|
||||
_printMenuText(xPos, 56, "\030\031Sel \033\032 Adj", false, eCentreJustify);
|
||||
_printMenuText(xPos, 56, "Save", false, eCentreJustify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CFuelCalScreen::animate()
|
||||
{
|
||||
if(_animateCount >= 0) {
|
||||
switch(_animateCount) {
|
||||
case 0:
|
||||
_display.fillRect(0, Line3-4, BatteryIconInfo.width, 40, BLACK);
|
||||
_drawBitmap(6, Line1-3, FuelIconSmallInfo);
|
||||
_drawBitmap(0, Line2-1 , BatteryIconInfo);
|
||||
_drawBitmap(5, Line3-4, miniThermoIconInfo);
|
||||
break;
|
||||
case 2:
|
||||
_display.fillRect(6, Line1-3, FuelIconSmallInfo.width, FuelIconSmallInfo.height, BLACK); // scrub prior drip
|
||||
_drawBitmap(6, Line1-2, FuelIconSmallInfo); // drip fuel
|
||||
_display.fillRect(BatteryIconInfo.width - 4, Line2+2, 2, 5, BLACK); // deplete battery
|
||||
_display.fillRect(7, Line3+2, 2, 2, WHITE); // grow thermometer
|
||||
break;
|
||||
case 4:
|
||||
_display.fillRect(6, Line1-2, FuelIconSmallInfo.width, FuelIconSmallInfo.height, BLACK); // scrub prior drip
|
||||
_drawBitmap(6, Line1-1, FuelIconSmallInfo); // drip fuel
|
||||
_display.fillRect(BatteryIconInfo.width - 7, Line2+2, 2, 5, BLACK); // deplete battery
|
||||
_display.fillRect(7, Line3+1, 2, 1, WHITE); // grow thermometer
|
||||
break;
|
||||
case 6:
|
||||
_display.fillRect(6, Line1-1, FuelIconSmallInfo.width, FuelIconSmallInfo.height, BLACK); // scrub prior drip
|
||||
_drawBitmap(6, Line1, FuelIconSmallInfo); // drip fuel
|
||||
_display.fillRect(BatteryIconInfo.width - 10, Line2+2, 2, 5, BLACK); // deplete battery
|
||||
_display.fillRect(7, Line3, 2, 1, WHITE); // grow thermometer
|
||||
break;
|
||||
case 8:
|
||||
_display.fillRect(6, Line1, FuelIconSmallInfo.width, FuelIconSmallInfo.height, BLACK); // scrub prior drip
|
||||
_drawBitmap(6, Line1+1, FuelIconSmallInfo); // drip fuel
|
||||
_display.fillRect(BatteryIconInfo.width - 13, Line2+2, 2, 5, BLACK); // deplete battery
|
||||
_display.fillRect(7, Line3-1, 2, 1, WHITE); // grow thermometer
|
||||
break;
|
||||
}
|
||||
|
||||
_animateCount++;
|
||||
WRAPUPPERLIMIT(_animateCount, 9, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CFuelCalScreen::keyHandler(uint8_t event)
|
||||
{
|
||||
sHeaterTuning tuning;
|
||||
|
||||
if(event & keyRepeat) {
|
||||
if(event & key_Left) {
|
||||
_adjust(-1);
|
||||
}
|
||||
if(event & key_Right) {
|
||||
_adjust(+1);
|
||||
}
|
||||
}
|
||||
|
||||
if(event & keyPressed) {
|
||||
// press LEFT to select previous screen
|
||||
if(event & key_Left) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_ScreenManager.prevMenu();
|
||||
break;
|
||||
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 0:
|
||||
_ScreenManager.nextMenu();
|
||||
break;
|
||||
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, 3);
|
||||
break;
|
||||
case 4: // confirmed save
|
||||
_display.clearDisplay();
|
||||
_animateCount = -1;
|
||||
_showStoringMessage();
|
||||
tuning = NVstore.getHeaterTuning();
|
||||
tuning.pumpCal = _mlPerStroke;
|
||||
tuning.lowVolts = _LVC;
|
||||
tuning.tempOfs = _tOfs;
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
saveNV();
|
||||
_rowSel = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// CENTRE press
|
||||
if(event & key_Centre) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_ScreenManager.selectMenu(CScreenManager::RootMenuLoop);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
_animateCount = -1;
|
||||
_display.clearDisplay();
|
||||
_rowSel = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CFuelCalScreen::_adjust(int dir)
|
||||
{
|
||||
switch(_rowSel) {
|
||||
case 1:
|
||||
_mlPerStroke += dir * 0.001;
|
||||
BOUNDSLIMIT(_mlPerStroke, 0.001, 1);
|
||||
break;
|
||||
case 2:
|
||||
if(_LVC == 0) {
|
||||
if(NVstore.getHeaterTuning().sysVoltage == 120)
|
||||
_LVC = dir > 0 ? 115 : 0;
|
||||
else
|
||||
_LVC = dir > 0 ? 230 : 0;
|
||||
}
|
||||
else {
|
||||
_LVC += dir;
|
||||
if(NVstore.getHeaterTuning().sysVoltage == 120) {
|
||||
if(_LVC < 100)
|
||||
_LVC = 0;
|
||||
else
|
||||
UPPERLIMIT(_LVC, 125);
|
||||
}
|
||||
else {
|
||||
if(_LVC < 200)
|
||||
_LVC = 0;
|
||||
else
|
||||
UPPERLIMIT(_LVC, 250);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
_tOfs += dir * 0.1;
|
||||
BOUNDSLIMIT(_tOfs, -10, 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ CInheritSettingsScreen::_initUI()
|
|||
bool
|
||||
CInheritSettingsScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
_display.writeFillRect(0, 16, 96, 12, WHITE);
|
||||
_printInverted(3, 18, "Inherit Settings", true);
|
||||
|
|
|
@ -41,6 +41,7 @@ CPasswordScreen::CPasswordScreen(C128x64_OLED& display, CScreenManager& mgr) : C
|
|||
void
|
||||
CPasswordScreen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
_initUI();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include "KeyPad.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
#include "../Protocol/Protocol.h"
|
||||
#include "fonts/Icons.h"
|
||||
#include "../RTC/Clock.h"
|
||||
#include "../Utility/FuelGauge.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -42,6 +46,7 @@ CPrimingScreen::CPrimingScreen(C128x64_OLED& display, CScreenManager& mgr) : CSc
|
|||
void
|
||||
CPrimingScreen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
_stopPump();
|
||||
_initUI();
|
||||
}
|
||||
|
@ -58,93 +63,147 @@ CPrimingScreen::_initUI()
|
|||
{
|
||||
_PrimeStop = 0;
|
||||
_PrimeCheck = 0;
|
||||
_rowSel = 0;
|
||||
_paramSel = 0;
|
||||
_colSel = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
CPrimingScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
_display.fillRect(0, 15, 100, 3, BLACK);
|
||||
|
||||
CRect extents;
|
||||
|
||||
int yPos = 53;
|
||||
// show next/prev menu navigation line
|
||||
switch(_rowSel) {
|
||||
switch(_paramSel) {
|
||||
case 0:
|
||||
_printMenuText(_display.xCentre(), yPos, " \021 \030Edit \020 ", _rowSel == 0, eCentreJustify);
|
||||
_printMenuText(_display.xCentre(), yPos, " \021 \030Edit \020 ", _paramSel == 0, eCentreJustify);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
_display.drawFastHLine(0, 53, 128, WHITE);
|
||||
_printMenuText(_display.xCentre(), 57, "\030\031 Sel \033\032 Adj", false, eCentreJustify);
|
||||
_printMenuText(_display.xCentre(), 57, "\030\031 Sel \033\032 Param", false, eCentreJustify);
|
||||
break;
|
||||
case 3:
|
||||
_display.drawFastHLine(0, 53, 128, WHITE);
|
||||
if(_colSel == 2) {
|
||||
_printMenuText(_display.xCentre(), 57, "\033\030\031 Stop", false, eCentreJustify);
|
||||
}
|
||||
else {
|
||||
_printMenuText(_display.xCentre(), 57, "\032 Start \031 Sel", false, eCentreJustify);
|
||||
switch(_colSel) {
|
||||
case 1:
|
||||
_printMenuText(_display.xCentre(), 57, "\033\030\031\032 Stop", false, eCentreJustify);
|
||||
break;
|
||||
case 0:
|
||||
_printMenuText(_display.xCentre(), 57, "\030 Start \031 Sel", false, eCentreJustify);
|
||||
break;
|
||||
case -1:
|
||||
_printMenuText(_display.xCentre(), 57, "\030 Sel Zero", false, eCentreJustify);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
yPos = 40;
|
||||
if(_rowSel == 1) {
|
||||
int topline = 19;
|
||||
int midline = 29;
|
||||
int botline = 35;
|
||||
|
||||
CRect loc;
|
||||
loc.height = ThermostatDegCIconInfo.height;
|
||||
loc.width = ThermostatDegCIconInfo.width;
|
||||
loc.xPos = border;
|
||||
if(_paramSel == 1) {
|
||||
// follow user desired setting, heater info is laggy
|
||||
_printMenuText(border, yPos, "Thermostat", _colSel == 0);
|
||||
_printMenuText(_display.width()-border, yPos, "Fixed Hz", _colSel == 1, eRightJustify);
|
||||
if(NVstore.getUserSettings().degF)
|
||||
_drawBitmap(loc.xPos, topline-1, ThermostatDegFIconInfo);
|
||||
else
|
||||
_drawBitmap(loc.xPos, topline-1, ThermostatDegCIconInfo);
|
||||
_drawBitmap(loc.xPos, botline+1, ThermostatHzIconInfo);
|
||||
loc.yPos = (_colSel == 0) ? topline-1 : botline+1;
|
||||
_drawMenuSelection(loc, border, radius);
|
||||
}
|
||||
else {
|
||||
// follow actual heater settings
|
||||
// int col = getHeaterInfo().isThermostat() ? 0 : 1;
|
||||
int col = getThermostatModeActive() ? 0 : 1;
|
||||
_printInverted(border, yPos, "Thermostat", col == 0);
|
||||
_printInverted(_display.width()-border, yPos, "Fixed Hz", col == 1, eRightJustify);
|
||||
}
|
||||
yPos = 28;
|
||||
if(_rowSel == 2) {
|
||||
_printMenuText(border, yPos, "degC", _colSel == 0);
|
||||
_printMenuText(_display.width()-border, yPos, "degF", _colSel == 1, eRightJustify);
|
||||
if(getThermostatModeActive()) {
|
||||
_drawBitmap(loc.xPos, midline, NVstore.getUserSettings().degF ? ThermostatDegFIconInfo : ThermostatDegCIconInfo);
|
||||
}
|
||||
else {
|
||||
int col = NVstore.getUserSettings().degF ? 1 : 0;
|
||||
_printInverted(border, yPos, "degC", col == 0);
|
||||
_printInverted(_display.width()-border, yPos, "degF", col == 1, eRightJustify);
|
||||
_drawBitmap(loc.xPos, midline, ThermostatHzIconInfo);
|
||||
}
|
||||
}
|
||||
|
||||
loc.height = DegCIconInfo.height;
|
||||
loc.width = DegCIconInfo.width;
|
||||
loc.xPos = 35;
|
||||
if(_paramSel == 2) {
|
||||
loc.yPos = (_colSel == 0) ? topline : botline;
|
||||
_drawMenuSelection(loc, border, radius);
|
||||
_drawBitmap(loc.xPos, topline, DegCIconInfo);
|
||||
_drawBitmap(loc.xPos, botline, DegFIconInfo);
|
||||
}
|
||||
else {
|
||||
_drawBitmap(loc.xPos, midline, NVstore.getUserSettings().degF ? DegFIconInfo : DegCIconInfo);
|
||||
}
|
||||
|
||||
// fuel pump priming menu
|
||||
yPos = 16;
|
||||
_printMenuText(border, yPos, "Pump");
|
||||
if(_rowSel == 3) {
|
||||
_printMenuText(40, yPos, "OFF", _colSel == 1);
|
||||
if(_colSel != 2) {
|
||||
if(!getHeaterInfo().getRunState()) { // prevent option if heater is running
|
||||
_printMenuText(70, yPos, "ON"); // becomes Hz when actually priming
|
||||
loc.xPos = 66;
|
||||
loc.width = BowserIconInfo.width;
|
||||
loc.height = BowserIconInfo.height;
|
||||
_drawBitmap(loc.xPos, midline, BowserIconInfo);
|
||||
loc.xPos = 81;
|
||||
if(_paramSel == 3) {
|
||||
_drawBitmap(loc.xPos, topline, FuelIconInfo);
|
||||
_drawBitmap(loc.xPos, botline, resetIconInfo);
|
||||
|
||||
if(_colSel == -1) {
|
||||
loc.yPos = botline;
|
||||
loc.width = resetIconInfo.width;
|
||||
loc.height = resetIconInfo.height;
|
||||
_drawMenuSelection(loc, border, radius);
|
||||
}
|
||||
|
||||
loc.yPos = _colSel == -1 ? botline : topline;
|
||||
loc.width = FuelIconInfo.width + StartIconInfo.width + 2;
|
||||
loc.height = FuelIconInfo.height;
|
||||
if(_colSel == 0) {
|
||||
_drawMenuSelection(loc, border, radius);
|
||||
}
|
||||
loc.xPos += FuelIconInfo.width + 2;
|
||||
if(_colSel != 1) { // only show start options if not priming already
|
||||
if(getHeaterInfo().getRunState() == 0) { // prevent priming option if heater is running
|
||||
_drawBitmap(loc.xPos, topline+2, StartIconInfo); // becomes Hz when actually priming
|
||||
}
|
||||
else {
|
||||
_drawBitmap(loc.xPos, topline, CrossIconInfo);
|
||||
}
|
||||
}
|
||||
if(_colSel == 1) {
|
||||
float pumpHz = getHeaterInfo().getPump_Actual();
|
||||
// recognise if heater has stopped pump, after an initial holdoff upon first starting
|
||||
long tDelta = millis() - _PrimeCheck;
|
||||
if(_PrimeCheck && tDelta > 0 && pumpHz < 0.1) {
|
||||
_stopPump();
|
||||
_paramSel = _colSel = 0;
|
||||
}
|
||||
// test if time is up, stop priming if so
|
||||
tDelta = millis() - _PrimeStop;
|
||||
if(_PrimeStop && tDelta > 0) {
|
||||
_stopPump();
|
||||
_paramSel = _colSel = 0;
|
||||
}
|
||||
|
||||
if(_PrimeStop) {
|
||||
char msg[16];
|
||||
sprintf(msg, "%.1fHz", pumpHz);
|
||||
_printMenuText(70, yPos, msg, true);
|
||||
_printMenuText(loc.xPos+1+border, topline+3, msg, true);
|
||||
_ScreenManager.bumpTimeout(); // don't allow menu timeouts whilst priming is active
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
char msg[16];
|
||||
sprintf(msg, "%.02fL", FuelGauge.Used_mL() * 0.001);
|
||||
_printMenuText(loc.xPos+1, midline+3, msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -157,47 +216,46 @@ CPrimingScreen::keyHandler(uint8_t event)
|
|||
if(event & keyPressed) {
|
||||
// press LEFT
|
||||
if(event & key_Left) {
|
||||
switch(_rowSel) {
|
||||
switch(_paramSel) {
|
||||
case 0:
|
||||
_ScreenManager.prevMenu();
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
_paramSel--;
|
||||
LOWERLIMIT(_paramSel, 0);
|
||||
_colSel = 0;
|
||||
setThermostatMode(1);
|
||||
saveNV();
|
||||
switch(_paramSel) {
|
||||
case 1:
|
||||
_colSel = getThermostatModeActive() ? 0 : 1;
|
||||
break;
|
||||
case 2:
|
||||
_colSel = 0;
|
||||
setDegFMode(false);
|
||||
saveNV();
|
||||
_colSel = NVstore.getUserSettings().degF ? 1 : 0;
|
||||
break;
|
||||
case 3:
|
||||
_colSel = 1;
|
||||
}
|
||||
break;
|
||||
case 4: break;
|
||||
}
|
||||
}
|
||||
// press RIGHT
|
||||
if(event & key_Right) {
|
||||
switch(_rowSel) {
|
||||
switch(_paramSel) {
|
||||
case 0:
|
||||
_ScreenManager.nextMenu();
|
||||
break;
|
||||
case 1:
|
||||
_colSel = 1;
|
||||
setThermostatMode(0);
|
||||
saveNV();
|
||||
default:
|
||||
_paramSel++;
|
||||
UPPERLIMIT(_paramSel, 3);
|
||||
switch(_paramSel) {
|
||||
case 3:
|
||||
_colSel = 0; // select OFF upon entry to priming menu
|
||||
break;
|
||||
case 2:
|
||||
_colSel = 1;
|
||||
setDegFMode(true);
|
||||
saveNV();
|
||||
_colSel = NVstore.getUserSettings().degF ? 1 : 0;
|
||||
break;
|
||||
case 3:
|
||||
if(!getHeaterInfo().getRunState())
|
||||
_colSel = 2;
|
||||
case 1:
|
||||
_colSel = getThermostatModeActive() ? 0 : 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4: break;
|
||||
}
|
||||
}
|
||||
// press UP
|
||||
|
@ -205,35 +263,90 @@ CPrimingScreen::keyHandler(uint8_t event)
|
|||
if(hasOEMcontroller())
|
||||
_reqOEMWarning();
|
||||
else {
|
||||
_rowSel++;
|
||||
UPPERLIMIT(_rowSel, 3);
|
||||
if(_rowSel == 3)
|
||||
_colSel = 1; // select OFF upon entry to priming menu
|
||||
if(_rowSel == 2)
|
||||
_colSel = NVstore.getUserSettings().degF ? 1 : 0;
|
||||
if(_rowSel == 1)
|
||||
switch(_paramSel) {
|
||||
case 0:
|
||||
_paramSel = 1;
|
||||
_colSel = getThermostatModeActive() ? 0 : 1;
|
||||
break;
|
||||
case 1:
|
||||
_colSel++;
|
||||
WRAPLIMITS(_colSel, 0, 1);
|
||||
setThermostatMode(_colSel == 0);
|
||||
saveNV();
|
||||
break;
|
||||
case 2:
|
||||
_colSel++;
|
||||
WRAPLIMITS(_colSel, 0, 1);
|
||||
setDegFMode(_colSel != 0);
|
||||
saveNV();
|
||||
break;
|
||||
case 3:
|
||||
if(_colSel == 1)
|
||||
_colSel = 0;
|
||||
else {
|
||||
_colSel++;
|
||||
UPPERLIMIT(_colSel, (getHeaterInfo().getRunState() == 0) ? 1 : 0); // prevent priming if heater is running
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// press DOWN
|
||||
if(event & key_Down) {
|
||||
if(_rowSel == 0) {
|
||||
if(_paramSel == 0) {
|
||||
_ScreenManager.selectMenu(CScreenManager::UserSettingsLoop, CScreenManager::VersionUI); // force return to main menu
|
||||
}
|
||||
else {
|
||||
_rowSel--;
|
||||
LOWERLIMIT(_rowSel, 0);
|
||||
switch(_paramSel) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
_colSel--;
|
||||
WRAPLIMITS(_colSel, 0, 1);
|
||||
setThermostatMode(_colSel == 0);
|
||||
saveNV();
|
||||
break;
|
||||
case 2:
|
||||
_colSel--;
|
||||
WRAPLIMITS(_colSel, 0, 1);
|
||||
setDegFMode(_colSel != 0);
|
||||
saveNV();
|
||||
break;
|
||||
case 3:
|
||||
_colSel--;
|
||||
LOWERLIMIT(_colSel, -1);
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// press UP
|
||||
if(event & key_Centre) {
|
||||
if(_paramSel == 3) {
|
||||
switch(_colSel) {
|
||||
case 0:
|
||||
if(getHeaterInfo().getRunState() == 0)
|
||||
_colSel = 1;
|
||||
break;
|
||||
case 1:
|
||||
_colSel = 0;
|
||||
if(_rowSel == 1)
|
||||
// _colSel = getHeaterInfo().isThermostat() ? 0 : 1;
|
||||
_colSel = getThermostatModeActive() ? 0 : 1;
|
||||
if(_rowSel == 2)
|
||||
_colSel = NVstore.getUserSettings().degF ? 1 : 0;
|
||||
break;
|
||||
case -1:
|
||||
FuelGauge.reset();
|
||||
_paramSel = _colSel = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_paramSel = _colSel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// check if fuel priming was selected
|
||||
if(_rowSel == 3 && _colSel == 2) {
|
||||
if(_paramSel == 3 && _colSel == 1 ) {
|
||||
reqPumpPrime(true);
|
||||
_PrimeStop = millis() + 150000; // allow 2.5 minutes - much the same as the heater itself cuts out at
|
||||
_PrimeCheck = millis() + 3000; // holdoff upon start before testing for heater shutting off pump
|
||||
|
@ -253,6 +366,7 @@ CPrimingScreen::_stopPump()
|
|||
reqPumpPrime(false);
|
||||
_PrimeCheck = 0;
|
||||
_PrimeStop = 0;
|
||||
if(_colSel == 2)
|
||||
_colSel = 1;
|
||||
if(_paramSel == 3 && _colSel == 1) {
|
||||
_colSel = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class CScreenManager;
|
|||
class CPrimingScreen : public CScreenHeader {
|
||||
unsigned long _PrimeStop;
|
||||
unsigned long _PrimeCheck;
|
||||
int _rowSel;
|
||||
int _paramSel;
|
||||
int _colSel;
|
||||
void _stopPump();
|
||||
void _initUI();
|
||||
|
|
|
@ -63,6 +63,7 @@ CScreen::show()
|
|||
void
|
||||
CScreen::onSelect()
|
||||
{
|
||||
_display.clearDisplay();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -91,9 +92,19 @@ CScreen::_printMenuText(int x, int y, const char* str, bool selected, eJUSTIFY j
|
|||
void
|
||||
CScreen::_drawMenuSelection(CRect extents, const char* str, int border, int radius)
|
||||
{
|
||||
_display.getTextExtents(str, extents);
|
||||
extents.Expand(border);
|
||||
_display.drawRoundRect(extents.xPos, extents.yPos, extents.width, extents.height, radius, WHITE);
|
||||
CRect resize(extents);
|
||||
_display.getTextExtents(str, resize);
|
||||
// resize.Expand(border);
|
||||
// _display.drawRoundRect(resize.xPos, resize.yPos, resize.width, resize.height, radius, WHITE);
|
||||
_drawMenuSelection(resize, border, radius);
|
||||
}
|
||||
|
||||
void
|
||||
CScreen::_drawMenuSelection(const CRect& extents, int border, int radius)
|
||||
{
|
||||
CRect resize(extents);
|
||||
resize.Expand(border);
|
||||
_display.drawRoundRect(resize.xPos, resize.yPos, resize.width, resize.height, radius, WHITE);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -52,6 +52,7 @@ protected:
|
|||
void _printInverted(int x, int y, const char* str, bool selected, eJUSTIFY justify = eLeftJustify);
|
||||
void _adjustExtents(CRect& rect, eJUSTIFY justify, const char* str);
|
||||
void _drawMenuSelection(CRect extents, const char* str, int border = 3, int radius = 4);
|
||||
void _drawMenuSelection(const CRect& extents, int border, int radius);
|
||||
void _scrollMessage(int y, const char* str, int& charOffset);
|
||||
void _reqOEMWarning();
|
||||
void _drawBitmap(int x, int y, const BITMAP_INFO& info, uint16_t color = WHITE, uint16_t bg = 0xffff);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "fonts/Icons.h"
|
||||
#include "fonts/MiniFont.h"
|
||||
#include "../RTC/TimerManager.h"
|
||||
#include "../Protocol/SmartError.h"
|
||||
#include "../Utility/DataFilter.h"
|
||||
|
||||
|
||||
#define MINIFONT miniFontInfo
|
||||
|
@ -65,9 +67,15 @@ CScreenHeader::CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr) : CScreen(
|
|||
}
|
||||
|
||||
bool
|
||||
CScreenHeader::show()
|
||||
CScreenHeader::show(bool erase)
|
||||
{
|
||||
_display.clearDisplay();
|
||||
if(erase)
|
||||
_display.clearDisplay(); // erase everything
|
||||
else {
|
||||
_display.fillRect(0, 17, 128, 47, BLACK); // only erase below the header
|
||||
_display.fillRect(119, 0, 9, 17, BLACK); // erase top of body thermo
|
||||
_display.fillRect(0, 0, 9, 17, BLACK); // erase top of ambient thermo
|
||||
}
|
||||
|
||||
// standard header items
|
||||
// Bluetooth
|
||||
|
@ -75,8 +83,7 @@ CScreenHeader::show()
|
|||
|
||||
// WiFi icon is updated in animate()
|
||||
|
||||
// battery
|
||||
showBatteryIcon(getBatteryVoltage());
|
||||
// Battery is updated in animate
|
||||
|
||||
// clock
|
||||
showTime();
|
||||
|
@ -104,7 +111,9 @@ CScreenHeader::animate()
|
|||
// animate timer icon,
|
||||
// inserting an update icon if new firmware available from internet web server
|
||||
_animateCount++;
|
||||
WRAPUPPERLIMIT(_animateCount, 10, 0);
|
||||
_batteryCount++;
|
||||
WRAPUPPERLIMIT(_animateCount, 9, 0);
|
||||
WRAPUPPERLIMIT(_batteryCount, 5, 0);
|
||||
if(isUpdateAvailable(true)) {
|
||||
int xPos = X_TIMER_ICON - 3;
|
||||
int yPos = Y_TIMER_ICON;
|
||||
|
@ -122,7 +131,22 @@ CScreenHeader::animate()
|
|||
}
|
||||
}
|
||||
else {
|
||||
int xPos = X_BATT_ICON;
|
||||
int yPos = Y_BATT_ICON;
|
||||
showTimers();
|
||||
switch(_batteryCount) {
|
||||
case 3:
|
||||
if(SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue())) {
|
||||
showBatteryIcon(getBatteryVoltage(true));
|
||||
}
|
||||
else {
|
||||
_display.fillRect(xPos, yPos, BatteryIconInfo.width, BatteryIconInfo.height, BLACK);
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
showBatteryIcon(getBatteryVoltage(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
showWifiIcon();
|
||||
|
@ -285,6 +309,7 @@ CScreenHeader::showTime()
|
|||
int xPos = X_WIFI_ICON + WifiIconInfo.width + WifiInIconInfo.width; // rhs of wifi conglomeration
|
||||
if(isWifiAP()) xPos += 4; // add more if an Access Point
|
||||
|
||||
_display.fillRect(xPos - 15, Y_CLOCK, 30, arial_8ptFontInfo.nBitsPerLine, BLACK);
|
||||
_printMenuText(X_CLOCK, Y_CLOCK, msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ class CScreenHeader : public CScreen {
|
|||
sScreenholdoff _UpAnnotation;
|
||||
sScreenholdoff _DnAnnotation;
|
||||
bool _colon;
|
||||
int _animateCount;
|
||||
uint8_t _animateCount;
|
||||
uint8_t _batteryCount;
|
||||
protected:
|
||||
void showBTicon();
|
||||
void showWifiIcon();
|
||||
|
@ -53,7 +54,7 @@ protected:
|
|||
virtual void showTime(); // x location depends upon how many timers are active
|
||||
public:
|
||||
CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr);
|
||||
bool show();
|
||||
bool show(bool erase);
|
||||
bool animate();
|
||||
};
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "ClockScreen.h"
|
||||
#include "RebootScreen.h"
|
||||
#include "HeaterSettingsScreen.h"
|
||||
#include "FuelCalScreen.h"
|
||||
#include "SettingsScreen.h"
|
||||
#include "ThermostatModeScreen.h"
|
||||
#include "FontDumpScreen.h"
|
||||
|
@ -290,8 +291,9 @@ CScreenManager::begin(bool bNoClock)
|
|||
|
||||
// create heater tuning screens loop - password protected
|
||||
menuloop.clear();
|
||||
menuloop.push_back(new CFuelMixtureScreen(*_pDisplay, *this)); // tuning
|
||||
menuloop.push_back(new CHeaterSettingsScreen(*_pDisplay, *this)); // tuning
|
||||
menuloop.push_back(new CFuelMixtureScreen(*_pDisplay, *this)); // mixture tuning
|
||||
menuloop.push_back(new CHeaterSettingsScreen(*_pDisplay, *this)); // heater system tuning
|
||||
menuloop.push_back(new CFuelCalScreen(*_pDisplay, *this)); // fuel pump calibration
|
||||
_Screens.push_back(menuloop);
|
||||
|
||||
// create User Settings screens loop
|
||||
|
@ -514,26 +516,30 @@ CScreenManager::prevMenu()
|
|||
void
|
||||
CScreenManager::keyHandler(uint8_t event)
|
||||
{
|
||||
long dimTime = NVstore.getUserSettings().dimTime;
|
||||
|
||||
if(_bDimmed) {
|
||||
if(event & keyReleased) {
|
||||
_dim(false);
|
||||
_DimTime_ms = (millis() + abs(dimTime)) | 1;
|
||||
_MenuTimeout = (millis() + NVstore.getUserSettings().menuTimeout) | 1;
|
||||
bumpTimeout();
|
||||
}
|
||||
return; // initial press when dimmed is always thrown away
|
||||
}
|
||||
|
||||
// _dim(false);
|
||||
_DimTime_ms = (millis() + abs(dimTime)) | 1;
|
||||
_MenuTimeout = (millis() + NVstore.getUserSettings().menuTimeout) | 1;
|
||||
bumpTimeout();
|
||||
|
||||
// call key handler for active screen
|
||||
if(_menu >= 0)
|
||||
_Screens[_menu][_subMenu]->keyHandler(event);
|
||||
}
|
||||
|
||||
void
|
||||
CScreenManager::bumpTimeout()
|
||||
{
|
||||
long dimTime = NVstore.getUserSettings().dimTime;
|
||||
_DimTime_ms = (millis() + abs(dimTime)) | 1;
|
||||
_MenuTimeout = (millis() + NVstore.getUserSettings().menuTimeout) | 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CScreenManager::selectMenu(eUIMenuSets menuSet, int specific)
|
||||
{
|
||||
|
@ -572,11 +578,8 @@ void
|
|||
CScreenManager::showOTAMessage(int percent, eOTAmodes updateType)
|
||||
{
|
||||
static int prevPercent = -1;
|
||||
static long prevTime = millis();
|
||||
|
||||
long tDelta = millis() - prevTime;
|
||||
if(percent != prevPercent/* && tDelta > 500*/) {
|
||||
prevTime = millis();
|
||||
_pDisplay->clearDisplay();
|
||||
_pDisplay->setCursor(64,22);
|
||||
switch(updateType) {
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
enum eUIRootMenus { DetailedControlUI, BasicControlUI, ClockUI, ModeUI, CommsUI, GPIOInfoUI, SettingsUI };
|
||||
enum eUITimerMenus { TimerOverviewUI, Timer1UI, Timer2UI, Timer3UI, Timer4UI, Timer5UI, Timer6UI, Timer7UI,
|
||||
Timer8UI, Timer9UI, Timer10UI, Timer11UI, Timer12UI, Timer13UI, Timer14UI };
|
||||
enum eUITuningMenus { MixtureUI, HeaterSettingsUI };
|
||||
enum eUITuningMenus { MixtureUI, HeaterSettingsUI, FuelCalUI };
|
||||
enum eUIUserSettingsMenus { GPIOUI, ExThermostatUI, VersionUI, HomeMenuUI, TimeIntervalsUI };
|
||||
enum eUIBranchMenus { SetClockUI, InheritSettingsUI, FontDumpUI };
|
||||
public:
|
||||
|
@ -66,6 +66,7 @@ public:
|
|||
void selectMenu(eUIMenuSets menuset, int specific = -1); // use to select loop menus, including the root or branches
|
||||
void showRebootMsg(const char* content[2], long delayTime);
|
||||
void showOTAMessage(int percent, eOTAmodes updateType);
|
||||
void bumpTimeout();
|
||||
};
|
||||
|
||||
#endif // __SCREEN_MANAGER_H__
|
||||
|
|
|
@ -43,6 +43,7 @@ CSetClockScreen::CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr) : C
|
|||
void
|
||||
CSetClockScreen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
_initUI();
|
||||
}
|
||||
|
||||
|
@ -67,7 +68,7 @@ CSetClockScreen::show()
|
|||
if(deltaT >= 0) {
|
||||
_nextT += 1000;
|
||||
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
char str[16];
|
||||
int xPos, yPos;
|
||||
|
|
|
@ -47,6 +47,7 @@ CSetTimerScreen::CSetTimerScreen(C128x64_OLED& display, CScreenManager& mgr, int
|
|||
void
|
||||
CSetTimerScreen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
_initUI();
|
||||
NVstore.getTimerInfo(_timerID, _timerInfo);
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ CSetTimerScreen::_initUI()
|
|||
bool
|
||||
CSetTimerScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
char str[20];
|
||||
int xPos, yPos;
|
||||
|
|
|
@ -66,10 +66,10 @@ CSettingsScreen::show()
|
|||
{
|
||||
char str[16];
|
||||
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
_display.writeFillRect(0, 16, 96, 12, WHITE);
|
||||
_printInverted(3, 18, "Heater Settings", true);
|
||||
_display.writeFillRect(0, 16, 84, 12, WHITE);
|
||||
_printInverted(3, 18, "Heater Tuning", true);
|
||||
|
||||
if(!CPasswordScreen::show()) {
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ CWiFiScreen::CWiFiScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreenHe
|
|||
void
|
||||
CWiFiScreen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
_initUI();
|
||||
}
|
||||
|
||||
|
@ -87,7 +88,7 @@ CWiFiScreen::_initUI()
|
|||
bool
|
||||
CWiFiScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
int yPos = 18;
|
||||
|
||||
|
|
|
@ -662,11 +662,19 @@ const uint8_t PROGMEM arial_8ptBitmaps [] =
|
|||
0x01, 0x00, // #
|
||||
|
||||
// @870 '~' (5 pixels wide)
|
||||
0x03, 0x00, // ##
|
||||
0x01, 0x00, // #
|
||||
0x02, 0x00, // #
|
||||
0x03, 0x00, // ##
|
||||
0x01, 0x00, // #
|
||||
0x02, 0x00, // #
|
||||
|
||||
// @880 '1' (5 pixels wide)
|
||||
0x00, 0x00, //
|
||||
0x04, 0x00, // #
|
||||
0x08, 0x00, // #
|
||||
0x1F, 0xE0, // ########
|
||||
0x00, 0x00, //
|
||||
|
||||
};
|
||||
|
||||
// Character descriptors for Arial 8pt
|
||||
|
@ -690,7 +698,7 @@ const FONT_CHAR_INFO PROGMEM arial_8ptDescriptors[] =
|
|||
{1, 14, 100}, // '.'
|
||||
{3, 14, 102}, // '/'
|
||||
{5, 14, 108}, // '0'
|
||||
{3, 14, 118}, // '1'
|
||||
{5, 14, 880}, // '1'
|
||||
{5, 14, 124}, // '2'
|
||||
{5, 14, 134}, // '3'
|
||||
{5, 14, 144}, // '4'
|
||||
|
|
|
@ -375,6 +375,25 @@ const uint8_t FuelIcon [] PROGMEM = {
|
|||
};
|
||||
const BITMAP_INFO FuelIconInfo(7, 12, FuelIcon);
|
||||
|
||||
//
|
||||
// Image data for FuelIconSmall
|
||||
//
|
||||
|
||||
const uint8_t PROGMEM FuelIconSmall[] =
|
||||
{
|
||||
0x20, // #
|
||||
0x20, // #
|
||||
0x70, // ###
|
||||
0x70, // ###
|
||||
0xF8, // #####
|
||||
0xF8, // #####
|
||||
0xF8, // #####
|
||||
0xF8, // #####
|
||||
0x70, // ###
|
||||
};
|
||||
const BITMAP_INFO FuelIconSmallInfo(5, 9, FuelIconSmall);
|
||||
|
||||
|
||||
// 'Target', 13x13px
|
||||
const uint8_t TargetIcon [] PROGMEM = {
|
||||
0x0f, 0x80, // #####
|
||||
|
@ -578,6 +597,7 @@ const uint8_t PROGMEM CrossIcon[] =
|
|||
0x50, // # #
|
||||
0x88, // # #
|
||||
};
|
||||
const BITMAP_INFO CrossIconInfo(5, 5, CrossIcon);
|
||||
|
||||
const uint8_t PROGMEM TickIcon[] =
|
||||
{
|
||||
|
@ -961,7 +981,146 @@ const uint8_t PROGMEM bowserIcon[] =
|
|||
0x7E, 0x00, // ######
|
||||
0xFF, 0x00, // ########
|
||||
};
|
||||
|
||||
const BITMAP_INFO BowserIconInfo(10, 12, bowserIcon);
|
||||
|
||||
|
||||
//
|
||||
// Image data for degC
|
||||
//
|
||||
const uint8_t PROGMEM degCIcon[] =
|
||||
{
|
||||
0x07, 0x00, 0x00, // ###
|
||||
0x18, 0xC1, 0x8E, // ## ## ## ###
|
||||
0x27, 0x22, 0x51, // # ### # # # # #
|
||||
0x4F, 0x92, 0x50, // # ##### # # # #
|
||||
0x8F, 0x89, 0x90, // # ##### # ## #
|
||||
0x4F, 0x90, 0x10, // # ##### # #
|
||||
0x27, 0x20, 0x11, // # ### # # #
|
||||
0x18, 0xC0, 0x0E, // ## ## ###
|
||||
0x07, 0x00, 0x00, // ###
|
||||
};
|
||||
const BITMAP_INFO DegCIconInfo(23, 9, degCIcon);
|
||||
|
||||
const uint8_t PROGMEM degFIcon[] =
|
||||
{
|
||||
0x07, 0x00, 0x00, // ###
|
||||
0x18, 0xC1, 0x9E, // ## ## ## ####
|
||||
0x27, 0x22, 0x50, // # ### # # # #
|
||||
0x4F, 0x92, 0x50, // # ##### # # # #
|
||||
0x8F, 0x89, 0x9C, // # ##### # ## ###
|
||||
0x4F, 0x90, 0x10, // # ##### # #
|
||||
0x27, 0x20, 0x10, // # ### # #
|
||||
0x18, 0xC0, 0x10, // ## ## #
|
||||
0x07, 0x00, 0x00, // ###
|
||||
};
|
||||
const BITMAP_INFO DegFIconInfo(23, 9, degFIcon);
|
||||
|
||||
//
|
||||
// Image data for thermostatC
|
||||
//
|
||||
|
||||
const uint8_t PROGMEM thermostatDegCIcon[] =
|
||||
{
|
||||
0x7F, 0xFF, 0xFC, // #####################
|
||||
0xFF, 0xFF, 0xFE, // #######################
|
||||
0xE0, 0x07, 0xDE, // ### ##### ####
|
||||
0xCC, 0x73, 0x8E, // ## ## ### ### ###
|
||||
0xD2, 0x8B, 0x06, // ## # # # # ## ##
|
||||
0xD2, 0x83, 0xFE, // ## # # # #########
|
||||
0xCC, 0x83, 0xFE, // ## ## # #########
|
||||
0xC0, 0x83, 0x06, // ## # ## ##
|
||||
0xC0, 0x8B, 0x8E, // ## # # ### ###
|
||||
0xC0, 0x73, 0xDE, // ## ### #### ####
|
||||
0xE0, 0x07, 0xFE, // ### ##########
|
||||
0xFF, 0xFF, 0xFE, // #######################
|
||||
0x7F, 0xFF, 0xFC, // #####################
|
||||
};
|
||||
const BITMAP_INFO ThermostatDegCIconInfo(23, 13, thermostatDegCIcon);
|
||||
|
||||
|
||||
//
|
||||
// Image data for thermostatDegF
|
||||
//
|
||||
|
||||
const uint8_t PROGMEM thermostatDegFIcon[] =
|
||||
{
|
||||
0x7F, 0xFF, 0xFC, // #####################
|
||||
0xFF, 0xFF, 0xFE, // #######################
|
||||
0xE0, 0x07, 0xDE, // ### ##### ####
|
||||
0xCC, 0xF3, 0x8E, // ## ## #### ### ###
|
||||
0xD2, 0x83, 0x06, // ## # # # ## ##
|
||||
0xD2, 0x83, 0xFE, // ## # # # #########
|
||||
0xCC, 0xE3, 0xFE, // ## ## ### #########
|
||||
0xC0, 0x83, 0x06, // ## # ## ##
|
||||
0xC0, 0x83, 0x8E, // ## # ### ###
|
||||
0xC0, 0x83, 0xDE, // ## # #### ####
|
||||
0xE0, 0x07, 0xFE, // ### ##########
|
||||
0xFF, 0xFF, 0xFE, // #######################
|
||||
0x7F, 0xFF, 0xFC, // #####################
|
||||
};
|
||||
const BITMAP_INFO ThermostatDegFIconInfo(23, 13, thermostatDegFIcon);
|
||||
|
||||
//
|
||||
// Image data for thermostatHz
|
||||
//
|
||||
|
||||
const uint8_t PROGMEM thermostatHzIcon[] =
|
||||
{
|
||||
0x7F, 0xFF, 0xFC, // #####################
|
||||
0xFF, 0xFF, 0xFE, // #######################
|
||||
0xE0, 0x07, 0xDE, // ### ##### ####
|
||||
0xC9, 0x03, 0x8E, // ## # # ### ###
|
||||
0xC9, 0x03, 0x06, // ## # # ## ##
|
||||
0xC9, 0x73, 0xFE, // ## # # ### #########
|
||||
0xCF, 0x13, 0xFE, // ## #### # #########
|
||||
0xC9, 0x23, 0x06, // ## # # # ## ##
|
||||
0xC9, 0x43, 0x8E, // ## # # # ### ###
|
||||
0xC9, 0x73, 0xDE, // ## # # ### #### ####
|
||||
0xE0, 0x07, 0xFE, // ### ##########
|
||||
0xFF, 0xFF, 0xFE, // #######################
|
||||
0x7F, 0xFF, 0xFC, // #####################
|
||||
};
|
||||
const BITMAP_INFO ThermostatHzIconInfo(23, 13, thermostatHzIcon);
|
||||
|
||||
|
||||
//
|
||||
// Image data for reset
|
||||
//
|
||||
|
||||
const uint8_t PROGMEM resetIcon[] =
|
||||
{
|
||||
0x9E, 0x00, 0x00, // # ####
|
||||
0xA1, 0x07, 0x00, // # # # ###
|
||||
0xC0, 0x88, 0x80, // ## # # #
|
||||
0xF0, 0x49, 0x80, // #### # # ##
|
||||
0x00, 0x4A, 0x80, // # # # #
|
||||
0x00, 0x4C, 0x80, // # ## #
|
||||
0x00, 0x48, 0x80, // # # #
|
||||
0x40, 0x87, 0x00, // # # ###
|
||||
0x21, 0x00, 0x00, // # #
|
||||
0x1E, 0x00, 0x00, // ####
|
||||
};
|
||||
const BITMAP_INFO resetIconInfo(17, 10, resetIcon);
|
||||
|
||||
//
|
||||
// Image data for miniThermo
|
||||
//
|
||||
|
||||
const uint8_t PROGMEM miniThermoIcon[] =
|
||||
{
|
||||
0x30, // ##
|
||||
0x48, // # #
|
||||
0x48, // # #
|
||||
0x48, // # #
|
||||
0x48, // # #
|
||||
0x48, // # #
|
||||
0x48, // # #
|
||||
0x48, // # #
|
||||
0x78, // ####
|
||||
0xFC, // ######
|
||||
0xFC, // ######
|
||||
0xFC, // ######
|
||||
0x78, // ####
|
||||
};
|
||||
const BITMAP_INFO miniThermoIconInfo(6, 13, miniThermoIcon);
|
||||
|
||||
|
|
|
@ -65,8 +65,8 @@ extern const BITMAP_INFO FanIcon4Info;
|
|||
|
||||
// 'FuelIcon', 7x12px
|
||||
extern const BITMAP_INFO FuelIconInfo;
|
||||
extern const BITMAP_INFO FuelIconSmallInfo;
|
||||
|
||||
// 'Target', 13x13px
|
||||
extern const BITMAP_INFO TargetIconInfo;
|
||||
|
||||
extern const BITMAP_INFO RepeatIconInfo;
|
||||
|
@ -77,6 +77,8 @@ extern const BITMAP_INFO LargeTimerIconInfo;
|
|||
extern const BITMAP_INFO VerticalRepeatIconInfo;
|
||||
|
||||
extern const BITMAP_INFO CrossLgIconInfo;
|
||||
extern const BITMAP_INFO CrossIconInfo
|
||||
;
|
||||
|
||||
// Bitmap for open
|
||||
extern const BITMAP_INFO OpenIconInfo;
|
||||
|
@ -130,3 +132,10 @@ extern const BITMAP_INFO UpdateIconInfo;
|
|||
extern const BITMAP_INFO WWWIconInfo;
|
||||
|
||||
extern const BITMAP_INFO BowserIconInfo;
|
||||
extern const BITMAP_INFO DegCIconInfo;
|
||||
extern const BITMAP_INFO DegFIconInfo;
|
||||
extern const BITMAP_INFO ThermostatDegCIconInfo;
|
||||
extern const BITMAP_INFO ThermostatDegFIconInfo;
|
||||
extern const BITMAP_INFO ThermostatHzIconInfo;
|
||||
extern const BITMAP_INFO resetIconInfo;
|
||||
extern const BITMAP_INFO miniThermoIconInfo;
|
||||
|
|
|
@ -368,7 +368,7 @@ const char* Errstates [] PROGMEM = {
|
|||
"Flame out", // [9] E-08
|
||||
"Temp sense", // [10] E-09
|
||||
"Ignition fail", // [11] E-10 SmartError manufactured state - sensing runstate 2 -> >5
|
||||
"Failed 1st ignition attempt", // [12] E-11 SmartError manufactured state - sensing runstate 2 -> 3
|
||||
"Failed 1st ignite", // [12] E-11 SmartError manufactured state - sensing runstate 2 -> 3
|
||||
"Unknown error?" // mystery code!
|
||||
};
|
||||
|
||||
|
@ -385,7 +385,7 @@ const char* ErrstatesEx [] PROGMEM = {
|
|||
"E-08: Flame out", // [9] E-08
|
||||
"E-09: Temp sense", // [10] E-09
|
||||
"E-10: Ignition fail", // [11] E-10 SmartError manufactured state - sensing runstate 2 -> >5
|
||||
"E-11: Failed 1st ignition attempt", // [12] E-11 SmartError manufactured state - sensing runstate 2 -> 3
|
||||
"E-11: Failed 1st ignite", // [12] E-11 SmartError manufactured state - sensing runstate 2 -> 3
|
||||
"Unknown error?" // mystery code!
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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) 2019 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
|
||||
|
@ -21,6 +21,10 @@
|
|||
|
||||
#include "SmartError.h"
|
||||
#include "TxManage.h"
|
||||
#include "../Utility/helpers.h"
|
||||
#include "../Utility/macros.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/DataFilter.h"
|
||||
|
||||
CSmartError::CSmartError()
|
||||
{
|
||||
|
@ -83,12 +87,12 @@ CSmartError::monitor(uint8_t newRunState)
|
|||
else if(newRunState > 5) {
|
||||
// transitioned from preheat to post glow
|
||||
// - second ignition attempt failed, heater is shutting down
|
||||
m_Error = 11;
|
||||
m_Error = 11; // +1 over displayed error code
|
||||
}
|
||||
else if(newRunState == 3) {
|
||||
// transitioned from preheat to retry
|
||||
// - first ignition attempt failed, heater will retry
|
||||
m_Error = 12;
|
||||
m_Error = 12; // +1 over displayed error code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +113,23 @@ CSmartError::monitor(uint8_t newRunState)
|
|||
m_prevRunState = newRunState;
|
||||
}
|
||||
|
||||
bool
|
||||
CSmartError::checkVolts(float ipVolts, float glowI)
|
||||
{
|
||||
// check for low voltage
|
||||
// values here are x10 integers
|
||||
if(NVstore.getHeaterTuning().lowVolts) { // only if enabled
|
||||
float cableComp = glowI * 0.1; // allow 1V drop for 10A current (bit naive but better than no compensation)
|
||||
float Thresh = NVstore.getHeaterTuning().getLVC() - cableComp; // NVstore
|
||||
if(ipVolts < Thresh) {
|
||||
m_Error = 2; // +1 over displayed error code
|
||||
requestOff();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// return our smart error, if it exists, as the registered code
|
||||
uint8_t
|
||||
CSmartError::getError()
|
||||
|
|
|
@ -31,6 +31,7 @@ public:
|
|||
void inhibit();
|
||||
void monitor(const CProtocol& heaterFrame);
|
||||
void monitor(uint8_t runstate);
|
||||
bool checkVolts(float volts, float plugI);
|
||||
uint8_t getError();
|
||||
};
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ RTC_DS3231Ex::readData(uint8_t* pData, int len, int ofs) {
|
|||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
RTC_DS3231Ex::resetLostPower()
|
||||
{
|
||||
Wire.beginTransmission(DS3231_ADDRESS);
|
||||
|
|
|
@ -30,7 +30,7 @@ class RTC_DS3231Ex : public RTC_DS3231 {
|
|||
public:
|
||||
void writeData(uint8_t* pData, int len, int ofs=0);
|
||||
void readData(uint8_t* pData, int len, int ofs=0);
|
||||
bool resetLostPower();
|
||||
void resetLostPower();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -277,7 +277,29 @@ void interpretJsonCommand(char* pLine)
|
|||
sHeaterTuning ht = NVstore.getHeaterTuning();
|
||||
ht.pumpCal = fCal;
|
||||
NVstore.setHeaterTuning(ht);
|
||||
NVstore.save();
|
||||
}
|
||||
}
|
||||
else if(strcmp("TempOffset", it->key) == 0) {
|
||||
float fCal = it->value.as<float>();
|
||||
if(INBOUNDS(fCal, -10.0, +10.0)) {
|
||||
sHeaterTuning ht = NVstore.getHeaterTuning();
|
||||
ht.tempOfs = fCal;
|
||||
NVstore.setHeaterTuning(ht);
|
||||
}
|
||||
}
|
||||
else if(strcmp("LowVoltCutout", it->key) == 0) {
|
||||
float fCal = it->value.as<float>();
|
||||
if(fCal != 0) {
|
||||
bool bOK = false;
|
||||
if(NVstore.getHeaterTuning().sysVoltage == 120)
|
||||
bOK = INBOUNDS(fCal, 10.0, 12.5);
|
||||
else
|
||||
bOK = INBOUNDS(fCal, 20.0, 25.0);
|
||||
if(bOK) {
|
||||
sHeaterTuning ht = NVstore.getHeaterTuning();
|
||||
ht.lowVolts = uint8_t(fCal * 10);
|
||||
NVstore.setHeaterTuning(ht);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +347,7 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len)
|
|||
bSend |= moderator.addJson("FanRPM", getFanSpeed(), root );
|
||||
bSend |= moderator.addJson("FanVoltage", getHeaterInfo().getFan_Voltage(), root );
|
||||
bSend |= moderator.addJson("FanSensor", getHeaterInfo().getFan_Sensor(), root );
|
||||
bSend |= moderator.addJson("InputVoltage", getBatteryVoltage(), root );
|
||||
bSend |= moderator.addJson("InputVoltage", getBatteryVoltage(false), root );
|
||||
bSend |= moderator.addJson("SystemVoltage", getHeaterInfo().getSystemVoltage(), root );
|
||||
bSend |= moderator.addJson("GlowVoltage", getGlowVolts(), root );
|
||||
bSend |= moderator.addJson("GlowCurrent", getGlowCurrent(), root );
|
||||
|
@ -356,7 +378,9 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len)
|
|||
bSend |= moderator.addJson("CyclicOff", stop, root); // threshold of over temp for cyclic mode
|
||||
bSend |= moderator.addJson("CyclicOn", NVstore.getUserSettings().cyclic.Start, root); // threshold of under temp for cyclic mode
|
||||
bSend |= moderator.addJson("PumpCount", RTC_Store.getFuelGauge(), root); // running count of pump strokes
|
||||
bSend |= moderator.addJson("PumpCal", NVstore.getHeaterTuning().pumpCal, root); // ml/stroke
|
||||
bSend |= moderator.addJson("PumpCal", NVstore.getHeaterTuning().pumpCal, root); // mL/stroke
|
||||
bSend |= moderator.addJson("TempOffset", NVstore.getHeaterTuning().tempOfs, root); // degC offset
|
||||
bSend |= moderator.addJson("LowVoltCutout", NVstore.getHeaterTuning().getLVC(), root); // low volatge cutout
|
||||
|
||||
if(bSend) {
|
||||
root.printTo(opStr, len);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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) 2019 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
|
||||
|
@ -44,6 +44,11 @@ struct sFilteredData {
|
|||
CExpMean GlowAmps;
|
||||
CExpMean Fan;
|
||||
CExpMean AmbientTemp;
|
||||
CExpMean FastipVolts;
|
||||
CExpMean FastGlowAmps;
|
||||
};
|
||||
|
||||
extern sFilteredData FilteredSamples;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,13 @@ CFuelGauge::init(float fuelUsed)
|
|||
_lastStoredVal = _pumpStrokes;
|
||||
}
|
||||
|
||||
void
|
||||
CFuelGauge::reset()
|
||||
{
|
||||
_pumpStrokes = 0;
|
||||
_lastStoredVal = _pumpStrokes;
|
||||
RTC_Store.setFuelGauge(_pumpStrokes); // uses RTC registers to store this
|
||||
}
|
||||
|
||||
void
|
||||
CFuelGauge::Integrate(float Hz)
|
||||
|
@ -66,5 +73,11 @@ CFuelGauge::Integrate(float Hz)
|
|||
float
|
||||
CFuelGauge::Used_mL()
|
||||
{
|
||||
return _pumpStrokes * _pumpCal; // strokes * mL / stroke
|
||||
return _pumpStrokes * _pumpCal; // strokes * millilitre / stroke
|
||||
}
|
||||
|
||||
float
|
||||
CFuelGauge::Used_strokes()
|
||||
{
|
||||
return _pumpStrokes;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,12 @@ class CFuelGauge {
|
|||
public:
|
||||
CFuelGauge();
|
||||
void init(float fuelUsed = 0);
|
||||
void reset();
|
||||
void Integrate(float Hz);
|
||||
float Used_mL();
|
||||
float Used_strokes();
|
||||
};
|
||||
|
||||
extern CFuelGauge FuelGauge;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -97,6 +97,11 @@ sHeaterTuning::setSysVoltage(float fVal)
|
|||
}
|
||||
}
|
||||
|
||||
float
|
||||
sHeaterTuning::getLVC() const
|
||||
{
|
||||
return lowVolts * 0.1;
|
||||
}
|
||||
|
||||
void
|
||||
CHeaterStorage::getTimerInfo(int idx, sTimer& timerInfo)
|
||||
|
@ -235,7 +240,12 @@ sHeaterTuning::load()
|
|||
validatedLoad("systemVoltage", sysVoltage, 120, u8Match2, 120, 240);
|
||||
validatedLoad("fanSensor", fanSensor, 1, u8inBounds, 1, 2);
|
||||
validatedLoad("glowDrive", glowDrive, 5, u8inBounds, 1, 6);
|
||||
if(sysVoltage == 120)
|
||||
validatedLoad("lowVolts", lowVolts, 115, u8inBounds, 100, 125);
|
||||
else
|
||||
validatedLoad("lowVolts", lowVolts, 230, u8inBounds, 200, 250);
|
||||
validatedLoad("pumpCal", pumpCal, 0.02, 0.001, 1);
|
||||
validatedLoad("tempOfs", tempOfs, 0.0, -10.0, +10.0);
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
|
@ -252,7 +262,9 @@ sHeaterTuning::save()
|
|||
preferences.putUChar("systemVoltage", sysVoltage);
|
||||
preferences.putUChar("fanSensor", fanSensor);
|
||||
preferences.putUChar("glowDrive", glowDrive);
|
||||
preferences.putUChar("lowVolts", lowVolts);
|
||||
preferences.putFloat("pumpCal", pumpCal);
|
||||
preferences.putFloat("tempOfs", tempOfs);
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,12 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
uint8_t Pmax;
|
||||
uint16_t Fmin;
|
||||
uint16_t Fmax;
|
||||
uint8_t sysVoltage;
|
||||
uint8_t sysVoltage; // x10
|
||||
uint8_t fanSensor;
|
||||
uint8_t glowDrive;
|
||||
uint8_t lowVolts; // x10
|
||||
float pumpCal;
|
||||
float tempOfs;
|
||||
|
||||
bool valid() {
|
||||
bool retval = true;
|
||||
|
@ -52,6 +54,11 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
retval &= fanSensor == 1 || fanSensor == 2;
|
||||
retval &= INBOUNDS(glowDrive, 1, 6);
|
||||
retval &= INBOUNDS(pumpCal, 0.001, 1.0);
|
||||
if(sysVoltage == 120)
|
||||
retval &= INBOUNDS(lowVolts, 100, 125);
|
||||
else
|
||||
retval &= INBOUNDS(lowVolts, 200, 250);
|
||||
retval &= INBOUNDS(tempOfs, -10, +10);
|
||||
return retval;
|
||||
};
|
||||
void init() {
|
||||
|
@ -63,6 +70,8 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
fanSensor = 1;
|
||||
glowDrive = 5;
|
||||
pumpCal = 0.02;
|
||||
lowVolts = 115;
|
||||
tempOfs = 0;
|
||||
};
|
||||
void load();
|
||||
void save();
|
||||
|
@ -75,6 +84,8 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
fanSensor = rhs.fanSensor;
|
||||
glowDrive = rhs.glowDrive;
|
||||
pumpCal = rhs.pumpCal;
|
||||
lowVolts = rhs.lowVolts;
|
||||
tempOfs = rhs.tempOfs;
|
||||
return *this;
|
||||
}
|
||||
float getPmin() const;
|
||||
|
@ -82,6 +93,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
void setPmin(float val);
|
||||
void setPmax(float val);
|
||||
void setSysVoltage(float val);
|
||||
float getLVC() const;
|
||||
};
|
||||
|
||||
struct sHomeMenuActions {
|
||||
|
@ -108,6 +120,11 @@ struct sHomeMenuActions {
|
|||
}
|
||||
};
|
||||
|
||||
struct sHourMeter {
|
||||
unsigned long RunTime;
|
||||
unsigned long GlowTime;
|
||||
};
|
||||
|
||||
struct sCyclicThermostat {
|
||||
int8_t Stop;
|
||||
int8_t Start;
|
||||
|
|
|
@ -152,6 +152,12 @@ struct CRect {
|
|||
CRect() {
|
||||
xPos = yPos = width = height = 0;
|
||||
}
|
||||
CRect(const CRect& a) {
|
||||
xPos = a.xPos;
|
||||
yPos = a.yPos;
|
||||
width = a.width;
|
||||
height = a.height;
|
||||
}
|
||||
void Expand(int val) {
|
||||
xPos -= val;
|
||||
yPos -= val;
|
||||
|
|
|
@ -78,19 +78,12 @@ extern void setUploadSize(long val);
|
|||
extern void getGPIOinfo(sGPIO& info);
|
||||
extern void simulateGPIOin(uint8_t newKey);
|
||||
extern void setDegFMode(bool state);
|
||||
extern float getBatteryVoltage();
|
||||
extern float getBatteryVoltage(bool fast);
|
||||
extern float getGlowVolts();
|
||||
extern float getGlowCurrent();
|
||||
extern float getFanSpeed();
|
||||
extern int sysUptime();
|
||||
|
||||
/* extern void setFuelGauge_RTC(float val);
|
||||
extern void getFuelGauge_RTC(float& val);
|
||||
extern void setDesiredTemp_RTC(uint8_t val);
|
||||
extern void getDesiredTemp_RTC(uint8_t& val);
|
||||
extern void setDesiredPump_RTC(uint8_t val);
|
||||
extern void getDesiredPump_RTC(uint8_t& val);*/
|
||||
|
||||
|
||||
extern void ShowOTAScreen(int percent=0, eOTAmodes updateType=eOTAnormal);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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) 2019 Ray Jones <ray@mrjones.id.au>
|
||||
* Copyright (C) 2018 James Clark
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
|
@ -23,12 +23,12 @@
|
|||
#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 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)))
|
||||
#define BOUNDSLIMIT(A, B, C) if((A) < (B)) (A) = (B); if((A) > (C)) (A) = (C)
|
||||
#define BOUNDSLIMIT(A, B, C) { if((A) < (B)) (A) = (B); if((A) > (C)) (A) = (C); }
|
||||
|
||||
#endif
|