Added Temp Probe selection screen, mapping sensors to user preferences
This commit is contained in:
parent
de9417ff73
commit
8fb1981552
|
@ -482,6 +482,10 @@ void setup() {
|
|||
pHourMeter->init(bESP32PowerUpInit || RTC_Store.getBootInit()); // ensure persistent memory variable are reset after powerup, or OTA update
|
||||
RTC_Store.setBootInit(false);
|
||||
|
||||
TempSensor.mapSensor(0, NVstore.getHeaterTuning().tempProbe[0].romCode);
|
||||
TempSensor.mapSensor(1, NVstore.getHeaterTuning().tempProbe[1].romCode);
|
||||
TempSensor.mapSensor(2, NVstore.getHeaterTuning().tempProbe[2].romCode);
|
||||
|
||||
delay(1000); // just to hold the splash screeen for while
|
||||
}
|
||||
|
||||
|
@ -799,7 +803,9 @@ void loop()
|
|||
if(tDelta > MIN_TEMPERATURE_INTERVAL) { // maintain a minimum holdoff period
|
||||
lastTemperatureTime = millis(); // reset time to observe temeprature
|
||||
|
||||
if(TempSensor.readTemperature(fTemperature)) {
|
||||
TempSensor.readSensors();
|
||||
// TempSensor.checkNumSensors();
|
||||
if(TempSensor.getTemperature(fTemperature)) { // get Primary sensor temeprature
|
||||
if(DS18B20holdoff) {
|
||||
DS18B20holdoff--;
|
||||
DebugPort.printf("Skipped initial DS18B20 reading: %f\r\n", fTemperature);
|
||||
|
@ -1125,7 +1131,8 @@ float getTemperatureDesired()
|
|||
|
||||
float getTemperatureSensor()
|
||||
{
|
||||
return FilteredSamples.AmbientTemp.getValue() + NVstore.getHeaterTuning().tempOfs;
|
||||
// NVstore always holds primary sensor as index 0
|
||||
return FilteredSamples.AmbientTemp.getValue() + NVstore.getHeaterTuning().tempProbe[0].offset;
|
||||
}
|
||||
|
||||
void setPumpMin(float val)
|
||||
|
|
371
src/OLED/DS18B20Screen.cpp
Normal file
371
src/OLED/DS18B20Screen.cpp
Normal file
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "128x64OLED.h"
|
||||
#include "DS18B20Screen.h"
|
||||
#include "KeyPad.h"
|
||||
#include "fonts/Icons.h"
|
||||
#include "fonts/MiniFont.h"
|
||||
#include "Utility/TempSense.h"
|
||||
|
||||
extern CTempSense TempSensor;
|
||||
|
||||
|
||||
CDS18B20Screen::CDS18B20Screen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
|
||||
{
|
||||
_nNumSensors = 0;
|
||||
for(int i=0; i<3; i++) {
|
||||
_sensorRole[i] = -1;
|
||||
_Offset[i] = 0;
|
||||
}
|
||||
_initUI();
|
||||
}
|
||||
|
||||
void
|
||||
CDS18B20Screen::onSelect()
|
||||
{
|
||||
CScreenHeader::onSelect();
|
||||
_initUI();
|
||||
_nNumSensors = TempSensor.getNumSensors();
|
||||
_readNV();
|
||||
}
|
||||
|
||||
void
|
||||
CDS18B20Screen::_initUI()
|
||||
{
|
||||
_rowSel = 0;
|
||||
_colSel = 0;
|
||||
_keyHold = -1;
|
||||
_scrollChar = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
CDS18B20Screen::show()
|
||||
{
|
||||
char msg[32];
|
||||
|
||||
_display.clearDisplay();
|
||||
|
||||
if(!CPasswordScreen::show()) { // for showing "saving settings"
|
||||
|
||||
if(_rowSel == SaveConfirm) {
|
||||
_showConfirmMessage();
|
||||
}
|
||||
else {
|
||||
if(_colSel == 0)
|
||||
_showTitle("Temp Sensor Role");
|
||||
else
|
||||
_showTitle("Temp Sensor Offset");
|
||||
|
||||
int baseLine = 40;
|
||||
switch(_nNumSensors) {
|
||||
case 1: baseLine = 18; break;
|
||||
case 2: baseLine = 30; break;
|
||||
}
|
||||
for(int i = 0; i<_nNumSensors; i++) {
|
||||
|
||||
switch(_sensorRole[i]) {
|
||||
case 0: strcpy(msg, "Pri"); break;
|
||||
case 1: strcpy(msg, "Sec"); break;
|
||||
case 2: strcpy(msg, "Ter"); break;
|
||||
default: strcpy(msg, " ? "); break;
|
||||
}
|
||||
_printMenuText(border, baseLine-i*12, msg, _rowSel == (i+1) && _colSel == 0);
|
||||
|
||||
OneWireBus_ROMCode romCode;
|
||||
if(!TempSensor.getRomCodeIdx(romCode, i)) {
|
||||
strcpy(msg, "missing?") ;
|
||||
}
|
||||
else {
|
||||
char* buffer = msg;
|
||||
for (int j = 5; j >= 0; j--) {
|
||||
sprintf(buffer, "%02X%s", romCode.fields.serial_number[j], j ? ":" : "");
|
||||
buffer += 3;
|
||||
}
|
||||
}
|
||||
{
|
||||
CTransientFont AF(_display, &miniFontInfo);
|
||||
_printMenuText(27, baseLine+2-i*12, msg);
|
||||
}
|
||||
|
||||
if(_colSel == 0) {
|
||||
float temperature;
|
||||
TempSensor.getTemperatureIdx(temperature, i);
|
||||
sprintf(msg, "%.01fC", temperature + _Offset[i]);
|
||||
}
|
||||
else {
|
||||
sprintf(msg, "%+.01f", _Offset[i]);
|
||||
}
|
||||
_printMenuText(90, baseLine-i*12, msg, _rowSel == (i+1) && _colSel == 1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CDS18B20Screen::animate()
|
||||
{
|
||||
if(!CPasswordScreen::_busy() && !CPasswordScreen::isPasswordBusy()) {
|
||||
if(_rowSel != SaveConfirm) {
|
||||
const char* pMsg = NULL;
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_printMenuText(_display.xCentre(), 52, " \021 \030Edit Exit \020 ", true, eCentreJustify);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if(_colSel == 0)
|
||||
pMsg = " Hold Right to adjust probe offset. ";
|
||||
else
|
||||
pMsg = " Hold Left to select probe's role. ";
|
||||
break;
|
||||
}
|
||||
if(pMsg != NULL) {
|
||||
_display.drawFastHLine(0, 52, 128, WHITE);
|
||||
_scrollMessage(56, pMsg, _scrollChar);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDS18B20Screen::keyHandler(uint8_t event)
|
||||
{
|
||||
if(CPasswordScreen::keyHandler(event)) {
|
||||
if(_isPasswordOK()) {
|
||||
_rowSel = 1;
|
||||
_keyHold = -1;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
sUserSettings us;
|
||||
if(event & keyPressed) {
|
||||
_keyHold = 0;
|
||||
// UP press
|
||||
if(event & key_Up) {
|
||||
if(_rowSel == SaveConfirm) {
|
||||
_enableStoringMessage();
|
||||
_saveNV();
|
||||
NVstore.save();
|
||||
TempSensor.mapSensor(-1); // reset existing mapping
|
||||
TempSensor.mapSensor(0, NVstore.getHeaterTuning().tempProbe[0].romCode);
|
||||
TempSensor.mapSensor(1, NVstore.getHeaterTuning().tempProbe[1].romCode);
|
||||
TempSensor.mapSensor(2, NVstore.getHeaterTuning().tempProbe[2].romCode);
|
||||
TempSensor.mapSensor(-2); // report mapping
|
||||
_rowSel = 0;
|
||||
}
|
||||
else {
|
||||
if(_rowSel == 0) {
|
||||
_getPassword();
|
||||
if(_isPasswordOK()) {
|
||||
_rowSel = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_testCancel();
|
||||
_rowSel++;
|
||||
UPPERLIMIT(_rowSel, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
// DOWN press
|
||||
if(event & key_Down) {
|
||||
_testCancel();
|
||||
if(_rowSel == SaveConfirm)
|
||||
_rowSel = 0;
|
||||
_rowSel--;
|
||||
LOWERLIMIT(_rowSel, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(event & keyRepeat) {
|
||||
if(_keyHold >= 0) {
|
||||
_keyHold++;
|
||||
if(_keyHold == 2) {
|
||||
if(event & key_Left) {
|
||||
_colSel = 0;
|
||||
_scrollChar = 0;
|
||||
}
|
||||
if(event & key_Right) {
|
||||
_colSel = 1;
|
||||
_scrollChar = 0;
|
||||
}
|
||||
if(event & key_Centre) {
|
||||
if(_colSel == 0)
|
||||
_sensorRole[_rowSel-1] = -1;
|
||||
else
|
||||
_Offset[_rowSel-1] = 0;
|
||||
}
|
||||
_keyHold = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(event & keyReleased) {
|
||||
if(_keyHold == 0) {
|
||||
// LEFT press
|
||||
if(event & key_Left) {
|
||||
if(_rowSel == 0)
|
||||
_ScreenManager.prevMenu();
|
||||
else
|
||||
adjust(-1);
|
||||
}
|
||||
// RIGHT press
|
||||
if(event & key_Right) {
|
||||
if(_rowSel == 0)
|
||||
_ScreenManager.nextMenu();
|
||||
else
|
||||
adjust(+1);
|
||||
}
|
||||
// CENTRE press
|
||||
if(event & key_Centre) {
|
||||
if(_rowSel == 0) {
|
||||
_ScreenManager.selectMenu(CScreenManager::RootMenuLoop); // force return to main menu
|
||||
}
|
||||
else {
|
||||
_rowSel = SaveConfirm;
|
||||
}
|
||||
}
|
||||
}
|
||||
_keyHold = -1;
|
||||
}
|
||||
|
||||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CDS18B20Screen::adjust(int dir)
|
||||
{
|
||||
switch(_rowSel) {
|
||||
case 1:
|
||||
if(_colSel == 0) {
|
||||
_sensorRole[0] += dir;
|
||||
WRAPLIMITS(_sensorRole[0], 0, _nNumSensors-1);
|
||||
if(_nNumSensors == 2)
|
||||
_sensorRole[1] = _sensorRole[0] == 0 ? 1 : 0;
|
||||
}
|
||||
else {
|
||||
_Offset[0] += dir * 0.1;
|
||||
BOUNDSLIMIT(_Offset[0], -10, +10);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(_colSel == 0) {
|
||||
_sensorRole[1] += dir;
|
||||
WRAPLIMITS(_sensorRole[1], 0, _nNumSensors-1);
|
||||
if(_nNumSensors == 2)
|
||||
_sensorRole[0] = _sensorRole[1] == 0 ? 1 : 0;
|
||||
}
|
||||
else {
|
||||
_Offset[1] += dir * 0.1;
|
||||
BOUNDSLIMIT(_Offset[1], -10, +10);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if(_colSel == 0) {
|
||||
_sensorRole[2] += dir;
|
||||
WRAPLIMITS(_sensorRole[2], 0, _nNumSensors-1);
|
||||
}
|
||||
else {
|
||||
_Offset[2] += dir * 0.1;
|
||||
BOUNDSLIMIT(_Offset[2], -10, +10);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CDS18B20Screen::_testCancel()
|
||||
{
|
||||
switch(_rowSel) {
|
||||
case 1:
|
||||
if(_sensorRole[1] == _sensorRole[0]) _sensorRole[1] = -1;
|
||||
if(_sensorRole[2] == _sensorRole[0]) _sensorRole[2] = -1;
|
||||
break;
|
||||
case 2:
|
||||
if(_sensorRole[0] == _sensorRole[1]) _sensorRole[0] = -1;
|
||||
if(_sensorRole[2] == _sensorRole[1]) _sensorRole[2] = -1;
|
||||
break;
|
||||
case 3:
|
||||
if(_sensorRole[0] == _sensorRole[2]) _sensorRole[0] = -1;
|
||||
if(_sensorRole[1] == _sensorRole[2]) _sensorRole[1] = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CDS18B20Screen::_readNV()
|
||||
{
|
||||
_sensorRole[0] = _sensorRole[1] = _sensorRole[2] = -1;
|
||||
|
||||
const sHeaterTuning& tuning = NVstore.getHeaterTuning();
|
||||
|
||||
for(int sensor = 0; sensor < TempSensor.getNumSensors(); sensor++) {
|
||||
OneWireBus_ROMCode romCode;
|
||||
TempSensor.getRomCodeIdx(romCode, sensor); // get rom code of each attached sensor
|
||||
// NV storage indices are the sensor role
|
||||
// ie 0 is normal thermostat
|
||||
// scan the NV store and match the stored romCodes
|
||||
// if not matched, the sensor remains unmapped
|
||||
for(int i=0; i< 3; i++) {
|
||||
if(memcmp(tuning.tempProbe[i].romCode.bytes, romCode.bytes, 8) == 0) {
|
||||
_sensorRole[sensor] = i; // assign role to sensor according to NV placement
|
||||
_Offset[sensor] = tuning.tempProbe[i].offset;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
DebugPort.printf("Sensor roles: %d, %d, %d\r\n", _sensorRole[0], _sensorRole[1], _sensorRole[2]);
|
||||
}
|
||||
|
||||
void
|
||||
CDS18B20Screen::_saveNV()
|
||||
{
|
||||
sHeaterTuning tuning = NVstore.getHeaterTuning();
|
||||
for(int i=0; i<3; i++) {
|
||||
memset(tuning.tempProbe[i].romCode.bytes, 0, 8);
|
||||
tuning.tempProbe[i].offset = 0;
|
||||
}
|
||||
|
||||
for(int sensor = 0; sensor < TempSensor.getNumSensors(); sensor++) {
|
||||
int role = _sensorRole[sensor]; // role of probe determines placement in NV storage
|
||||
if(role != -1) {
|
||||
tuning.tempProbe[role].offset = _Offset[sensor];
|
||||
OneWireBus_ROMCode romCode;
|
||||
TempSensor.getRomCodeIdx(romCode, sensor); // get rom code of indexed sensor
|
||||
memcpy(tuning.tempProbe[role].romCode.bytes, romCode.bytes, 8);
|
||||
}
|
||||
}
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
}
|
53
src/OLED/DS18B20Screen.h
Normal file
53
src/OLED/DS18B20Screen.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* 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
|
||||
* 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 __DS18B20SCREEN_H__
|
||||
#define __DS18B20SCREEN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "PasswordScreen.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
|
||||
class C128x64_OLED;
|
||||
class CScreenManager;
|
||||
|
||||
class CDS18B20Screen : public CPasswordScreen
|
||||
{
|
||||
int _rowSel, _colSel;
|
||||
int _keyHold;
|
||||
int _scrollChar;
|
||||
int _nNumSensors;
|
||||
int _sensorRole[3];
|
||||
float _Offset[3];
|
||||
void _initUI();
|
||||
void _testCancel();
|
||||
void _readNV();
|
||||
void _saveNV();
|
||||
public:
|
||||
CDS18B20Screen(C128x64_OLED& display, CScreenManager& mgr);
|
||||
bool show();
|
||||
bool animate();
|
||||
bool keyHandler(uint8_t event);
|
||||
void onSelect();
|
||||
void adjust(int dir);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -48,7 +48,7 @@ CFuelCalScreen::onSelect()
|
|||
_initUI();
|
||||
_mlPerStroke = NVstore.getHeaterTuning().pumpCal;
|
||||
_LVC = NVstore.getHeaterTuning().lowVolts;
|
||||
_tOfs = NVstore.getHeaterTuning().tempOfs;
|
||||
_tOfs = NVstore.getHeaterTuning().tempProbe[0].offset;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -231,7 +231,7 @@ CFuelCalScreen::keyHandler(uint8_t event)
|
|||
tuning = NVstore.getHeaterTuning();
|
||||
tuning.pumpCal = _mlPerStroke;
|
||||
tuning.lowVolts = _LVC;
|
||||
tuning.tempOfs = _tOfs;
|
||||
tuning.tempProbe[0].offset = _tOfs;
|
||||
NVstore.setHeaterTuning(tuning);
|
||||
saveNV();
|
||||
_rowSel = 0;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "BTScreen.h"
|
||||
#include "MenuTrunkScreen.h"
|
||||
#include "MQTTScreen.h"
|
||||
#include "DS18B20Screen.h"
|
||||
#include <Wire.h>
|
||||
#include "../cfg/pins.h"
|
||||
#include "../cfg/BTCConfig.h"
|
||||
|
@ -486,6 +487,7 @@ CScreenManager::_loadScreens()
|
|||
menuloop.push_back(new CWiFiScreen(*_pDisplay, *this));
|
||||
menuloop.push_back(new CMQTTScreen(*_pDisplay, *this));
|
||||
menuloop.push_back(new CBTScreen(*_pDisplay, *this));
|
||||
menuloop.push_back(new CDS18B20Screen(*_pDisplay, *this));
|
||||
_Screens.push_back(menuloop);
|
||||
}
|
||||
|
||||
|
|
|
@ -168,6 +168,16 @@ const uint8_t miniFontBitmaps[] PROGMEM =
|
|||
// @81 ':' (1 pixel wide)
|
||||
0x50, // # #
|
||||
|
||||
// @82 'b' (3 pixels wide)
|
||||
0x38, // ###
|
||||
0x28, // # #
|
||||
0xf8, // #####
|
||||
|
||||
// @85 'd' (3 pixels wide)
|
||||
0xf8, // #####
|
||||
0x28, // # #
|
||||
0x38, // ###
|
||||
|
||||
};
|
||||
|
||||
// Character descriptors for a 3x5 font
|
||||
|
@ -194,9 +204,9 @@ const FONT_CHAR_INFO miniFontDescriptors[] PROGMEM =
|
|||
{0, 0, 0}, // '?'
|
||||
{0, 0, 0}, // '@'
|
||||
{3, 5, 33}, // 'A'
|
||||
{0, 0, 0}, // 'B'
|
||||
{3, 5, 82}, // 'B'
|
||||
{3, 5, 36}, // 'C'
|
||||
{0, 0, 0}, // 'D'
|
||||
{3, 5, 85}, // 'D'
|
||||
{3, 5, 72}, // 'E'
|
||||
{3, 5, 39}, // 'F'
|
||||
{3, 5, 42}, // 'G'
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
#include "../Protocol/Protocol.h"
|
||||
#include <string.h>
|
||||
#include "HourMeter.h"
|
||||
#include "Utility/TempSense.h"
|
||||
|
||||
extern CTempSense TempSensor;
|
||||
extern CModerator MQTTmoderator;
|
||||
|
||||
char defaultJSONstr[64];
|
||||
|
@ -143,6 +145,22 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len)
|
|||
if(tidyTemp > -80) {
|
||||
bSend |= moderator.addJson("TempCurrent", tidyTemp, root);
|
||||
}
|
||||
if(TempSensor.getNumSensors() > 1) {
|
||||
TempSensor.getTemperature(tidyTemp, 1);
|
||||
tidyTemp += NVstore.getHeaterTuning().tempProbe[1].offset;
|
||||
tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution
|
||||
if(tidyTemp > -80) {
|
||||
bSend |= moderator.addJson("Temp2Current", tidyTemp, root);
|
||||
}
|
||||
if(TempSensor.getNumSensors() > 2) {
|
||||
TempSensor.getTemperature(tidyTemp, 2);
|
||||
tidyTemp += NVstore.getHeaterTuning().tempProbe[2].offset;
|
||||
tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution
|
||||
if(tidyTemp > -80) {
|
||||
bSend |= moderator.addJson("Temp3Current", tidyTemp, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
bSend |= moderator.addJson("TempDesired", getTemperatureDesired(), root);
|
||||
bSend |= moderator.addJson("TempMode", NVstore.getUserSettings().degF, root);
|
||||
if(NVstore.getUserSettings().menuMode < 2) {
|
||||
|
@ -196,9 +214,14 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len)
|
|||
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("LowVoltCutout", NVstore.getHeaterTuning().getLVC(), root); // low volatge cutout
|
||||
bSend |= moderator.addJson("LowVoltCutout", NVstore.getHeaterTuning().getLVC(), root); // low voltage cutout
|
||||
}
|
||||
bSend |= moderator.addJson("TempOffset", NVstore.getHeaterTuning().tempProbe[0].offset, root); // degC offset
|
||||
if(TempSensor.getNumSensors() > 1) {
|
||||
bSend |= moderator.addJson("Temp2Offset", NVstore.getHeaterTuning().tempProbe[1].offset, root); // degC offset
|
||||
if(TempSensor.getNumSensors() > 2)
|
||||
bSend |= moderator.addJson("Temp3Offset", NVstore.getHeaterTuning().tempProbe[2].offset, root); // degC offset
|
||||
}
|
||||
bSend |= moderator.addJson("TempOffset", NVstore.getHeaterTuning().tempOfs, root); // degC offset
|
||||
|
||||
if(bSend) {
|
||||
root.printTo(opStr, len);
|
||||
|
|
|
@ -265,8 +265,25 @@ sHeaterTuning::load()
|
|||
else
|
||||
validatedLoad("lowVolts", lowVolts, 230, u8inBoundsOrZero, 200, 250);
|
||||
validatedLoad("pumpCal", pumpCal, 0.02, 0.001, 1);
|
||||
validatedLoad("tempOfs", tempOfs, 0.0, -10.0, +10.0);
|
||||
validatedLoad("tempOffset0", tempProbe[0].offset, 0.0, -10.0, +10.0);
|
||||
validatedLoad("tempOffset1", tempProbe[1].offset, 0.0, -10.0, +10.0);
|
||||
validatedLoad("tempOffset2", tempProbe[2].offset, 0.0, -10.0, +10.0);
|
||||
preferences.getBytes("probeSerial0", tempProbe[0].romCode.bytes, 8);
|
||||
preferences.getBytes("probeSerial1", tempProbe[1].romCode.bytes, 8);
|
||||
preferences.getBytes("probeSerial2", tempProbe[2].romCode.bytes, 8);
|
||||
preferences.end();
|
||||
|
||||
for(int i=0; i<3; i++) {
|
||||
DebugPort.printf("Rd Probe[%d] %02X:%02X:%02X:%02X:%02X:%02X\r\n",
|
||||
i,
|
||||
tempProbe[i].romCode.fields.serial_number[5],
|
||||
tempProbe[i].romCode.fields.serial_number[4],
|
||||
tempProbe[i].romCode.fields.serial_number[3],
|
||||
tempProbe[i].romCode.fields.serial_number[2],
|
||||
tempProbe[i].romCode.fields.serial_number[1],
|
||||
tempProbe[i].romCode.fields.serial_number[0]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -284,8 +301,25 @@ sHeaterTuning::save()
|
|||
preferences.putUChar("glowDrive", glowDrive);
|
||||
preferences.putUChar("lowVolts", lowVolts);
|
||||
preferences.putFloat("pumpCal", pumpCal);
|
||||
preferences.putFloat("tempOfs", tempOfs);
|
||||
preferences.putFloat("tempOffset0", tempProbe[0].offset);
|
||||
preferences.putFloat("tempOffset1", tempProbe[1].offset);
|
||||
preferences.putFloat("tempOffset2", tempProbe[2].offset);
|
||||
preferences.putBytes("probeSerial0", tempProbe[0].romCode.bytes, 8);
|
||||
preferences.putBytes("probeSerial1", tempProbe[1].romCode.bytes, 8);
|
||||
preferences.putBytes("probeSerial2", tempProbe[2].romCode.bytes, 8);
|
||||
preferences.end();
|
||||
|
||||
for(int i=0; i<3; i++) {
|
||||
DebugPort.printf("Wr Probe[%d] %02X:%02X:%02X:%02X:%02X:%02X\r\n",
|
||||
i,
|
||||
tempProbe[i].romCode.fields.serial_number[5],
|
||||
tempProbe[i].romCode.fields.serial_number[4],
|
||||
tempProbe[i].romCode.fields.serial_number[3],
|
||||
tempProbe[i].romCode.fields.serial_number[2],
|
||||
tempProbe[i].romCode.fields.serial_number[1],
|
||||
tempProbe[i].romCode.fields.serial_number[0]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -25,12 +25,17 @@
|
|||
#include "BTC_GPIO.h"
|
||||
#include "NVCore.h"
|
||||
#include "../Utility/helpers.h"
|
||||
#include "Utility/TempSense.h"
|
||||
|
||||
#include "../RTC/Timers.h" // for sTimer
|
||||
|
||||
void toggle(bool& ref);
|
||||
void toggle(uint8_t& ref);
|
||||
|
||||
struct sProbeTuning {
|
||||
float offset;
|
||||
OneWireBus_ROMCode romCode;
|
||||
};
|
||||
|
||||
struct sHeaterTuning : public CESP32_NVStorage {
|
||||
uint8_t Pmin;
|
||||
|
@ -42,7 +47,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
uint8_t glowDrive;
|
||||
uint8_t lowVolts; // x10
|
||||
float pumpCal;
|
||||
float tempOfs;
|
||||
sProbeTuning tempProbe[3]; // [0],[1],[2] - Primary, Secondary, Tertiary
|
||||
|
||||
bool valid() {
|
||||
bool retval = true;
|
||||
|
@ -58,7 +63,9 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
retval &= INBOUNDS(lowVolts, 100, 125) || (lowVolts == 0);
|
||||
else
|
||||
retval &= INBOUNDS(lowVolts, 200, 250 || (lowVolts == 0));
|
||||
retval &= INBOUNDS(tempOfs, -10, +10);
|
||||
retval &= INBOUNDS(tempProbe[0].offset, -10, +10);
|
||||
retval &= INBOUNDS(tempProbe[1].offset, -10, +10);
|
||||
retval &= INBOUNDS(tempProbe[2].offset, -10, +10);
|
||||
return retval;
|
||||
};
|
||||
void init() {
|
||||
|
@ -71,7 +78,12 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
glowDrive = 5;
|
||||
pumpCal = 0.02;
|
||||
lowVolts = 115;
|
||||
tempOfs = 0;
|
||||
tempProbe[0].offset = 0;
|
||||
tempProbe[1].offset = 0;
|
||||
tempProbe[2].offset = 0;
|
||||
memset(tempProbe[0].romCode.bytes, 0, sizeof(tempProbe[0].romCode));
|
||||
memset(tempProbe[1].romCode.bytes, 0, sizeof(tempProbe[1].romCode));
|
||||
memset(tempProbe[2].romCode.bytes, 0, sizeof(tempProbe[1].romCode));
|
||||
};
|
||||
void load();
|
||||
void save();
|
||||
|
@ -85,7 +97,12 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
glowDrive = rhs.glowDrive;
|
||||
pumpCal = rhs.pumpCal;
|
||||
lowVolts = rhs.lowVolts;
|
||||
tempOfs = rhs.tempOfs;
|
||||
tempProbe[0].offset = rhs.tempProbe[0].offset;
|
||||
tempProbe[1].offset = rhs.tempProbe[1].offset;
|
||||
tempProbe[2].offset = rhs.tempProbe[2].offset;
|
||||
memcpy(tempProbe[0].romCode.bytes, rhs.tempProbe[0].romCode.bytes, 8);
|
||||
memcpy(tempProbe[1].romCode.bytes, rhs.tempProbe[1].romCode.bytes, 8);
|
||||
memcpy(tempProbe[2].romCode.bytes, rhs.tempProbe[2].romCode.bytes, 8);
|
||||
return *this;
|
||||
}
|
||||
float getPmin() const;
|
||||
|
|
|
@ -23,13 +23,19 @@
|
|||
|
||||
#include "TempSense.h"
|
||||
#include "DebugPort.h"
|
||||
#include "macros.h"
|
||||
|
||||
CTempSense::CTempSense()
|
||||
{
|
||||
_TempSensor = NULL;
|
||||
_owb = NULL;
|
||||
_nNumSensors = 0;
|
||||
for(int i=0; i< MAX_DS18B20_DEVICES; i++)
|
||||
_Sensors[i] = NULL;
|
||||
for(int i=0; i<3; i++)
|
||||
_sensorMap[i] = -1;
|
||||
}
|
||||
|
||||
#ifdef SINGLE_DS18B20_SENSOR
|
||||
void CTempSense::begin(int pin)
|
||||
{
|
||||
// initialise DS18B20 sensor interface
|
||||
|
@ -48,27 +54,24 @@ void CTempSense::begin(int pin)
|
|||
attach();
|
||||
}
|
||||
}
|
||||
/*void CTempSense::begin(int pin)
|
||||
#else
|
||||
void CTempSense::begin(int pin)
|
||||
{
|
||||
// initialise DS18B20 sensor interface
|
||||
|
||||
// create one wire bus interface, using RMT peripheral
|
||||
_owb = owb_rmt_initialize(&_rmt_driver_info, pin, RMT_CHANNEL_1, RMT_CHANNEL_0);
|
||||
owb_use_crc(_owb, true); // enable CRC check for ROM code
|
||||
|
||||
bool found = find();
|
||||
|
||||
readROMcode();
|
||||
|
||||
// Create DS18B20 device on the 1-Wire bus
|
||||
if(found) {
|
||||
attach();
|
||||
}
|
||||
find();
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifdef SINGLE_DS18B20_SENSOR
|
||||
bool
|
||||
CTempSense::readTemperature(float& tempReading)
|
||||
CTempSense::readSensors(float& tempReading)
|
||||
{
|
||||
if(_TempSensor == NULL) {
|
||||
if(_Sensors[0] == NULL) {
|
||||
|
||||
// bool found = find();
|
||||
bool found = readROMcode();
|
||||
|
@ -85,8 +88,8 @@ CTempSense::readTemperature(float& tempReading)
|
|||
}
|
||||
}
|
||||
|
||||
if(_TempSensor != NULL) {
|
||||
DS18B20_ERROR error = ds18b20_read_temp(_TempSensor, &tempReading);
|
||||
if(_Sensors[0] != NULL) {
|
||||
DS18B20_ERROR error = ds18b20_read_temp(_Sensors[0], &tempReading);
|
||||
// DebugPort.printf(">>>> DS18B20 = %f, error=%d\r\n", fTemperature, error);
|
||||
|
||||
if(error == DS18B20_OK) {
|
||||
|
@ -94,63 +97,134 @@ CTempSense::readTemperature(float& tempReading)
|
|||
}
|
||||
else {
|
||||
DebugPort.println("\007DS18B20 sensor removed?");
|
||||
ds18b20_free(&_TempSensor);
|
||||
ds18b20_free(&_Sensors[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/*bool
|
||||
CTempSense::readTemperature(float& tempReading)
|
||||
#else
|
||||
bool
|
||||
CTempSense::readSensors()
|
||||
{
|
||||
if(_TempSensor == NULL) {
|
||||
bool retval = false;
|
||||
|
||||
if(_nNumSensors == 0) {
|
||||
|
||||
bool found = find();
|
||||
|
||||
if(found) {
|
||||
DebugPort.println("Found DS18B20 device");
|
||||
|
||||
readROMcode();
|
||||
|
||||
attach();
|
||||
DebugPort.println("Found DS18B20 device(s)");
|
||||
|
||||
startConvert(); // request a new conversion,
|
||||
waitConvertDone();
|
||||
}
|
||||
}
|
||||
|
||||
if(_TempSensor != NULL) {
|
||||
DS18B20_ERROR error = ds18b20_read_temp(_TempSensor, &tempReading);
|
||||
// DebugPort.printf(">>>> DS18B20 = %f, error=%d\r\n", fTemperature, error);
|
||||
|
||||
if(error == DS18B20_OK) {
|
||||
return true;
|
||||
if(_nNumSensors) {
|
||||
for (int i = 0; i < MAX_DS18B20_DEVICES; ++i) {
|
||||
_Errors[i] = DS18B20_ERROR_UNKNOWN;
|
||||
}
|
||||
else {
|
||||
DebugPort.println("\007DS18B20 sensor removed?");
|
||||
ds18b20_free(&_TempSensor);
|
||||
|
||||
for (int i = 0; i < _nNumSensors; ++i) {
|
||||
_Errors[i] = ds18b20_read_temp(_Sensors[i], &_Readings[i]);
|
||||
}
|
||||
|
||||
#ifdef REPORT_READINGS
|
||||
DebugPort.println("\nTemperature readings (degrees C)");
|
||||
#endif
|
||||
for (int i = 0; i < _nNumSensors; ++i) {
|
||||
if(_Errors[i] == DS18B20_OK) {
|
||||
#ifdef REPORT_READINGS
|
||||
DebugPort.printf(" %d: %.1f OK\r\n", i, _Readings[i]);
|
||||
#endif
|
||||
retval = true; // at least one sensor read OK
|
||||
}
|
||||
else {
|
||||
#ifdef REPORT_READINGS
|
||||
DebugPort.printf("\007 %d: DS18B20 sensor removed?\r\n", i);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return retval;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifdef SINGLE_DS18B20_SENSOR
|
||||
bool
|
||||
CTempSense::find()
|
||||
{
|
||||
// Find all connected devices
|
||||
// DebugPort.printf("Finding one wire bus devices...");
|
||||
_nNumSensors = 0;
|
||||
OneWireBus_SearchState search_state = {0};
|
||||
bool found = false;
|
||||
owb_search_first(_owb, &search_state, &found);
|
||||
if(found)
|
||||
if(found) {
|
||||
_nNumSensors = 1;
|
||||
DebugPort.println("Found a one wire device");
|
||||
}
|
||||
else
|
||||
DebugPort.println("No one wire devices found!!");
|
||||
|
||||
return found;
|
||||
}
|
||||
#else
|
||||
bool
|
||||
CTempSense::find()
|
||||
{
|
||||
// Find all connected devices
|
||||
DebugPort.println("Finding one wire bus devices...");
|
||||
memset(_device_rom_codes, 0, sizeof(_device_rom_codes));
|
||||
_nNumSensors = 0;
|
||||
OneWireBus_SearchState search_state = {0};
|
||||
|
||||
bool found = false;
|
||||
owb_search_first(_owb, &search_state, &found);
|
||||
while(found) {
|
||||
char rom_code_s[17];
|
||||
owb_string_from_rom_code(search_state.rom_code, rom_code_s, sizeof(rom_code_s));
|
||||
DebugPort.printf(" %d : %s\r\n", _nNumSensors, rom_code_s);
|
||||
|
||||
_device_rom_codes[_nNumSensors] = search_state.rom_code;
|
||||
_nNumSensors++;
|
||||
owb_search_next(_owb, &search_state, &found);
|
||||
}
|
||||
DebugPort.printf("Found %d device%s\r\n", _nNumSensors, _nNumSensors==1 ? "" : "s");
|
||||
|
||||
// Create DS18B20 devices on the 1-Wire bus
|
||||
for (int i = 0; i < MAX_DS18B20_DEVICES; ++i) {
|
||||
if(_Sensors[i]) {
|
||||
ds18b20_free(&_Sensors[i]);
|
||||
}
|
||||
_Sensors[i] = NULL;
|
||||
}
|
||||
for (int i = 0; i < _nNumSensors; ++i)
|
||||
{
|
||||
DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation
|
||||
_Sensors[i] = ds18b20_info;
|
||||
|
||||
if (_nNumSensors == 1)
|
||||
{
|
||||
printf("Single device optimisations enabled\n");
|
||||
ds18b20_init_solo(ds18b20_info, _owb); // only one device on bus
|
||||
}
|
||||
else
|
||||
{
|
||||
ds18b20_init(ds18b20_info, _owb, _device_rom_codes[i]); // associate with bus and device
|
||||
}
|
||||
ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings
|
||||
ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION_12_BIT);
|
||||
}
|
||||
|
||||
|
||||
return found;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SINGLE_DS18B20_SENSOR
|
||||
bool
|
||||
CTempSense::readROMcode()
|
||||
{
|
||||
|
@ -174,28 +248,104 @@ CTempSense::readROMcode()
|
|||
bool
|
||||
CTempSense::attach()
|
||||
{
|
||||
if(_TempSensor == NULL) {
|
||||
_TempSensor = ds18b20_malloc(); // heap allocation
|
||||
if(_Sensors[0] == NULL) {
|
||||
_Sensors[0] = ds18b20_malloc(); // heap allocation
|
||||
|
||||
DebugPort.printf("Single device optimisations enabled\r\n");
|
||||
ds18b20_init_solo(_TempSensor, _owb); // only one device on bus
|
||||
ds18b20_use_crc(_TempSensor, true); // enable CRC check for temperature readings
|
||||
ds18b20_set_resolution(_TempSensor, DS18B20_RESOLUTION_12_BIT);
|
||||
ds18b20_init_solo(_Sensors[0], _owb); // only one device on bus
|
||||
ds18b20_use_crc(_Sensors[0], true); // enable CRC check for temperature readings
|
||||
ds18b20_set_resolution(_Sensors[0], DS18B20_RESOLUTION_12_BIT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
CTempSense::startConvert()
|
||||
{
|
||||
// kick off the initial temperature conversion
|
||||
if(_TempSensor)
|
||||
ds18b20_convert(_TempSensor);
|
||||
if(_Sensors[0])
|
||||
ds18b20_convert_all(_owb);
|
||||
}
|
||||
|
||||
void
|
||||
CTempSense::waitConvertDone()
|
||||
{
|
||||
if(_TempSensor)
|
||||
ds18b20_wait_for_conversion(_TempSensor);
|
||||
if(_Sensors[0])
|
||||
ds18b20_wait_for_conversion(_Sensors[0]);
|
||||
}
|
||||
|
||||
int
|
||||
CTempSense::checkNumSensors() const
|
||||
{
|
||||
long start = millis();
|
||||
bool found = false;
|
||||
int numSensors = 0;
|
||||
OneWireBus_SearchState search_state = {0};
|
||||
owb_search_first(_owb, &search_state, &found);
|
||||
while(found) {
|
||||
numSensors++;
|
||||
owb_search_next(_owb, &search_state, &found);
|
||||
}
|
||||
DebugPort.printf("Found %d one-wire device%s\r\n", numSensors, numSensors==1 ? "" : "s");
|
||||
long tDelta = millis() - start;
|
||||
DebugPort.printf("checkNumSensors: %ldms\r\n", tDelta);
|
||||
return numSensors;
|
||||
}
|
||||
|
||||
bool
|
||||
CTempSense::mapSensor(int idx, OneWireBus_ROMCode romCode)
|
||||
{
|
||||
if(idx == -1) {
|
||||
_sensorMap[0] = _sensorMap[1] = _sensorMap[2] = -1;
|
||||
return false;
|
||||
}
|
||||
if(idx == -2) {
|
||||
DebugPort.printf("Sensor Map: %d %d %d\r\n",
|
||||
_sensorMap[0], _sensorMap[1], _sensorMap[2]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!INBOUNDS(idx, 0, 2))
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < _nNumSensors; i++) {
|
||||
if(memcmp(_Sensors[i]->rom_code.bytes, romCode.bytes, 8) == 0) {
|
||||
_sensorMap[idx] = i;
|
||||
DebugPort.printf("Mapped DS18B20 %02X:%02X:%02X:%02X:%02X:%02X as role %d\r\n",
|
||||
romCode.fields.serial_number[5], romCode.fields.serial_number[4], romCode.fields.serial_number[3],
|
||||
romCode.fields.serial_number[2], romCode.fields.serial_number[1], romCode.fields.serial_number[0],
|
||||
idx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CTempSense::getTemperature(float& temperature, int mapIdx)
|
||||
{
|
||||
int idx = _sensorMap[mapIdx];
|
||||
if(idx < 0)
|
||||
return getTemperatureIdx(temperature, 0); // default to sensor 0 if not mapped
|
||||
// temperature = _Readings[idx];
|
||||
// return _Errors[idx] == DS18B20_OK;
|
||||
return getTemperatureIdx(temperature, idx);
|
||||
}
|
||||
|
||||
bool
|
||||
CTempSense::getTemperatureIdx(float& temperature, int idx)
|
||||
{
|
||||
temperature = _Readings[idx];
|
||||
return _Errors[idx] == DS18B20_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
CTempSense::getRomCodeIdx(OneWireBus_ROMCode& romCode, int idx)
|
||||
{
|
||||
if(idx >= _nNumSensors)
|
||||
return false;
|
||||
romCode = _Sensors[idx]->rom_code;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,22 +24,40 @@
|
|||
|
||||
#include "../../lib/esp32-ds18b20/ds18b20.h"
|
||||
|
||||
//#define SINGLE_DS18B20_SENSOR
|
||||
|
||||
const int MAX_DS18B20_DEVICES = 3;
|
||||
|
||||
class CTempSense {
|
||||
|
||||
OneWireBus * _owb;
|
||||
owb_rmt_driver_info _rmt_driver_info;
|
||||
DS18B20_Info * _TempSensor = NULL;
|
||||
DS18B20_Info * _Sensors[MAX_DS18B20_DEVICES];
|
||||
OneWireBus_ROMCode _device_rom_codes[MAX_DS18B20_DEVICES];
|
||||
int _nNumSensors;
|
||||
|
||||
float _Readings[MAX_DS18B20_DEVICES];
|
||||
DS18B20_ERROR _Errors[MAX_DS18B20_DEVICES];
|
||||
|
||||
bool _discover();
|
||||
int _sensorMap[3];
|
||||
public:
|
||||
CTempSense();
|
||||
void begin(int pin);
|
||||
bool find();
|
||||
#ifdef SINGLE_DS18B20_SENSOR
|
||||
bool readROMcode();
|
||||
bool attach();
|
||||
bool readTemperature(float& tempReading);
|
||||
#endif
|
||||
bool readSensors();
|
||||
void startConvert();
|
||||
void waitConvertDone();
|
||||
bool getTemperature(float& tempReading, int mapIdx=0); // indexed as mapped by user
|
||||
bool getTemperatureIdx(float& tempReading, int selSensor=0); // index is discovery order on one-wire bus
|
||||
bool getRomCodeIdx(OneWireBus_ROMCode& romCode, int selSensor=0); // index is discovery order on one-wire bus
|
||||
int checkNumSensors() const;
|
||||
int getNumSensors() const { return _nNumSensors; };
|
||||
bool mapSensor(int idx, OneWireBus_ROMCode romCode = { 0 } );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -340,8 +340,22 @@ void DecodeCmd(const char* cmd, String& payload)
|
|||
}
|
||||
else if(strcmp("TempOffset", cmd) == 0) {
|
||||
sHeaterTuning ht = NVstore.getHeaterTuning();
|
||||
ht.tempOfs = payload.toFloat();
|
||||
if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) {
|
||||
ht.tempProbe[0].offset = payload.toFloat();
|
||||
if(INBOUNDS(ht.tempProbe[0].offset, -10.0, +10.0)) {
|
||||
NVstore.setHeaterTuning(ht);
|
||||
}
|
||||
}
|
||||
else if(strcmp("Temp2Offset", cmd) == 0) {
|
||||
sHeaterTuning ht = NVstore.getHeaterTuning();
|
||||
ht.tempProbe[1].offset = payload.toFloat();
|
||||
if(INBOUNDS(ht.tempProbe[1].offset, -10.0, +10.0)) {
|
||||
NVstore.setHeaterTuning(ht);
|
||||
}
|
||||
}
|
||||
else if(strcmp("Temp3Offset", cmd) == 0) {
|
||||
sHeaterTuning ht = NVstore.getHeaterTuning();
|
||||
ht.tempProbe[2].offset = payload.toFloat();
|
||||
if(INBOUNDS(ht.tempProbe[2].offset, -10.0, +10.0)) {
|
||||
NVstore.setHeaterTuning(ht);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue