Added auto save of single DS18B20 serial number

This commit is contained in:
Ray Jones 2019-09-22 14:46:39 +10:00
parent 8fb1981552
commit 573ebf3e3b
6 changed files with 156 additions and 82 deletions

View file

@ -482,6 +482,32 @@ void setup() {
pHourMeter->init(bESP32PowerUpInit || RTC_Store.getBootInit()); // ensure persistent memory variable are reset after powerup, or OTA update
RTC_Store.setBootInit(false);
// Check for solo DS18B20
// store it's serial number as the primary sensor
// This allows seamless standard operation, and marks the iniital sensor
// as the primary if another is added later
OneWireBus_ROMCode romCode;
TempSensor.getRomCodeIdx(0, romCode);
if(TempSensor.getNumSensors() == 1 &&
memcmp(NVstore.getHeaterTuning().tempProbe[0].romCode.bytes, romCode.bytes, 8) != 0)
{
sHeaterTuning tuning = NVstore.getHeaterTuning();
tuning.tempProbe[0].romCode = romCode;
tuning.tempProbe[1].romCode = {0};
tuning.tempProbe[2].romCode = {0};
tuning.tempProbe[0].offset = 0;
NVstore.setHeaterTuning(tuning);
NVstore.save();
DebugPort.printf("Saved solo DS18B20 %02X:%02X:%02X:%02X:%02X:%02X to NVstore\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]
);
}
TempSensor.mapSensor(0, NVstore.getHeaterTuning().tempProbe[0].romCode);
TempSensor.mapSensor(1, NVstore.getHeaterTuning().tempProbe[1].romCode);
TempSensor.mapSensor(2, NVstore.getHeaterTuning().tempProbe[2].romCode);
@ -804,8 +830,7 @@ void loop()
lastTemperatureTime = millis(); // reset time to observe temeprature
TempSensor.readSensors();
// TempSensor.checkNumSensors();
if(TempSensor.getTemperature(fTemperature)) { // get Primary sensor temeprature
if(TempSensor.getTemperature(0, fTemperature)) { // get Primary sensor temeprature
if(DS18B20holdoff) {
DS18B20holdoff--;
DebugPort.printf("Skipped initial DS18B20 reading: %f\r\n", fTemperature);

View file

@ -75,23 +75,23 @@ CDS18B20Screen::show()
else
_showTitle("Temp Sensor Offset");
int baseLine = 40;
int baseLine = 16;
switch(_nNumSensors) {
case 1: baseLine = 18; break;
case 2: baseLine = 30; break;
case 2: baseLine = 28; break;
case 3: baseLine = 40; break;
}
for(int i = 0; i<_nNumSensors; i++) {
for(int sensor = 0; sensor<_nNumSensors; sensor++) {
switch(_sensorRole[i]) {
switch(_sensorRole[sensor]) {
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);
_printMenuText(border, baseLine-sensor*12, msg, _rowSel == (sensor+1) && _colSel == 0);
OneWireBus_ROMCode romCode;
if(!TempSensor.getRomCodeIdx(romCode, i)) {
if(!TempSensor.getRomCodeIdx(sensor, romCode)) {
strcpy(msg, "missing?") ;
}
else {
@ -103,18 +103,18 @@ CDS18B20Screen::show()
}
{
CTransientFont AF(_display, &miniFontInfo);
_printMenuText(27, baseLine+2-i*12, msg);
_printMenuText(27, baseLine+2-sensor*12, msg);
}
if(_colSel == 0) {
float temperature;
TempSensor.getTemperatureIdx(temperature, i);
sprintf(msg, "%.01fC", temperature + _Offset[i]);
TempSensor.getTemperatureIdx(sensor, temperature);
sprintf(msg, "%.01fC", temperature + _Offset[sensor]);
}
else {
sprintf(msg, "%+.01f", _Offset[i]);
sprintf(msg, "%+.01f", _Offset[sensor]);
}
_printMenuText(90, baseLine-i*12, msg, _rowSel == (i+1) && _colSel == 1);
_printMenuText(90, baseLine-sensor*12, msg, _rowSel == (sensor+1) && _colSel == 1);
}
}
@ -166,33 +166,6 @@ CDS18B20Screen::keyHandler(uint8_t event)
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();
@ -208,11 +181,18 @@ CDS18B20Screen::keyHandler(uint8_t event)
if(_keyHold >= 0) {
_keyHold++;
if(_keyHold == 2) {
if(event & key_Up) {
// rescan the one wire bus
TempSensor.find();
_nNumSensors = TempSensor.getNumSensors();
_readNV();
}
if(event & key_Left) {
_colSel = 0;
_scrollChar = 0;
}
if(event & key_Right) {
_testCancel();
_colSel = 1;
_scrollChar = 0;
}
@ -230,6 +210,33 @@ CDS18B20Screen::keyHandler(uint8_t event)
if(event & keyReleased) {
if(_keyHold == 0) {
// UP release
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);
}
}
}
// LEFT press
if(event & key_Left) {
if(_rowSel == 0)
@ -327,13 +334,14 @@ CDS18B20Screen::_testCancel()
void
CDS18B20Screen::_readNV()
{
_sensorRole[0] = _sensorRole[1] = _sensorRole[2] = -1;
for(int i=0; i< 3; i++)
_sensorRole[i] = -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
TempSensor.getRomCodeIdx(sensor, romCode); // 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
@ -342,7 +350,7 @@ CDS18B20Screen::_readNV()
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;
break;
}
}
}
@ -363,7 +371,7 @@ CDS18B20Screen::_saveNV()
if(role != -1) {
tuning.tempProbe[role].offset = _Offset[sensor];
OneWireBus_ROMCode romCode;
TempSensor.getRomCodeIdx(romCode, sensor); // get rom code of indexed sensor
TempSensor.getRomCodeIdx(sensor, romCode); // get rom code of indexed sensor
memcpy(tuning.tempProbe[role].romCode.bytes, romCode.bytes, 8);
}
}

View file

@ -146,14 +146,14 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len)
bSend |= moderator.addJson("TempCurrent", tidyTemp, root);
}
if(TempSensor.getNumSensors() > 1) {
TempSensor.getTemperature(tidyTemp, 1);
TempSensor.getTemperature(1, tidyTemp);
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);
TempSensor.getTemperature(2, tidyTemp);
tidyTemp += NVstore.getHeaterTuning().tempProbe[2].offset;
tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution
if(tidyTemp > -80) {

View file

@ -210,6 +210,7 @@ CTempSense::find()
{
printf("Single device optimisations enabled\n");
ds18b20_init_solo(ds18b20_info, _owb); // only one device on bus
ds18b20_info->rom_code = _device_rom_codes[i]; // added, for GUI setup!!
}
else
{
@ -219,7 +220,6 @@ CTempSense::find()
ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION_12_BIT);
}
return found;
}
#endif
@ -313,9 +313,14 @@ CTempSense::mapSensor(int idx, OneWireBus_ROMCode romCode)
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);
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;
}
}
@ -323,29 +328,28 @@ CTempSense::mapSensor(int idx, OneWireBus_ROMCode romCode)
}
bool
CTempSense::getTemperature(float& temperature, int mapIdx)
CTempSense::getTemperature(int mapIdx, float& temperature)
{
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);
int snsIdx = _sensorMap[mapIdx];
if(snsIdx < 0)
snsIdx = 0; // default to sensor 0 if not mapped
return getTemperatureIdx(snsIdx, temperature);
}
bool
CTempSense::getTemperatureIdx(float& temperature, int idx)
CTempSense::getTemperatureIdx(int snsIdx, float& temperature)
{
temperature = _Readings[idx];
return _Errors[idx] == DS18B20_OK;
temperature = _Readings[snsIdx];
return _Errors[snsIdx] == DS18B20_OK;
}
bool
CTempSense::getRomCodeIdx(OneWireBus_ROMCode& romCode, int idx)
CTempSense::getRomCodeIdx(int snsIdx, OneWireBus_ROMCode& romCode)
{
if(idx >= _nNumSensors)
if(snsIdx >= _nNumSensors)
return false;
romCode = _Sensors[idx]->rom_code;
romCode = _Sensors[snsIdx]->rom_code;
return true;
}

View file

@ -52,9 +52,9 @@ public:
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
bool getTemperature(int mapIdx, float& tempReading); // indexed as mapped by user
bool getTemperatureIdx(int sensIdx, float& tempReading); // index is sensor discovery order on one-wire bus
bool getRomCodeIdx(int sensIdx, OneWireBus_ROMCode& romCode); // index is sensor discovery order on one-wire bus
int checkNumSensors() const;
int getNumSensors() const { return _nNumSensors; };
bool mapSensor(int idx, OneWireBus_ROMCode romCode = { 0 } );

View file

@ -34,8 +34,10 @@
#include "../Utility/Moderator.h"
#include "../Protocol/Protocol.h"
#include "../Utility/BTC_JSON.h"
#include "Utility/TempSense.h"
extern void DecodeCmd(const char* cmd, String& payload);
extern CTempSense TempSensor;
#define USE_RTOS_MQTTTIMER
//#define USE_LOCAL_MQTTSTRINGS
@ -49,6 +51,9 @@ char topicnameJSONin[128];
char topicnameCmd[128];
CModerator MQTTmoderator;
void subscribe(const char* topic);
#ifdef USE_LOCAL_MQTTSTRINGS
char mqttHost[128];
char mqttUser[32];
@ -84,20 +89,23 @@ void onMqttConnect(bool sessionPresent)
mqttReconnect = 0;
#endif
sprintf(statusTopic, "%s/status", NVstore.getMQTTinfo().topic);
DebugPort.println("MQTT: Connected to broker.");
// DebugPort.printf("Session present: %d\r\n", sessionPresent);
// create the topicname we use to accept incoming JSON
DebugPort.printf("MQTT: base topic name \"%s\"\r\n", NVstore.getMQTTinfo().topic);
sprintf(topicnameJSONin, "%s/JSONin", NVstore.getMQTTinfo().topic);
sprintf(topicnameCmd, "%s/cmd/#", NVstore.getMQTTinfo().topic);
DebugPort.printf("MQTT: topic prefix name \"%s\"\r\n", NVstore.getMQTTinfo().topicPrefix);
sprintf(statusTopic, "%s/status", NVstore.getMQTTinfo().topicPrefix);
sprintf(topicnameJSONin, "%s/JSONin", NVstore.getMQTTinfo().topicPrefix);
sprintf(topicnameCmd, "%s/cmd/#", NVstore.getMQTTinfo().topicPrefix);
// subscribe to that topic
DebugPort.printf("MQTT: Subscribing to \"%s\"\r\n", topicnameJSONin);
MQTTclient.subscribe(topicnameJSONin, NVstore.getMQTTinfo().qos);
MQTTclient.subscribe(topicnameCmd, NVstore.getMQTTinfo().qos);
MQTTclient.subscribe(statusTopic, NVstore.getMQTTinfo().qos);
// DebugPort.printf("MQTT: Subscribing to \"%s\"\r\n", topicnameJSONin);
// MQTTclient.subscribe(topicnameJSONin, NVstore.getMQTTinfo().qos);
// MQTTclient.subscribe(topicnameCmd, NVstore.getMQTTinfo().qos);
// MQTTclient.subscribe(statusTopic, NVstore.getMQTTinfo().qos);
subscribe(topicnameJSONin);
subscribe(topicnameCmd);
subscribe(statusTopic);
// spit out an "I'm here" message
MQTTclient.publish(statusTopic, NVstore.getMQTTinfo().qos, true, "online");
@ -241,7 +249,7 @@ bool mqttPublishJSON(const char* str)
if(MQTTclient.connected()) {
const sMQTTparams params = NVstore.getMQTTinfo();
char topic[128];
sprintf(topic, "%s/JSONout", params.topic);
sprintf(topic, "%s/JSONout", params.topicPrefix);
MQTTclient.publish(topic, params.qos, false, str);
return true;
}
@ -299,7 +307,7 @@ void pubTopic(const char* name, int value)
if(MQTTmoderator.shouldSend(name, value)) {
const sMQTTparams params = NVstore.getMQTTinfo();
char topic[128];
sprintf(topic, "%s/sts/%s", params.topic, name);
sprintf(topic, "%s/sts/%s", params.topicPrefix, name);
char payload[128];
sprintf(payload, "%d", value);
MQTTclient.publish(topic, params.qos, false, payload);
@ -313,7 +321,7 @@ void pubTopic(const char* name, float value)
if(MQTTmoderator.shouldSend(name, value)) {
const sMQTTparams params = NVstore.getMQTTinfo();
char topic[128];
sprintf(topic, "%s/sts/%s", params.topic, name);
sprintf(topic, "%s/sts/%s", params.topicPrefix, name);
char payload[128];
sprintf(payload, "%.1f", value);
MQTTclient.publish(topic, params.qos, false, payload);
@ -327,7 +335,7 @@ void pubTopic(const char* name, const char* payload)
if(MQTTmoderator.shouldSend(name, payload)) {
const sMQTTparams params = NVstore.getMQTTinfo();
char topic[128];
sprintf(topic, "%s/sts/%s", params.topic, name);
sprintf(topic, "%s/sts/%s", params.topicPrefix, name);
MQTTclient.publish(topic, params.qos, false, payload);
}
}
@ -338,9 +346,33 @@ void updateMQTT()
pubTopic("RunState", getHeaterInfo().getRunStateEx());
pubTopic("Run", getHeaterInfo().getRunStateEx() ? "1" : "0");
pubTopic("RunString", getHeaterInfo().getRunStateStr());
float tidyTemp = getTemperatureSensor();
tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution
pubTopic("TempCurrent", tidyTemp);
float tidyTemp;
if(TempSensor.getTemperature(0, tidyTemp)) {
tidyTemp += NVstore.getHeaterTuning().tempProbe[0].offset;
tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution
pubTopic("TempCurrent", tidyTemp);
}
else
pubTopic("TempCurrent", "n/a");
if(TempSensor.getNumSensors() > 1) {
if(TempSensor.getTemperature(1, tidyTemp)) {
tidyTemp += NVstore.getHeaterTuning().tempProbe[1].offset;
tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution
pubTopic("Temp2Current", tidyTemp);
}
else
pubTopic("Temp2Current", "n/a");
if(TempSensor.getNumSensors() > 2) {
if(TempSensor.getTemperature(2, tidyTemp)) {
tidyTemp += NVstore.getHeaterTuning().tempProbe[2].offset;
tidyTemp = int(tidyTemp * 10 + 0.5) * 0.1f; // round to 0.1 resolution
pubTopic("Temp3Current", tidyTemp);
}
else
pubTopic("Temp3Current", "n/a");
}
}
pubTopic("TempDesired", getTemperatureDesired());
pubTopic("TempBody", getHeaterInfo().getTemperature_HeatExchg());
pubTopic("ErrorState", getHeaterInfo().getErrState());
@ -362,5 +394,10 @@ void refreshMQTT()
MQTTmoderator.reset();
}
void subscribe(const char* topic)
{
DebugPort.printf("MQTT: Subscribing to \"%s\"\r\n", topic);
MQTTclient.subscribe(topic, NVstore.getMQTTinfo().qos);
}
#endif