Temperature and humidity are now propagated to the distance sensor.

This commit is contained in:
Maurice Makaay 2020-07-20 00:38:03 +02:00
parent 2022eb33c5
commit e416dab9dd
8 changed files with 78 additions and 51 deletions

View File

@ -15,13 +15,14 @@ namespace Dough
statePlugin(&ui, &mqtt), statePlugin(&ui, &mqtt),
state(&statePlugin), state(&statePlugin),
sensorControllerPlugin(&mqtt, &ui), sensorControllerPlugin(&mqtt, &ui),
distanceSensor( distanceSensor(),
new DistanceSensor(), &sensorControllerPlugin, distanceController(
&distanceSensor, &sensorControllerPlugin,
DISTANCE_AVERAGE_STORAGE, DISTANCE_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL), DISTANCE_AVERAGE_STORAGE, DISTANCE_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL),
temperatureSensor( temperatureController(
new TemperatureSensor(), &sensorControllerPlugin, new TemperatureSensor(), &sensorControllerPlugin,
TEMPERATURE_AVERAGE_STORAGE, TEMPERATURE_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL), TEMPERATURE_AVERAGE_STORAGE, TEMPERATURE_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL),
humiditySensor( humidityController(
new HumiditySensor(), &sensorControllerPlugin, new HumiditySensor(), &sensorControllerPlugin,
HUMIDITY_AVERAGE_STORAGE, HUMIDITY_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL), HUMIDITY_AVERAGE_STORAGE, HUMIDITY_MEASURE_INTERVAL, MINIMUM_PUBLISH_INTERVAL),
_logger("APP") _logger("APP")
@ -37,9 +38,9 @@ namespace Dough
ui.setup(); ui.setup();
wifi.setup(); wifi.setup();
mqtt.setup(); mqtt.setup();
temperatureSensor.setup(); temperatureController.setup();
humiditySensor.setup(); humidityController.setup();
distanceSensor.setup(); distanceController.setup();
} }
void App::loop() void App::loop()
@ -71,9 +72,11 @@ namespace Dough
case MEASURING: case MEASURING:
if (config.isOk()) if (config.isOk())
{ {
temperatureSensor.loop(); if (temperatureController.loop())
humiditySensor.loop(); distanceSensor.setTemperature(temperatureController.getLast().value);
distanceSensor.loop(); if (humidityController.loop())
distanceSensor.setHumidity(humidityController.getLast().value);
distanceController.loop();
} }
else else
{ {
@ -81,14 +84,18 @@ namespace Dough
} }
break; break;
case CALIBRATING: case CALIBRATING:
temperatureController.loop();
humidityController.loop();
distanceController.loop();
delay(2000); delay(2000);
state.pauseMeasurements(); state.pauseDevice();
state.startMeasurements(); state.startMeasurements();
break; break;
case PAUSED: case PAUSED:
temperatureSensor.clearHistory(); temperatureController.clearHistory();
humiditySensor.clearHistory(); humidityController.clearHistory();
distanceSensor.clearHistory(); distanceController.clearHistory();
break; break;
default: default:
// NOOP // NOOP

View File

@ -27,9 +27,11 @@ namespace Dough
AppStateControllerPlugin statePlugin; AppStateControllerPlugin statePlugin;
AppStateController state; AppStateController state;
SensorControllerPlugin sensorControllerPlugin; SensorControllerPlugin sensorControllerPlugin;
SensorController distanceSensor; DistanceSensor distanceSensor;
SensorController temperatureSensor; SensorController distanceController;
SensorController humiditySensor; SensorController temperatureController;
SensorController humidityController;
void propagateMeasurement(const char* sensorName, int lastValue);
void setup(); void setup();
void loop(); void loop();

View File

@ -91,13 +91,13 @@ namespace Dough
_updateState(); _updateState();
} }
void AppStateController::pauseMeasurements() void AppStateController::pauseDevice()
{ {
_paused = true; _paused = true;
_updateState(); _updateState();
} }
void AppStateController::resumeMeasurements() void AppStateController::resumeDevice()
{ {
_paused = false; _paused = false;
_updateState(); _updateState();

View File

@ -53,8 +53,8 @@ namespace Dough
void startConfiguration(); void startConfiguration();
void startMeasurements(); void startMeasurements();
void startCalibration(); void startCalibration();
void pauseMeasurements(); void pauseDevice();
void resumeMeasurements(); void resumeDevice();
AppState get(); AppState get();
private: private:

View File

@ -1,5 +1,5 @@
#ifndef DOUGH_SENSORCONTROLLER_PLUGINS_H #ifndef DOUGH_SENSORCONTROLLER_PLUGIN_H
#define DOUGH_SENSORCONTROLLER_PLUGINS_H #define DOUGH_SENSORCONTROLLER_PLUGIN_H
#include <Arduino.h> #include <Arduino.h>
#include "UI/Logger.h" #include "UI/Logger.h"

View File

@ -42,11 +42,11 @@ void handleOnoffButtonPress()
auto app = Dough::App::Instance(); auto app = Dough::App::Instance();
if (app->state.get() == Dough::MEASURING) if (app->state.get() == Dough::MEASURING)
{ {
app->state.pauseMeasurements(); app->state.pauseDevice();
} }
else if (app->state.get() == Dough::PAUSED) else if (app->state.get() == Dough::PAUSED)
{ {
app->state.resumeMeasurements(); app->state.resumeDevice();
} }
} }

View File

@ -8,7 +8,7 @@ namespace Dough
SensorControllerPluginBase *plugin, SensorControllerPluginBase *plugin,
unsigned int storageSize, unsigned int storageSize,
unsigned int minimumMeasureTime, unsigned int minimumMeasureTime,
unsigned int minimumPublishTime) : _sensor(sensor), unsigned int minimumPublishTime) : sensor(sensor),
_plugin(plugin), _plugin(plugin),
_storageSize(storageSize), _storageSize(storageSize),
_minimumMeasureTime(minimumMeasureTime), _minimumMeasureTime(minimumMeasureTime),
@ -16,12 +16,12 @@ namespace Dough
const char *SensorController::getSensorName() const char *SensorController::getSensorName()
{ {
return _sensor->getName(); return sensor->getName();
} }
void SensorController::setup() void SensorController::setup()
{ {
_sensor->setup(); sensor->setup();
// Initialize the storage for holding measurements. This storage is used // Initialize the storage for holding measurements. This storage is used
// as a circular buffer, and it helps in computing an over time average // as a circular buffer, and it helps in computing an over time average
@ -35,25 +35,30 @@ namespace Dough
clearHistory(); clearHistory();
} }
void SensorController::loop() bool SensorController::loop()
{ {
if (_mustMeasure()) if (_mustMeasure())
{ {
_plugin->beforeMeasure(this); _plugin->beforeMeasure(this);
_measure(); _lastMeasuredAt = millis();
_store(sensor->read());
_plugin->afterMeasure(this); _plugin->afterMeasure(this);
} }
auto last = getLast();
if (_mustPublish()) if (_mustPublish())
{ {
_plugin->beforePublish(this); _plugin->beforePublish(this);
auto average = _getAverage(); auto average = getAverage();
auto last = _getLast();
_lastPublishedAt = millis(); _lastPublishedAt = millis();
average.copyTo(&_lastPublishedAverage); average.copyTo(&_lastPublishedAverage);
last.copyTo(&_lastPublished); last.copyTo(&_lastPublished);
_plugin->doPublish(this, last, average); _plugin->doPublish(this, last, average);
_plugin->afterPublish(this); _plugin->afterPublish(this);
} }
return last.ok;
} }
bool SensorController::_mustMeasure() bool SensorController::_mustMeasure()
@ -71,16 +76,9 @@ namespace Dough
return delta >= (_minimumMeasureTime * 1000); return delta >= (_minimumMeasureTime * 1000);
} }
void SensorController::_measure()
{
_lastMeasuredAt = millis();
_store(_sensor->read());
}
bool SensorController::_mustPublish() bool SensorController::_mustPublish()
{ {
Measurement lastMeasurement = _getLast(); Measurement lastMeasurement = getLast();
// When the measurement failed, then there's no need to publish it. // When the measurement failed, then there's no need to publish it.
if (lastMeasurement.ok == false) if (lastMeasurement.ok == false)
@ -103,7 +101,7 @@ namespace Dough
return _lastPublishedAt == 0 || delta >= (_minimumPublishTime * 1000); return _lastPublishedAt == 0 || delta >= (_minimumPublishTime * 1000);
} }
auto precision = _sensor->getPrecision(); auto precision = sensor->getPrecision();
// When there is a significant change in the sensor value, then publish. // When there is a significant change in the sensor value, then publish.
if (abs(_lastPublished.value - lastMeasurement.value) >= precision) if (abs(_lastPublished.value - lastMeasurement.value) >= precision)
@ -111,7 +109,7 @@ namespace Dough
return true; return true;
} }
auto average = _getAverage(); auto average = getAverage();
// When there is a significant change in the average value, then publish. // When there is a significant change in the average value, then publish.
if (average.ok && abs(_lastPublishedAverage.value - average.value) >= precision) if (average.ok && abs(_lastPublishedAverage.value - average.value) >= precision)
@ -164,12 +162,12 @@ namespace Dough
return _index; return _index;
} }
Measurement SensorController::_getLast() Measurement SensorController::getLast()
{ {
return *_storage[_index]; return *_storage[_index];
} }
Measurement SensorController::_getAverage() Measurement SensorController::getAverage()
{ {
return _averageCount > 0 return _averageCount > 0
? Measurement::Value(round(_averageSum / _averageCount)) ? Measurement::Value(round(_averageSum / _averageCount))

View File

@ -54,16 +54,37 @@ namespace Dough
unsigned int storageSize, unsigned int storageSize,
unsigned int minimumMeasureTime, unsigned int minimumMeasureTime,
unsigned int minimumPublishTime); unsigned int minimumPublishTime);
const char *getSensorName(); SensorBase *sensor;
void setup(); void setup();
void loop();
// Return the name for the contained sensor.
const char *getSensorName();
// Read the sensor and publish the results when needed.
// This method returns true when the last read value was an ok measurement.
// This means that after this method returns true, getLast() will return
// an ok Dough::Measurement.
bool loop();
// Read a measurement from the sensor.
Measurement readSensor();
// Returns the last measurement that was done for the sensor.
// This might be a failed measurement, in which case the ok field
// of the result will be set to false.
Measurement getLast();
// Returns the running average value for the sensor readings so far.
// When no successful measurements were done at all, then the ok
// field of the result will be set to false.
Measurement getAverage();
// Clear the collected data for the running average, letting the
// average computation start from a clean slate.
void clearHistory(); void clearHistory();
private: private:
SensorBase *_sensor;
SensorControllerPluginBase *_plugin; SensorControllerPluginBase *_plugin;
Measurement _getLast();
Measurement _getAverage();
// Members related to the measurement storage. // Members related to the measurement storage.
Measurement **_storage; Measurement **_storage;
@ -76,7 +97,6 @@ namespace Dough
// Members used for controlling measurements. // Members used for controlling measurements.
bool _mustMeasure(); bool _mustMeasure();
void _measure();
unsigned int _minimumMeasureTime; unsigned int _minimumMeasureTime;
unsigned long _lastMeasuredAt = 0; unsigned long _lastMeasuredAt = 0;