Added Temp Probe selection screen, mapping sensors to user preferences
This commit is contained in:
parent
de9417ff73
commit
8fb1981552
12 changed files with 762 additions and 63 deletions
|
@ -482,6 +482,10 @@ void setup() {
|
||||||
pHourMeter->init(bESP32PowerUpInit || RTC_Store.getBootInit()); // ensure persistent memory variable are reset after powerup, or OTA update
|
pHourMeter->init(bESP32PowerUpInit || RTC_Store.getBootInit()); // ensure persistent memory variable are reset after powerup, or OTA update
|
||||||
RTC_Store.setBootInit(false);
|
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
|
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
|
if(tDelta > MIN_TEMPERATURE_INTERVAL) { // maintain a minimum holdoff period
|
||||||
lastTemperatureTime = millis(); // reset time to observe temeprature
|
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) {
|
if(DS18B20holdoff) {
|
||||||
DS18B20holdoff--;
|
DS18B20holdoff--;
|
||||||
DebugPort.printf("Skipped initial DS18B20 reading: %f\r\n", fTemperature);
|
DebugPort.printf("Skipped initial DS18B20 reading: %f\r\n", fTemperature);
|
||||||
|
@ -1125,7 +1131,8 @@ float getTemperatureDesired()
|
||||||
|
|
||||||
float getTemperatureSensor()
|
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)
|
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();
|
_initUI();
|
||||||
_mlPerStroke = NVstore.getHeaterTuning().pumpCal;
|
_mlPerStroke = NVstore.getHeaterTuning().pumpCal;
|
||||||
_LVC = NVstore.getHeaterTuning().lowVolts;
|
_LVC = NVstore.getHeaterTuning().lowVolts;
|
||||||
_tOfs = NVstore.getHeaterTuning().tempOfs;
|
_tOfs = NVstore.getHeaterTuning().tempProbe[0].offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -231,7 +231,7 @@ CFuelCalScreen::keyHandler(uint8_t event)
|
||||||
tuning = NVstore.getHeaterTuning();
|
tuning = NVstore.getHeaterTuning();
|
||||||
tuning.pumpCal = _mlPerStroke;
|
tuning.pumpCal = _mlPerStroke;
|
||||||
tuning.lowVolts = _LVC;
|
tuning.lowVolts = _LVC;
|
||||||
tuning.tempOfs = _tOfs;
|
tuning.tempProbe[0].offset = _tOfs;
|
||||||
NVstore.setHeaterTuning(tuning);
|
NVstore.setHeaterTuning(tuning);
|
||||||
saveNV();
|
saveNV();
|
||||||
_rowSel = 0;
|
_rowSel = 0;
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "BTScreen.h"
|
#include "BTScreen.h"
|
||||||
#include "MenuTrunkScreen.h"
|
#include "MenuTrunkScreen.h"
|
||||||
#include "MQTTScreen.h"
|
#include "MQTTScreen.h"
|
||||||
|
#include "DS18B20Screen.h"
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include "../cfg/pins.h"
|
#include "../cfg/pins.h"
|
||||||
#include "../cfg/BTCConfig.h"
|
#include "../cfg/BTCConfig.h"
|
||||||
|
@ -486,6 +487,7 @@ CScreenManager::_loadScreens()
|
||||||
menuloop.push_back(new CWiFiScreen(*_pDisplay, *this));
|
menuloop.push_back(new CWiFiScreen(*_pDisplay, *this));
|
||||||
menuloop.push_back(new CMQTTScreen(*_pDisplay, *this));
|
menuloop.push_back(new CMQTTScreen(*_pDisplay, *this));
|
||||||
menuloop.push_back(new CBTScreen(*_pDisplay, *this));
|
menuloop.push_back(new CBTScreen(*_pDisplay, *this));
|
||||||
|
menuloop.push_back(new CDS18B20Screen(*_pDisplay, *this));
|
||||||
_Screens.push_back(menuloop);
|
_Screens.push_back(menuloop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,16 @@ const uint8_t miniFontBitmaps[] PROGMEM =
|
||||||
// @81 ':' (1 pixel wide)
|
// @81 ':' (1 pixel wide)
|
||||||
0x50, // # #
|
0x50, // # #
|
||||||
|
|
||||||
|
// @82 'b' (3 pixels wide)
|
||||||
|
0x38, // ###
|
||||||
|
0x28, // # #
|
||||||
|
0xf8, // #####
|
||||||
|
|
||||||
|
// @85 'd' (3 pixels wide)
|
||||||
|
0xf8, // #####
|
||||||
|
0x28, // # #
|
||||||
|
0x38, // ###
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Character descriptors for a 3x5 font
|
// Character descriptors for a 3x5 font
|
||||||
|
@ -194,9 +204,9 @@ const FONT_CHAR_INFO miniFontDescriptors[] PROGMEM =
|
||||||
{0, 0, 0}, // '?'
|
{0, 0, 0}, // '?'
|
||||||
{0, 0, 0}, // '@'
|
{0, 0, 0}, // '@'
|
||||||
{3, 5, 33}, // 'A'
|
{3, 5, 33}, // 'A'
|
||||||
{0, 0, 0}, // 'B'
|
{3, 5, 82}, // 'B'
|
||||||
{3, 5, 36}, // 'C'
|
{3, 5, 36}, // 'C'
|
||||||
{0, 0, 0}, // 'D'
|
{3, 5, 85}, // 'D'
|
||||||
{3, 5, 72}, // 'E'
|
{3, 5, 72}, // 'E'
|
||||||
{3, 5, 39}, // 'F'
|
{3, 5, 39}, // 'F'
|
||||||
{3, 5, 42}, // 'G'
|
{3, 5, 42}, // 'G'
|
||||||
|
|
|
@ -36,7 +36,9 @@
|
||||||
#include "../Protocol/Protocol.h"
|
#include "../Protocol/Protocol.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "HourMeter.h"
|
#include "HourMeter.h"
|
||||||
|
#include "Utility/TempSense.h"
|
||||||
|
|
||||||
|
extern CTempSense TempSensor;
|
||||||
extern CModerator MQTTmoderator;
|
extern CModerator MQTTmoderator;
|
||||||
|
|
||||||
char defaultJSONstr[64];
|
char defaultJSONstr[64];
|
||||||
|
@ -143,6 +145,22 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len)
|
||||||
if(tidyTemp > -80) {
|
if(tidyTemp > -80) {
|
||||||
bSend |= moderator.addJson("TempCurrent", tidyTemp, root);
|
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("TempDesired", getTemperatureDesired(), root);
|
||||||
bSend |= moderator.addJson("TempMode", NVstore.getUserSettings().degF, root);
|
bSend |= moderator.addJson("TempMode", NVstore.getUserSettings().degF, root);
|
||||||
if(NVstore.getUserSettings().menuMode < 2) {
|
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("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("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("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) {
|
if(bSend) {
|
||||||
root.printTo(opStr, len);
|
root.printTo(opStr, len);
|
||||||
|
|
|
@ -265,8 +265,25 @@ sHeaterTuning::load()
|
||||||
else
|
else
|
||||||
validatedLoad("lowVolts", lowVolts, 230, u8inBoundsOrZero, 200, 250);
|
validatedLoad("lowVolts", lowVolts, 230, u8inBoundsOrZero, 200, 250);
|
||||||
validatedLoad("pumpCal", pumpCal, 0.02, 0.001, 1);
|
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();
|
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
|
void
|
||||||
|
@ -284,8 +301,25 @@ sHeaterTuning::save()
|
||||||
preferences.putUChar("glowDrive", glowDrive);
|
preferences.putUChar("glowDrive", glowDrive);
|
||||||
preferences.putUChar("lowVolts", lowVolts);
|
preferences.putUChar("lowVolts", lowVolts);
|
||||||
preferences.putFloat("pumpCal", pumpCal);
|
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();
|
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
|
void
|
||||||
|
|
|
@ -25,12 +25,17 @@
|
||||||
#include "BTC_GPIO.h"
|
#include "BTC_GPIO.h"
|
||||||
#include "NVCore.h"
|
#include "NVCore.h"
|
||||||
#include "../Utility/helpers.h"
|
#include "../Utility/helpers.h"
|
||||||
|
#include "Utility/TempSense.h"
|
||||||
|
|
||||||
#include "../RTC/Timers.h" // for sTimer
|
#include "../RTC/Timers.h" // for sTimer
|
||||||
|
|
||||||
void toggle(bool& ref);
|
void toggle(bool& ref);
|
||||||
void toggle(uint8_t& ref);
|
void toggle(uint8_t& ref);
|
||||||
|
|
||||||
|
struct sProbeTuning {
|
||||||
|
float offset;
|
||||||
|
OneWireBus_ROMCode romCode;
|
||||||
|
};
|
||||||
|
|
||||||
struct sHeaterTuning : public CESP32_NVStorage {
|
struct sHeaterTuning : public CESP32_NVStorage {
|
||||||
uint8_t Pmin;
|
uint8_t Pmin;
|
||||||
|
@ -42,7 +47,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
||||||
uint8_t glowDrive;
|
uint8_t glowDrive;
|
||||||
uint8_t lowVolts; // x10
|
uint8_t lowVolts; // x10
|
||||||
float pumpCal;
|
float pumpCal;
|
||||||
float tempOfs;
|
sProbeTuning tempProbe[3]; // [0],[1],[2] - Primary, Secondary, Tertiary
|
||||||
|
|
||||||
bool valid() {
|
bool valid() {
|
||||||
bool retval = true;
|
bool retval = true;
|
||||||
|
@ -58,7 +63,9 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
||||||
retval &= INBOUNDS(lowVolts, 100, 125) || (lowVolts == 0);
|
retval &= INBOUNDS(lowVolts, 100, 125) || (lowVolts == 0);
|
||||||
else
|
else
|
||||||
retval &= INBOUNDS(lowVolts, 200, 250 || (lowVolts == 0));
|
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;
|
return retval;
|
||||||
};
|
};
|
||||||
void init() {
|
void init() {
|
||||||
|
@ -71,7 +78,12 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
||||||
glowDrive = 5;
|
glowDrive = 5;
|
||||||
pumpCal = 0.02;
|
pumpCal = 0.02;
|
||||||
lowVolts = 115;
|
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 load();
|
||||||
void save();
|
void save();
|
||||||
|
@ -85,7 +97,12 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
||||||
glowDrive = rhs.glowDrive;
|
glowDrive = rhs.glowDrive;
|
||||||
pumpCal = rhs.pumpCal;
|
pumpCal = rhs.pumpCal;
|
||||||
lowVolts = rhs.lowVolts;
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
float getPmin() const;
|
float getPmin() const;
|
||||||
|
|
|
@ -23,13 +23,19 @@
|
||||||
|
|
||||||
#include "TempSense.h"
|
#include "TempSense.h"
|
||||||
#include "DebugPort.h"
|
#include "DebugPort.h"
|
||||||
|
#include "macros.h"
|
||||||
|
|
||||||
CTempSense::CTempSense()
|
CTempSense::CTempSense()
|
||||||
{
|
{
|
||||||
_TempSensor = NULL;
|
|
||||||
_owb = 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)
|
void CTempSense::begin(int pin)
|
||||||
{
|
{
|
||||||
// initialise DS18B20 sensor interface
|
// initialise DS18B20 sensor interface
|
||||||
|
@ -48,27 +54,24 @@ void CTempSense::begin(int pin)
|
||||||
attach();
|
attach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*void CTempSense::begin(int pin)
|
#else
|
||||||
|
void CTempSense::begin(int pin)
|
||||||
{
|
{
|
||||||
// initialise DS18B20 sensor interface
|
// initialise DS18B20 sensor interface
|
||||||
|
|
||||||
// create one wire bus interface, using RMT peripheral
|
// create one wire bus interface, using RMT peripheral
|
||||||
_owb = owb_rmt_initialize(&_rmt_driver_info, pin, RMT_CHANNEL_1, RMT_CHANNEL_0);
|
_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
|
owb_use_crc(_owb, true); // enable CRC check for ROM code
|
||||||
|
|
||||||
bool found = find();
|
find();
|
||||||
|
|
||||||
readROMcode();
|
|
||||||
|
|
||||||
// Create DS18B20 device on the 1-Wire bus
|
|
||||||
if(found) {
|
|
||||||
attach();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
|
#ifdef SINGLE_DS18B20_SENSOR
|
||||||
bool
|
bool
|
||||||
CTempSense::readTemperature(float& tempReading)
|
CTempSense::readSensors(float& tempReading)
|
||||||
{
|
{
|
||||||
if(_TempSensor == NULL) {
|
if(_Sensors[0] == NULL) {
|
||||||
|
|
||||||
// bool found = find();
|
// bool found = find();
|
||||||
bool found = readROMcode();
|
bool found = readROMcode();
|
||||||
|
@ -85,8 +88,8 @@ CTempSense::readTemperature(float& tempReading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_TempSensor != NULL) {
|
if(_Sensors[0] != NULL) {
|
||||||
DS18B20_ERROR error = ds18b20_read_temp(_TempSensor, &tempReading);
|
DS18B20_ERROR error = ds18b20_read_temp(_Sensors[0], &tempReading);
|
||||||
// DebugPort.printf(">>>> DS18B20 = %f, error=%d\r\n", fTemperature, error);
|
// DebugPort.printf(">>>> DS18B20 = %f, error=%d\r\n", fTemperature, error);
|
||||||
|
|
||||||
if(error == DS18B20_OK) {
|
if(error == DS18B20_OK) {
|
||||||
|
@ -94,63 +97,134 @@ CTempSense::readTemperature(float& tempReading)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DebugPort.println("\007DS18B20 sensor removed?");
|
DebugPort.println("\007DS18B20 sensor removed?");
|
||||||
ds18b20_free(&_TempSensor);
|
ds18b20_free(&_Sensors[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*bool
|
#else
|
||||||
CTempSense::readTemperature(float& tempReading)
|
bool
|
||||||
|
CTempSense::readSensors()
|
||||||
{
|
{
|
||||||
if(_TempSensor == NULL) {
|
bool retval = false;
|
||||||
|
|
||||||
|
if(_nNumSensors == 0) {
|
||||||
|
|
||||||
bool found = find();
|
bool found = find();
|
||||||
|
|
||||||
if(found) {
|
if(found) {
|
||||||
DebugPort.println("Found DS18B20 device");
|
DebugPort.println("Found DS18B20 device(s)");
|
||||||
|
|
||||||
readROMcode();
|
|
||||||
|
|
||||||
attach();
|
|
||||||
|
|
||||||
startConvert(); // request a new conversion,
|
startConvert(); // request a new conversion,
|
||||||
waitConvertDone();
|
waitConvertDone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_TempSensor != NULL) {
|
if(_nNumSensors) {
|
||||||
DS18B20_ERROR error = ds18b20_read_temp(_TempSensor, &tempReading);
|
for (int i = 0; i < MAX_DS18B20_DEVICES; ++i) {
|
||||||
// DebugPort.printf(">>>> DS18B20 = %f, error=%d\r\n", fTemperature, error);
|
_Errors[i] = DS18B20_ERROR_UNKNOWN;
|
||||||
|
|
||||||
if(error == DS18B20_OK) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
DebugPort.println("\007DS18B20 sensor removed?");
|
for (int i = 0; i < _nNumSensors; ++i) {
|
||||||
ds18b20_free(&_TempSensor);
|
_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
|
bool
|
||||||
CTempSense::find()
|
CTempSense::find()
|
||||||
{
|
{
|
||||||
// Find all connected devices
|
// Find all connected devices
|
||||||
// DebugPort.printf("Finding one wire bus devices...");
|
// DebugPort.printf("Finding one wire bus devices...");
|
||||||
|
_nNumSensors = 0;
|
||||||
OneWireBus_SearchState search_state = {0};
|
OneWireBus_SearchState search_state = {0};
|
||||||
bool found = false;
|
bool found = false;
|
||||||
owb_search_first(_owb, &search_state, &found);
|
owb_search_first(_owb, &search_state, &found);
|
||||||
if(found)
|
if(found) {
|
||||||
|
_nNumSensors = 1;
|
||||||
DebugPort.println("Found a one wire device");
|
DebugPort.println("Found a one wire device");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
DebugPort.println("No one wire devices found!!");
|
DebugPort.println("No one wire devices found!!");
|
||||||
|
|
||||||
return 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
|
bool
|
||||||
CTempSense::readROMcode()
|
CTempSense::readROMcode()
|
||||||
{
|
{
|
||||||
|
@ -174,28 +248,104 @@ CTempSense::readROMcode()
|
||||||
bool
|
bool
|
||||||
CTempSense::attach()
|
CTempSense::attach()
|
||||||
{
|
{
|
||||||
if(_TempSensor == NULL) {
|
if(_Sensors[0] == NULL) {
|
||||||
_TempSensor = ds18b20_malloc(); // heap allocation
|
_Sensors[0] = ds18b20_malloc(); // heap allocation
|
||||||
|
|
||||||
DebugPort.printf("Single device optimisations enabled\r\n");
|
DebugPort.printf("Single device optimisations enabled\r\n");
|
||||||
ds18b20_init_solo(_TempSensor, _owb); // only one device on bus
|
ds18b20_init_solo(_Sensors[0], _owb); // only one device on bus
|
||||||
ds18b20_use_crc(_TempSensor, true); // enable CRC check for temperature readings
|
ds18b20_use_crc(_Sensors[0], true); // enable CRC check for temperature readings
|
||||||
ds18b20_set_resolution(_TempSensor, DS18B20_RESOLUTION_12_BIT);
|
ds18b20_set_resolution(_Sensors[0], DS18B20_RESOLUTION_12_BIT);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
CTempSense::startConvert()
|
CTempSense::startConvert()
|
||||||
{
|
{
|
||||||
// kick off the initial temperature conversion
|
// kick off the initial temperature conversion
|
||||||
if(_TempSensor)
|
if(_Sensors[0])
|
||||||
ds18b20_convert(_TempSensor);
|
ds18b20_convert_all(_owb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CTempSense::waitConvertDone()
|
CTempSense::waitConvertDone()
|
||||||
{
|
{
|
||||||
if(_TempSensor)
|
if(_Sensors[0])
|
||||||
ds18b20_wait_for_conversion(_TempSensor);
|
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"
|
#include "../../lib/esp32-ds18b20/ds18b20.h"
|
||||||
|
|
||||||
|
//#define SINGLE_DS18B20_SENSOR
|
||||||
|
|
||||||
|
const int MAX_DS18B20_DEVICES = 3;
|
||||||
|
|
||||||
class CTempSense {
|
class CTempSense {
|
||||||
|
|
||||||
OneWireBus * _owb;
|
OneWireBus * _owb;
|
||||||
owb_rmt_driver_info _rmt_driver_info;
|
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();
|
bool _discover();
|
||||||
|
int _sensorMap[3];
|
||||||
public:
|
public:
|
||||||
CTempSense();
|
CTempSense();
|
||||||
void begin(int pin);
|
void begin(int pin);
|
||||||
bool find();
|
bool find();
|
||||||
|
#ifdef SINGLE_DS18B20_SENSOR
|
||||||
bool readROMcode();
|
bool readROMcode();
|
||||||
bool attach();
|
bool attach();
|
||||||
bool readTemperature(float& tempReading);
|
#endif
|
||||||
|
bool readSensors();
|
||||||
void startConvert();
|
void startConvert();
|
||||||
void waitConvertDone();
|
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
|
#endif
|
||||||
|
|
|
@ -340,8 +340,22 @@ void DecodeCmd(const char* cmd, String& payload)
|
||||||
}
|
}
|
||||||
else if(strcmp("TempOffset", cmd) == 0) {
|
else if(strcmp("TempOffset", cmd) == 0) {
|
||||||
sHeaterTuning ht = NVstore.getHeaterTuning();
|
sHeaterTuning ht = NVstore.getHeaterTuning();
|
||||||
ht.tempOfs = payload.toFloat();
|
ht.tempProbe[0].offset = payload.toFloat();
|
||||||
if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) {
|
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);
|
NVstore.setHeaterTuning(ht);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue