diff --git a/src/Data/DataController.cpp b/src/Data/DataController.cpp index 4fd07ff..3b53720 100644 --- a/src/Data/DataController.cpp +++ b/src/Data/DataController.cpp @@ -15,20 +15,20 @@ namespace Dough DataController::DataController() : _temperatureMeasurements( "temperature", TemperatureSensor::Instance(), - TEMPERATURE_AVG_LOOKBACK, - 30, + TEMPERATURE_AVERAGE_STORAGE, + TEMPERATURE_MEASURE_INTERVAL, PUBLISH_INTERVAL), _humidityMeasurements( "humidity", HumiditySensor::Instance(), - HUMIDITY_AVG_LOOKBACK, - 30, + HUMIDITY_AVERAGE_STORAGE, + HUMIDITY_MEASURE_INTERVAL, PUBLISH_INTERVAL), _distanceMeasurements( "distance", DistanceSensor::Instance(), - DISTANCE_AVG_LOOKBACK, - 1, + DISTANCE_AVERAGE_STORAGE, + DISTANCE_MEASURE_INTERVAL, PUBLISH_INTERVAL), _logger("DATA") { @@ -57,6 +57,7 @@ namespace Dough void DataController::handleMqttConnect(MQTT *mqtt) { mqtt->subscribe("container_height"); + mqtt->subscribe("temperature_offset"); } void DataController::handleMqttMessage(String &key, String &payload) @@ -65,6 +66,10 @@ namespace Dough { DataController::Instance()->setContainerHeight(payload.toInt()); } + if (key.equals("temperature_offset")) + { + DataController::Instance()->setTemperatureOffset(payload.toInt()); + } else { DataController::Instance()->_logger.log("sS", "ERROR - Unhandled MQTT message, key = ", key); @@ -101,6 +106,25 @@ namespace Dough _containerHeightSet = true; } + // Set the temperature offset in °C, to calibrate the temperature + // as measured by the device. On my device, the temperature raises about + // 5 degrees in the first few minutes, due to the circuitry warming up. + // I will have to fix that in the hardware as well, because 5 degrees is + // just redicoulous, but there might always be a diff that needs to be + // compensated for. + void DataController::setTemperatureOffset(int offset) + { + // Just a little safety measure. Devices should never need more than + // 10 degrees correction, right? + if (offset < -10 || offset > 10) { + _logger.log("sisis", "ERROR - Temperature offset ", offset, + "°C is too large (allowed range: -10°C up to +10°C)"); + return; + } + _logger.log("sis", "Set temperature offset to ", offset, "°C"); + _temperatureOffset = offset; + } + // ---------------------------------------------------------------------- // Loop // ---------------------------------------------------------------------- @@ -112,8 +136,6 @@ namespace Dough _temperatureMeasurements.loop(); _humidityMeasurements.loop(); _distanceMeasurements.loop(); - // Moved logic into sensor controller code. - //_sample(); } } @@ -122,55 +144,5 @@ namespace Dough _temperatureMeasurements.clearHistory(); _humidityMeasurements.clearHistory(); _distanceMeasurements.clearHistory(); - _sampleType = SAMPLE_TEMPERATURE; - _sampleCounter = 0; - } - - void DataController::_sample() - { - auto now = millis(); - auto delta = now - _lastSample; - auto tick = _lastSample == 0 || delta >= SAMPLE_INTERVAL; - - if (tick) - { - _lastSample = now; - - // Quickly dip the LED to indicate that a measurement has started. - // This is done synchroneously, because we suspend the timer interrupts - // in the upcoming code. - _ui->led3.off(); - delay(50); - _ui->led3.on(); - - // Suspend the UI timer interrupts, to not let these interfere - // with the sensor measurements. - _ui->suspend(); - - // Take a sample. - switch (_sampleType) - { - case SAMPLE_TEMPERATURE: - _temperatureMeasurements.loop(); - _sampleType = SAMPLE_HUMIDITY; - break; - case SAMPLE_HUMIDITY: - _humidityMeasurements.loop(); - _sampleType = SAMPLE_DISTANCE; - break; - case SAMPLE_DISTANCE: - _distanceMeasurements.loop(); - break; - } - - _ui->resume(); - - _sampleCounter++; - if (_sampleCounter == SAMPLE_CYCLE_LENGTH) - { - _sampleCounter = 0; - _sampleType = SAMPLE_TEMPERATURE; - } - } } } \ No newline at end of file diff --git a/src/Data/DataController.h b/src/Data/DataController.h index 172e351..6dfea03 100644 --- a/src/Data/DataController.h +++ b/src/Data/DataController.h @@ -1,21 +1,6 @@ #ifndef DOUGH_DATA_DATACONTROLLER_H #define DOUGH_DATA_DATACONTROLLER_H -// These definitions describes what measurements are performed in sequence. -// One measurement is done every SAMPLE_INTERVAL microseconds. -// We always start with a temperature measurement, then a humidity measurement, -// and finally a number of distance measurements. -// The SAMPLE_CYCLE_LENGTH defines the total number of samples in this sequence. -#define SAMPLE_INTERVAL 1000 -#define SAMPLE_CYCLE_LENGTH 30 // 1 temperature + 1 humidity + 28 distance samples - -// Two different values are published per sensor: a recent value and an average -// value. These definition define the number of recent measurements to include -// in the average computation. -#define TEMPERATURE_AVG_LOOKBACK 6 // making this a 3 minute average -#define HUMIDITY_AVG_LOOKBACK 6 // making this a 3 minute average -#define DISTANCE_AVG_LOOKBACK 28 * 2 * 3 // making this a 3 minute average - // The minimal interval in seconds at which to forcibly publish measurements to the // MQTT broker. When significant changes occur in the measurements, then these will // be published to the MQTT broker at all times, independent from this interval. @@ -51,6 +36,7 @@ namespace Dough void loop(); void clearHistory(); void setContainerHeight(int height); + void setTemperatureOffset(int offset); bool isConfigured(); static void handleMqttConnect(MQTT *mqtt); static void handleMqttMessage(String &key, String &value); @@ -63,11 +49,9 @@ namespace Dough SensorController _humidityMeasurements; SensorController _distanceMeasurements; Logger _logger; - unsigned long _lastSample = 0; - DoughSampleType _sampleType = SAMPLE_TEMPERATURE; - int _sampleCounter = 0; - int _containerHeight; + unsigned int _containerHeight; bool _containerHeightSet; + int _temperatureOffset = 0; void _sample(); }; } diff --git a/src/Data/SensorController.cpp b/src/Data/SensorController.cpp index 12218f4..e0b2880 100644 --- a/src/Data/SensorController.cpp +++ b/src/Data/SensorController.cpp @@ -136,6 +136,14 @@ namespace Dough void SensorController::_publish() { + // Quickly dip the LED to indicate that a publish has started. + // This is done synchroneously, because the upcoming code is too + // fast normally to register a LED going off and on again during + // the operation. + _ui->led1.off(); + delay(50); + _ui->led1.on(); + auto average = getAverage(); auto last = getLast(); @@ -201,4 +209,4 @@ namespace Dough _storage[i]->clear(); } } -} // namespace Dough \ No newline at end of file +} \ No newline at end of file diff --git a/src/Data/SensorController.h b/src/Data/SensorController.h index 879442c..87f8843 100644 --- a/src/Data/SensorController.h +++ b/src/Data/SensorController.h @@ -69,6 +69,6 @@ namespace Dough void _store(Measurement measurement); unsigned int _next(); }; -} // namespace Dough +} #endif diff --git a/src/Sensors/TemperatureSensor.cpp b/src/Sensors/TemperatureSensor.cpp index 855eac2..7cdeb83 100644 --- a/src/Sensors/TemperatureSensor.cpp +++ b/src/Sensors/TemperatureSensor.cpp @@ -47,4 +47,4 @@ namespace Dough { return 2; // prevent flapping when transitioning from value A to value B } -} // namespace Dough \ No newline at end of file +} \ No newline at end of file diff --git a/src/config.h b/src/config.h index 9f89aa0..532327d 100644 --- a/src/config.h +++ b/src/config.h @@ -1,20 +1,30 @@ -// The digital pin to which the DATA pin of the DHT11 -// temperature/humidity sensor is connected. -#define DHT11_DATA_PIN 10 +// The digital pins to which the push buttons are connected. +#define ONOFF_BUTTON_PIN 2 +#define SETUP_BUTTON_PIN 3 // The digital pins to which the TRIG and ECHO pins of // the HCSR04 distance sensor are connected. #define HCSR04_TRIG_PIN 4 #define HCSR04_ECHO_PIN 5 +// The digital pin to which the DATA pin of the DHT11 +// temperature/humidity sensor is connected. +#define DHT11_DATA_PIN 10 + // The digital pins to which the three LEDs are connected. #define LED1_PIN 8 #define LED2_PIN 7 -#define LED3_PIN 6 +#define LED3_PIN 6 // PWM pin, so pulsing during "device paused" is possible -// The digital pins to which the push buttons are connected. -#define ONOFF_BUTTON_PIN 2 -#define SETUP_BUTTON_PIN 3 +// Two different values are published per sensor: a recent value and an average +// value. These definitions define how often measurements must be taken and +// how many values must be stored to compute an average. +#define TEMPERATURE_MEASURE_INTERVAL 30 // measure twice per minute +#define TEMPERATURE_AVERAGE_STORAGE 6 // making this a 3 minute average +#define HUMIDITY_MEASURE_INTERVAL 30 // measure twice per minute +#define HUMIDITY_AVERAGE_STORAGE 6 // making this a 3 minute average +#define DISTANCE_MEASURE_INTERVAL 1 // measure every second +#define DISTANCE_AVERAGE_STORAGE 180 // making this a 3 minute average // The network configuration and possibly overrides for the above // definitions are stored in a separate header file, which is