Added Low Volt Cutout, Temperature probe offset
Tarted up fuel mixture adjust screen
This commit is contained in:
parent
dd5e62c8cb
commit
06e69acc77
|
@ -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());
|
||||
|
@ -796,6 +801,9 @@ void loop()
|
|||
updateFilteredData();
|
||||
FuelGauge.Integrate(HeaterFrame2.getPump_Actual());
|
||||
}
|
||||
if(INBOUNDS(HeaterFrame2.getRunState(), 1, 5)) { // check for Low Voltage Cutout
|
||||
SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
|
||||
}
|
||||
updateJSONclients(bReportJSONData);
|
||||
CommState.set(CommStates::Idle);
|
||||
NVstore.doSave(); // now is a good time to store to the NV storage, well away from any blue wire activity
|
||||
|
@ -822,7 +830,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,8 +891,10 @@ 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 +1051,7 @@ float getTemperatureDesired()
|
|||
|
||||
float getTemperatureSensor()
|
||||
{
|
||||
return FilteredSamples.AmbientTemp.getValue();
|
||||
return FilteredSamples.AmbientTemp.getValue() + NVstore.getHeaterTuning().tempOfs;
|
||||
}
|
||||
|
||||
void setPumpMin(float val)
|
||||
|
@ -1449,11 +1459,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
|
||||
}
|
||||
|
@ -1491,6 +1504,8 @@ void updateFilteredData()
|
|||
FilteredSamples.GlowVolts.update(HeaterFrame2.getGlowPlug_Voltage());
|
||||
FilteredSamples.GlowAmps.update(HeaterFrame2.getGlowPlug_Current());
|
||||
FilteredSamples.Fan.update(HeaterFrame2.getFan_Actual());
|
||||
FilteredSamples.FastipVolts.update(HeaterFrame2.getVoltage_Supply());
|
||||
FilteredSamples.FastGlowAmps.update(HeaterFrame2.getGlowPlug_Current());
|
||||
}
|
||||
|
||||
int sysUptime()
|
||||
|
|
|
@ -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.....
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 102 B After Width: | Height: | Size: 198 B |
Binary file not shown.
Before Width: | Height: | Size: 126 B After Width: | Height: | Size: 110 B |
Binary file not shown.
After Width: | Height: | Size: 154 B |
Binary file not shown.
After Width: | Height: | Size: 170 B |
|
@ -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());
|
||||
|
@ -796,6 +801,9 @@ void loop()
|
|||
updateFilteredData();
|
||||
FuelGauge.Integrate(HeaterFrame2.getPump_Actual());
|
||||
}
|
||||
if(INBOUNDS(HeaterFrame2.getRunState(), 1, 5)) { // check for Low Voltage Cutout
|
||||
SmartError.checkVolts(FilteredSamples.FastipVolts.getValue(), FilteredSamples.FastGlowAmps.getValue());
|
||||
}
|
||||
updateJSONclients(bReportJSONData);
|
||||
CommState.set(CommStates::Idle);
|
||||
NVstore.doSave(); // now is a good time to store to the NV storage, well away from any blue wire activity
|
||||
|
@ -822,7 +830,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,8 +891,10 @@ 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 +1051,7 @@ float getTemperatureDesired()
|
|||
|
||||
float getTemperatureSensor()
|
||||
{
|
||||
return FilteredSamples.AmbientTemp.getValue();
|
||||
return FilteredSamples.AmbientTemp.getValue() + NVstore.getHeaterTuning().tempOfs;
|
||||
}
|
||||
|
||||
void setPumpMin(float val)
|
||||
|
@ -1449,11 +1459,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
|
||||
}
|
||||
|
@ -1491,6 +1504,8 @@ void updateFilteredData()
|
|||
FilteredSamples.GlowVolts.update(HeaterFrame2.getGlowPlug_Voltage());
|
||||
FilteredSamples.GlowAmps.update(HeaterFrame2.getGlowPlug_Current());
|
||||
FilteredSamples.Fan.update(HeaterFrame2.getFan_Actual());
|
||||
FilteredSamples.FastipVolts.update(HeaterFrame2.getVoltage_Supply());
|
||||
FilteredSamples.FastGlowAmps.update(HeaterFrame2.getGlowPlug_Current());
|
||||
}
|
||||
|
||||
int sysUptime()
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -82,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();
|
||||
|
@ -133,7 +133,7 @@ CDetailedScreen::show()
|
|||
}
|
||||
|
||||
if(!bGlowActive) {
|
||||
showBowser(FuelGauge.Used_ml());
|
||||
showBowser(FuelGauge.Used_mL());
|
||||
}
|
||||
showRunState(runstate, errstate);
|
||||
return true;
|
||||
|
|
|
@ -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,11 +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"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -264,6 +266,8 @@ CFuelCalScreen::CFuelCalScreen(C128x64_OLED& display, CScreenManager& mgr) : CPa
|
|||
{
|
||||
_initUI();
|
||||
_mlPerStroke = 0.02;
|
||||
_LVC = 115;
|
||||
_tOfs = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -272,6 +276,8 @@ CFuelCalScreen::onSelect()
|
|||
CPasswordScreen::onSelect();
|
||||
_initUI();
|
||||
_mlPerStroke = NVstore.getHeaterTuning().pumpCal;
|
||||
_LVC = NVstore.getHeaterTuning().lowVolts;
|
||||
_tOfs = NVstore.getHeaterTuning().tempOfs;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -285,7 +291,10 @@ bool
|
|||
CFuelCalScreen::show()
|
||||
{
|
||||
char msg[20];
|
||||
_display.clearDisplay();
|
||||
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"
|
||||
|
||||
|
@ -295,13 +304,31 @@ CFuelCalScreen::show()
|
|||
_printMenuText(_display.xCentre(), 43, "confirm save", false, eCentreJustify);
|
||||
}
|
||||
else {
|
||||
int col = 80;
|
||||
_printInverted(_display.xCentre(), 0, " Fuel Calibration ", true, eCentreJustify);
|
||||
_printMenuText(col, Line1, "ml / stroke:", false, eRightJustify);
|
||||
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+1, Line1, msg, _rowSel == 1);
|
||||
_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
|
||||
int yPos = 53;
|
||||
yPos = 53;
|
||||
int xPos = _display.xCentre();
|
||||
|
||||
switch(_rowSel) {
|
||||
|
@ -324,43 +351,44 @@ CFuelCalScreen::show()
|
|||
bool
|
||||
CFuelCalScreen::animate()
|
||||
{
|
||||
/* char msg[16];
|
||||
|
||||
if(isPasswordBusy() || (_rowSel == 4)) { // Password screen activity
|
||||
_printMenuText(Column, Line2, " ");
|
||||
_printMenuText(Column, Line1, " ");
|
||||
if(_rowSel == 4)
|
||||
_printMenuText(_display.xCentre(), 43, "Confirm save", false, eCentreJustify);
|
||||
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;
|
||||
}
|
||||
else {
|
||||
|
||||
_animateCount++;
|
||||
WRAPUPPERLIMIT(_animateCount, 9, 0);
|
||||
|
||||
if(_rowSel == 1) {
|
||||
_display.drawRect(Column-border, Line1-border, 34, 8+2*border, BLACK);
|
||||
_display.drawRoundRect(Column-border, Line1-border, 34, 8+2*border, radius, WHITE);
|
||||
}
|
||||
else {
|
||||
_printMenuText(Column, Line1, " ");
|
||||
}
|
||||
|
||||
if(_animateCount < 4)
|
||||
sprintf(msg, "PF-%d ", _glowDrive);
|
||||
else
|
||||
sprintf(msg, "(%dW)", plugPowers[_glowDrive-1]);
|
||||
_printMenuText(Column, Line1, msg);
|
||||
|
||||
int xPos = Column;
|
||||
_printMenuText(xPos, Line2, " ", _rowSel == 2); // erase, but create selection loop
|
||||
if(_animateCount < 4) {
|
||||
sprintf(msg, "SN-%d", _fanSensor);
|
||||
_printMenuText(Column, Line2, msg);
|
||||
}
|
||||
else {
|
||||
sprintf(msg, "(\365%d)", _fanSensor); // \365 is division character
|
||||
_printMenuText(xPos, Line2, msg);
|
||||
}
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -370,6 +398,15 @@ 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) {
|
||||
|
@ -418,9 +455,13 @@ CFuelCalScreen::keyHandler(uint8_t event)
|
|||
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;
|
||||
|
@ -436,6 +477,8 @@ CFuelCalScreen::keyHandler(uint8_t event)
|
|||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
_animateCount = -1;
|
||||
_display.clearDisplay();
|
||||
_rowSel = 4;
|
||||
break;
|
||||
}
|
||||
|
@ -452,10 +495,34 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,19 +45,4 @@ public:
|
|||
void onSelect();
|
||||
};
|
||||
|
||||
class CFuelCalScreen : public CPasswordScreen
|
||||
{
|
||||
int _rowSel;
|
||||
void _adjust(int dir);
|
||||
float _mlPerStroke;
|
||||
int _animateCount;
|
||||
void _initUI();
|
||||
public:
|
||||
CFuelCalScreen(C128x64_OLED& display, CScreenManager& mgr);
|
||||
bool show();
|
||||
bool animate();
|
||||
bool keyHandler(uint8_t event);
|
||||
void onSelect();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ CPrimingScreen::CPrimingScreen(C128x64_OLED& display, CScreenManager& mgr) : CSc
|
|||
void
|
||||
CPrimingScreen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
_stopPump();
|
||||
_initUI();
|
||||
}
|
||||
|
@ -69,7 +70,7 @@ CPrimingScreen::_initUI()
|
|||
bool
|
||||
CPrimingScreen::show()
|
||||
{
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
CRect extents;
|
||||
|
||||
|
@ -200,7 +201,7 @@ CPrimingScreen::show()
|
|||
}
|
||||
else {
|
||||
char msg[16];
|
||||
sprintf(msg, "%.02fL", FuelGauge.Used_ml() * 0.001);
|
||||
sprintf(msg, "%.02fL", FuelGauge.Used_mL() * 0.001);
|
||||
_printMenuText(loc.xPos+1, midline+3, msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ CScreen::show()
|
|||
void
|
||||
CScreen::onSelect()
|
||||
{
|
||||
_display.clearDisplay();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,7 +66,7 @@ CSettingsScreen::show()
|
|||
{
|
||||
char str[16];
|
||||
|
||||
CScreenHeader::show();
|
||||
CScreenHeader::show(false);
|
||||
|
||||
_display.writeFillRect(0, 16, 84, 12, WHITE);
|
||||
_printInverted(3, 18, "Heater Tuning", true);
|
||||
|
|
|
@ -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, // #####
|
||||
|
@ -1083,3 +1102,25 @@ const uint8_t PROGMEM resetIcon[] =
|
|||
};
|
||||
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,7 +77,8 @@ extern const BITMAP_INFO LargeTimerIconInfo;
|
|||
extern const BITMAP_INFO VerticalRepeatIconInfo;
|
||||
|
||||
extern const BITMAP_INFO CrossLgIconInfo;
|
||||
extern const BITMAP_INFO CrossIconInfo;
|
||||
extern const BITMAP_INFO CrossIconInfo
|
||||
;
|
||||
|
||||
// Bitmap for open
|
||||
extern const BITMAP_INFO OpenIconInfo;
|
||||
|
@ -137,3 +138,4 @@ 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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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 = fCal;
|
||||
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().lowVolts, 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
|
||||
|
|
|
@ -71,7 +71,7 @@ CFuelGauge::Integrate(float Hz)
|
|||
}
|
||||
|
||||
float
|
||||
CFuelGauge::Used_ml()
|
||||
CFuelGauge::Used_mL()
|
||||
{
|
||||
return _pumpStrokes * _pumpCal; // strokes * millilitre / stroke
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
void init(float fuelUsed = 0);
|
||||
void reset();
|
||||
void Integrate(float Hz);
|
||||
float Used_ml();
|
||||
float Used_mL();
|
||||
float Used_strokes();
|
||||
};
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue