Skip to content

Commit 5f62586

Browse files
Serial UI enhance, running
- added new modifiers “swap”, “clr" and “ack” to “set config” for temp sensor ids. - serial UI adapted, manual test (cmd line) ok
1 parent 031466f commit 5f62586

File tree

13 files changed

+144
-36
lines changed

13 files changed

+144
-36
lines changed

bc_setup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// Uncomment AT MOST ONE (!) of the following lines:
55
// #define UNIT_TEST
66
// #define BLE_UI
7-
// #define SERIAL_UI
7+
#define SERIAL_UI
88

99
#ifdef UNIT_TEST
1010
// Comment the following line to prevent execution of STATE tests:

boiler_controller.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ void logTemperatureValues(ControlContext *context) {
187187
}
188188

189189
if (logValuesNow) {
190-
Flags flags = context->op->water.sensorStatus<<4 | context->op->ambient.sensorStatus;
190+
Flags flags = (context->op->water.sensorStatus<<4) | (context->op->ambient.sensorStatus);
191191
context->log->logValues(context->op->water.currentTemp, context->op->ambient.currentTemp, flags);
192192
context->op->water.lastLoggedTemp = water;
193193
context->op->water.lastLoggedTime = time;

config.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#include "config.h"
22

3+
4+
void ConfigParams::setTempSensorIDs(TempSensorID water, TempSensorID ambient) {
5+
memcpy(this->waterTempSensorId, water, TEMP_SENSOR_ID_BYTES);
6+
memcpy(this->ambientTempSensorId, ambient, TEMP_SENSOR_ID_BYTES);
7+
}
8+
39
void ConfigParams::initParams(boolean &updated) {
410
updated = false;
511

config.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,13 @@
5252
float heaterPower; // [Watts]
5353
float insulationFactor; // correction factor to model tank insulation charactericstis
5454
uint8_t reserved[32]; // for future use
55-
55+
56+
void setTempSensorIDs(TempSensorID water, TempSensorID ambient);
57+
58+
/* Override. */
5659
void print();
5760

61+
/* Override. */
5862
uint16_t memSize() { return sizeof(*this); };
5963

6064
protected:

control.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
// #define DEBUG_CONTROL
44

55

6+
void OperationalParams::swapTempSensorIDs() {
7+
TempSensorID tempId;
8+
memcpy(tempId, water.id, TEMP_SENSOR_ID_BYTES);
9+
water.setId(ambient.id);
10+
ambient.setId(tempId);
11+
12+
SensorStatusEnum tempStatus = water.sensorStatus;
13+
water.sensorStatus = ambient.sensorStatus;
14+
ambient.sensorStatus = tempStatus;
15+
}
16+
617
uint32_t heatingTotalMillis(OperationalParams *op) {
718
uint32_t duration = op->heatingAccumulatedMillis;
819
if (op->heatingStartMillis != 0L) {
@@ -50,6 +61,32 @@ uint8_t ControlActions::setupSensors() {
5061
return matched;
5162
}
5263

64+
void ControlActions::swapTempSensorIDs() {
65+
context->op->swapTempSensorIDs();
66+
}
67+
68+
void ControlActions::clearTempSensorIDs() {
69+
context->config->setTempSensorIDs((uint8_t*) UNDEFINED_SENSOR_ID, (uint8_t*) UNDEFINED_SENSOR_ID);
70+
context->config->save();
71+
context->log->logConfigParam(PARAM_WATER_TEMP_SENSOR_ID, 0.0);
72+
context->log->logConfigParam(PARAM_AMBIENT_TEMP_SENSOR_ID, 0.0);
73+
context->log->logMessage(MSG_TEMP_SENSOR_IDS_CLEARED, 0, 0);
74+
}
75+
76+
boolean ControlActions::confirmTempSensorIDs() {
77+
if (context->op->water.sensorStatus == SENSOR_ID_AUTO_ASSIGNED || context->op->ambient.sensorStatus == SENSOR_ID_AUTO_ASSIGNED) {
78+
context->config->setTempSensorIDs(context->op->water.id, context->op->ambient.id);
79+
context->config->save();
80+
context->log->logConfigParam(PARAM_WATER_TEMP_SENSOR_ID, 0.0);
81+
context->log->logConfigParam(PARAM_AMBIENT_TEMP_SENSOR_ID, 0.0);
82+
83+
context->op->water.confirmId();
84+
context->op->ambient.confirmId();
85+
return true;
86+
}
87+
return false;
88+
}
89+
5390
void ControlActions::initSensorReadout() {
5491
context->controller->initSensorReadout();
5592
}

control.h

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
MSG_WATER_TEMP_SENSOR_ID_UNDEF = 20, // Sensor ID of water-temperature sensor could not be obtained. Check wiring and sensor, then restart.
1313
MSG_WATER_TEMP_SENSOR_ID_AUTO = 21, // Sensor ID of water-temperature sensor was assigned automatically. Confirm that it refers to the correct sensor, then restart.
1414
MSG_AMBIENT_TEMP_SENSOR_ID_UNDEF = 22, // Sensor ID of ambient-temperature sensor could not be obtained. Check wiring and sensor, then restart.
15-
MSG_AMBIENT_TEMP_SENSOR_ID_AUTO = 23 // Sensor ID of ambient-temperature sensor was assigned automatically. Confirm that it refers to the correct sensor, then restart.
15+
MSG_AMBIENT_TEMP_SENSOR_ID_AUTO = 23, // Sensor ID of ambient-temperature sensor was assigned automatically. Confirm that it refers to the correct sensor, then restart.
16+
MSG_TEMP_SENSOR_IDS_CLEARED = 24 // Sensor IDs of water- and ambient-temperature sensor cleared. Restart to see the effect.
1617
} ControlMessageEnum;
1718

1819

@@ -74,6 +75,11 @@
7475
// accumulated time in state HEATING, not including the period since last start (if heatingStartMillis != 0L)
7576
uint32_t heatingAccumulatedMillis = 0L;
7677
boolean loggingValues = false;
78+
79+
/*
80+
* Swap sensor IDs and sensor states between water and ambient sensor.
81+
*/
82+
void swapTempSensorIDs();
7783
};
7884

7985
/*
@@ -99,9 +105,44 @@
99105
ControlActions(ControlContext *context) {
100106
this->context = context;
101107
}
102-
virtual uint8_t setupSensors();
103-
virtual void initSensorReadout();
104-
virtual void completeSensorReadout();
108+
109+
/*
110+
* Performs a search on the OneWire Bus and matches / assigns returned sensor addresses with configured sensors.
111+
*/
112+
uint8_t setupSensors();
113+
114+
/*
115+
* Swap the sensor IDs and states of water- and ambient-temperature sensor in the operational parameters.
116+
*/
117+
void swapTempSensorIDs();
118+
119+
/*
120+
* Clears the sensor IDs of water- and ambient-temperature sensors in the configuration parameters and saves the latter to EEPROM.
121+
*/
122+
void clearTempSensorIDs();
123+
124+
/*
125+
* Copies the sensor IDs of water- and ambient-temperature sensors of the the configuration parameters to the configuration parameters and saves the latter to EEPROM.
126+
* Sets the sensor status of one or both sensors to SENSOR_OK iff sensor status is SENSOR_ID_AUTO_ASSIGNED.
127+
*
128+
* @return true if at lestt one ID was copied and status was changed.
129+
*/
130+
boolean confirmTempSensorIDs();
131+
132+
/*
133+
* Sends a command to all physical temperature sensors to trigger the conversion of physical values to a temperature.
134+
*
135+
* Note: The conversion takes time (up to 750 ms depending on the precision of the returned value) and completeSensorReadout cannot be invoked before that.
136+
* See the data sheet of the DS18B20 temperature sensors for exact times.
137+
*/
138+
void initSensorReadout();
139+
140+
/*
141+
* Reads the temperatures from the physical sensors and assignes the value and state to the configured temperature sonsors.
142+
*
143+
* Note: See the note for initSensorReadout()
144+
*/
145+
void completeSensorReadout();
105146

106147
/*
107148
* Physically turns the water heater on or off.

log.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Timestamp Log::logState(StateID previous, StateID current, EventID event) {
4040
data.previous = previous;
4141
data.current = current;
4242
data.event = event;
43-
LogEntry e = addLogEntry(LOG_DATA_TYPE_VALUES, (LogData *) &data);
43+
LogEntry e = addLogEntry(LOG_DATA_TYPE_STATE, (LogData *) &data);
4444
#ifdef DEBUG_LOG
4545
Serial.println(F("DEBUG_LOG: logState(..)"));
4646
#endif
@@ -54,7 +54,7 @@ Timestamp Log::logConfigParam(ConfigParamID id, float newValue) {
5454
LogConfigParamData data;
5555
data.id = id;
5656
data.newValue = newValue;
57-
LogEntry e = addLogEntry(LOG_DATA_TYPE_VALUES, (LogData *) &data);
57+
LogEntry e = addLogEntry(LOG_DATA_TYPE_CONFIG, (LogData *) &data);
5858
#ifdef DEBUG_LOG
5959
Serial.println(F("DEBUG_LOG: logConfigParam(..)"));
6060
#endif

sensors/OneWireSensors.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
*/
2222
typedef enum {
2323
SENSOR_INITIALISING = 1,
24-
SENSOR_OK = 2, // temperature value is defined and within the given range
25-
SENSOR_NOK = 3, // temperature value could not be obtained or is outside the given range
26-
SENSOR_ID_UNDEFINED = 4, // no physical sensor could be found for the logical sensor
27-
SENSOR_ID_AUTO_ASSIGNED = 5 // a physical sensor was assigned to the logical sensor but it may not correspond to the intended sensor
24+
SENSOR_ID_AUTO_ASSIGNED = 2, // a physical sensor was assigned to the logical sensor but it may not correspond to the intended sensor
25+
SENSOR_ID_UNDEFINED = 3, // no physical sensor could be found for the logical sensor
26+
SENSOR_OK = 4, // temperature value is defined and within the given range
27+
SENSOR_NOK = 5 // temperature value could not be obtained or is outside the given range
2828
} SensorStatusEnum;
2929

3030
typedef uint8_t SensorStatusID;
@@ -74,6 +74,19 @@
7474
static boolean idUndefined(const TempSensorID id) {
7575
return ! memcmp(id, UNDEFINED_SENSOR_ID, TEMP_SENSOR_ID_BYTES);
7676
}
77+
78+
/*
79+
* Sets the sensor status to SENSOR_OK iff it is SENSOR_ID_AUTO_ASSIGNED.
80+
*
81+
* @return true if status was changed.
82+
*/
83+
boolean confirmId() {
84+
if (sensorStatus == SENSOR_ID_AUTO_ASSIGNED) {
85+
sensorStatus = SENSOR_OK;
86+
return true;
87+
}
88+
return false;
89+
}
7790
};
7891

7992
struct TemperatureReadout {

sensors/sensors.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ test(b_single_sensor_readout) {
104104
uint8_t matched = controller.setupSensors();
105105
assertEqual(matched, 1);
106106
assertEqual(s1.sensorStatus, SENSOR_ID_AUTO_ASSIGNED);
107-
// manually confirm auto-assigned:
108-
s1.sensorStatus = SENSOR_OK;
107+
// manually confirm auto-assigned ID:
108+
s1.confirmId();
109109

110110
#ifdef MOCK_ONE_WIRE
111111
const int16_t temperatures100_1[] = {2300};
@@ -164,8 +164,8 @@ test(c_twin_sensor_readout) {
164164
uint8_t matched = controller.setupSensors();
165165
assertEqual(matched, 2);
166166
assertEqual(s1.sensorStatus, SENSOR_ID_AUTO_ASSIGNED);
167-
// manually confirm auto-assigned s1 but not s2:
168-
s1.sensorStatus = SENSOR_OK;
167+
// manually confirm auto-assigned ID for s1 but not for s2:
168+
s1.confirmId();
169169

170170
#ifdef MOCK_ONE_WIRE
171171
const int16_t temperatures100_1[] = {2300, 2400};

ui.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
class NullUI {
2121
public:
22-
NullUI(ControlContext *context) {
22+
NullUI(ExecutionContext *context) {
2323
this->context = context;
2424
}
2525

@@ -36,15 +36,15 @@
3636
virtual void notifyNewLogEntry(LogEntry) { }
3737

3838
protected:
39-
ControlContext *context;
39+
ExecutionContext *context;
4040
};
4141

4242

4343
#ifdef BLE_UI
4444

4545
class BLEUI : public NullUI {
4646
public:
47-
BLEUI(ControlContext *context) : NullUI(context) { }
47+
BLEUI(ExecutionContext *context) : NullUI(context) { }
4848
void setup();
4949

5050
void readUserCommand();

ui_ble.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
class BLEUI : public NullUI {
77
public:
8-
BLEUI(ControlContext *context) : NullUI(context) { }
8+
BLEUI(ExecutionContext *context) : NullUI(context) { }
99
void setup();
1010

1111
void readUserCommand();

ui_ser.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include <string.h>
1+
//#include <string.h>
22
#include "ui_ser.h"
33
#include "config.h"
44

@@ -7,6 +7,10 @@ const char COMMAND_CHARS[] = " abcdefghijklmnopqrstuvwxyz"; // includes blank (f
77
const char INT_CHARS[] = "0123456789";
88
const char SENSOR_ID_CHARS[] = "0123456789abcdef-"; // includes dash
99

10+
const char STR_CONFIG_SENSOR_ID_SWAP[] PROGMEM = "swap";
11+
const char STR_CONFIG_SENSOR_ID_CLR[] PROGMEM = "clr";
12+
const char STR_CONFIG_SENSOR_ID_ACK[] PROGMEM = "ack";
13+
1014
//#define DEBUG_UI
1115

1216
/*
@@ -48,13 +52,13 @@ String getConfigParamName(ConfigParamEnum literal) {
4852

4953
String formatFloat(float f) {
5054
char s[20];
51-
dtostrf((double)f, 6, 2, &s[0]);
55+
dtostrf((double)f, 6, 2, s);
5256
return s;
5357
}
5458

5559
String formatInt(uint16_t i) {
5660
char s[20];
57-
utoa(i, &s[0], 10);
61+
utoa(i, s, 10);
5862
return s;
5963
}
6064

@@ -85,6 +89,7 @@ String getConfigParamValue(ConfigParams *all, ConfigParamEnum p) {
8589
}
8690
}
8791

92+
/*
8893
boolean parseTempSensorID(char *value, uint8_t *id) {
8994
uint8_t len = strspn(value, SENSOR_ID_CHARS);
9095
#ifdef DEBUG_UI
@@ -106,24 +111,25 @@ boolean parseTempSensorID(char *value, uint8_t *id) {
106111
return false;
107112
}
108113
}
114+
*/
109115

110-
boolean setConfigParamValue(ControlContext *context, ConfigParamEnum p, char *value) {
116+
boolean setConfigParamValue(ExecutionContext *context, ConfigParamEnum p, char *value) {
111117
switch(p) {
112118
case PARAM_TARGET_TEMP:
113119
context->config->targetTemp = atoi(value);
114120
context->log->logConfigParam(p, (float) context->config->targetTemp);
115121
return true;
116122
case PARAM_WATER_TEMP_SENSOR_ID:
117-
if (parseTempSensorID(value, context->config->waterTempSensorId)) {
118-
context->log->logConfigParam(p, 0.0);
119-
return true;
120-
}
121-
return false;
122123
case PARAM_AMBIENT_TEMP_SENSOR_ID:
123-
if (parseTempSensorID(value, context->config->ambientTempSensorId)) {
124-
context->log->logConfigParam(p, 0.0);
124+
if (!strcmp_P(value, STR_CONFIG_SENSOR_ID_SWAP)) {
125+
context->control->swapTempSensorIDs();
125126
return true;
126-
}
127+
} else if (!strcmp_P(value, STR_CONFIG_SENSOR_ID_CLR)) {
128+
context->control->clearTempSensorIDs();
129+
return true;
130+
} else if (!strcmp_P(value, STR_CONFIG_SENSOR_ID_ACK)) {
131+
return context->control->confirmTempSensorIDs();
132+
}
127133
return false;
128134
case PARAM_HEATER_CUT_OUT_WATER_TEMP:
129135
context->config->heaterCutOutWaterTemp = atoi(value);
@@ -438,6 +444,7 @@ void SerialUI::readUserCommand() {
438444
}
439445

440446
void printLogEntry(LogEntry *e) {
447+
441448
Serial.print(formatTimestamp(e->timestamp));
442449
Serial.print(" ");
443450
LogDataTypeEnum type = (LogDataTypeEnum)e->type;
@@ -531,15 +538,15 @@ void SerialUI::processReadWriteRequests(ReadWriteRequests requests, BoilerStateA
531538

532539
Serial.print(F("Water: "));
533540
Serial.print(getSensorStatusName(context->op->water.sensorStatus));
534-
if (context->op->water.sensorStatus == SENSOR_OK) {
541+
if (context->op->water.sensorStatus == SENSOR_OK || context->op->water.sensorStatus == SENSOR_ID_AUTO_ASSIGNED) {
535542
Serial.print(F(", "));
536543
Serial.print(formatTemperature(context->op->water.currentTemp));
537544
}
538545
Serial.println();
539546

540547
Serial.print(F("Ambient: "));
541548
Serial.print(getSensorStatusName(context->op->ambient.sensorStatus));
542-
if (context->op->ambient.sensorStatus == SENSOR_OK) {
549+
if (context->op->ambient.sensorStatus == SENSOR_OK || context->op->ambient.sensorStatus == SENSOR_ID_AUTO_ASSIGNED) {
543550
Serial.print(F(", "));
544551
Serial.print(formatTemperature(context->op->ambient.currentTemp));
545552
}

ui_ser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
class SerialUI : public NullUI {
77
public:
8-
SerialUI(ControlContext *context) : NullUI(context) { }
8+
SerialUI(ExecutionContext *context) : NullUI(context) { }
99

1010
void setup();
1111

0 commit comments

Comments
 (0)