Commit c1fa76f3 authored by Eric Duminil's avatar Eric Duminil
Browse files

Sensor config via web

parent 9c11a3cb
Pipeline #5761 passed with stage
in 2 minutes and 20 seconds
#include "co2_sensor.h"
#include "config.h"
#include "web_config.h"
#include "ntp.h"
#include "led_effects.h"
#include "sensor_console.h"
......@@ -11,25 +11,12 @@
#include "src/lib/SparkFun_SCD30_Arduino_Library/src/SparkFun_SCD30_Arduino_Library.h" // From: http://librarymanager/All#SparkFun_SCD30
namespace config {
// UPPERCASE values should be defined in config.h
uint16_t measurement_timestep = MEASUREMENT_TIMESTEP; // [s] Value between 2 and 1800 (range for SCD30 sensor).
const uint16_t altitude_above_sea_level = ALTITUDE_ABOVE_SEA_LEVEL; // [m]
uint16_t co2_calibration_level = ATMOSPHERIC_CO2_CONCENTRATION; // [ppm]
const uint16_t measurement_timestep_bootup = 5; // [s] Measurement timestep during acclimatization.
const uint8_t max_deviation_during_bootup = 20; // [%]
const int8_t max_deviation_during_calibration = 30; // [ppm]
const int16_t timestep_during_calibration = 10; // [s] WARNING: Measurements can be unreliable for timesteps shorter than 10s.
const int8_t stable_measurements_before_calibration = 120 / timestep_during_calibration; // [-] Stable measurements during at least 2 minutes.
const uint16_t co2_alert_threshold = 2000; // [ppm] Display a flashing led ring, if concentration exceeds this value
#ifdef TEMPERATURE_OFFSET
// Residual heat from CO2 sensor seems to be high enough to change the temperature reading. How much should it be offset?
// NOTE: Sign isn't relevant. The returned temperature will always be shifted down.
const float temperature_offset = TEMPERATURE_OFFSET; // [K]
#else
const float temperature_offset = -3.0; // [K] Temperature measured by sensor is usually at least 3K too high.
#endif
bool auto_calibrate_sensor = AUTO_CALIBRATE_SENSOR; // [true / false]
const bool debug_sensor_states = false; // If true, log state transitions over serial console
}
......@@ -96,9 +83,9 @@ namespace sensor {
scd30.reset();
Serial.print(F("Setting temperature offset to -"));
Serial.print(abs(config::temperature_offset));
Serial.print(abs(*config::temperature_offset));
Serial.println(F(" K."));
scd30.setTemperatureOffset(abs(config::temperature_offset)); // setTemperatureOffset only accepts positive numbers, but shifts the temperature down.
scd30.setTemperatureOffset(abs(*config::temperature_offset)); // setTemperatureOffset only accepts positive numbers, but shifts the temperature down.
delay(100);
Serial.print(F("Temperature offset is : -"));
......@@ -106,7 +93,7 @@ namespace sensor {
Serial.println(F(" K"));
Serial.print(F("Auto-calibration is "));
Serial.println(config::auto_calibrate_sensor ? "ON." : "OFF.");
Serial.println(*config::auto_calibrate_sensor ? "ON." : "OFF.");
// SCD30 has its own timer.
//NOTE: The timer seems to be inaccurate, though, possibly depending on voltage. Should it be offset?
......@@ -170,8 +157,8 @@ namespace sensor {
void calibrate() {
Serial.print(F("Calibrating SCD30 now..."));
scd30.setAltitudeCompensation(config::altitude_above_sea_level);
scd30.setForcedRecalibrationFactor(config::co2_calibration_level);
scd30.setAltitudeCompensation(*config::altitude_above_sea_level);
scd30.setForcedRecalibrationFactor(*config::co2_calibration_level);
Serial.println(F(" Done!"));
Serial.println(F("Sensor calibrated."));
switchState(BOOTUP); // In order to stop the calibration and select the desired timestep.
......@@ -210,12 +197,12 @@ namespace sensor {
switchState(READY);
Serial.println(F("Sensor acclimatization finished."));
Serial.print(F("Setting SCD30 timestep to "));
Serial.print(config::measurement_timestep);
Serial.print(*config::measurement_timestep);
Serial.println(F(" s."));
if (config::measurement_timestep < 10) {
if (*config::measurement_timestep < 10) {
Serial.println(F("WARNING: Timesteps shorter than 10s can lead to unreliable measurements!"));
}
scd30.setMeasurementInterval(config::measurement_timestep); // [s]
scd30.setMeasurementInterval(*config::measurement_timestep); // [s]
}
// Check for pre-calibration states first, because we do not want to
......@@ -305,7 +292,7 @@ namespace sensor {
}
void setAutoCalibration(int32_t autoCalibration) {
config::auto_calibrate_sensor = autoCalibration;
*config::auto_calibrate_sensor = autoCalibration;
scd30.setAutoSelfCalibration(autoCalibration);
Serial.print(F("Setting auto-calibration to : "));
Serial.println(autoCalibration ? F("On.") : F("Off."));
......@@ -317,7 +304,7 @@ namespace sensor {
Serial.print(timestep);
Serial.println(F("s (change will only be applied after next measurement)."));
scd30.setMeasurementInterval(timestep);
config::measurement_timestep = timestep;
*config::measurement_timestep = timestep;
led_effects::showKITTWheel(color::green, 1);
}
}
......@@ -325,8 +312,8 @@ namespace sensor {
void calibrateSensorToSpecificPPM(int32_t calibrationLevel) {
if (calibrationLevel >= 400 && calibrationLevel <= 2000) {
Serial.print(F("Force calibration, at "));
config::co2_calibration_level = calibrationLevel;
Serial.print(config::co2_calibration_level);
*config::co2_calibration_level = calibrationLevel;
Serial.print(*config::co2_calibration_level);
Serial.println(F(" ppm."));
startCalibrationProcess();
}
......@@ -335,8 +322,8 @@ namespace sensor {
void calibrateSensorRightNow(int32_t calibrationLevel) {
if (calibrationLevel >= 400 && calibrationLevel <= 2000) {
Serial.print(F("Force calibration, right now, at "));
config::co2_calibration_level = calibrationLevel;
Serial.print(config::co2_calibration_level);
*config::co2_calibration_level = calibrationLevel;
Serial.print(*config::co2_calibration_level);
Serial.println(F(" ppm."));
calibrate();
}
......
......@@ -3,13 +3,6 @@
#include <stdint.h> // For uint16_t
namespace config {
extern uint16_t measurement_timestep; // [s] Value between 2 and 1800 (range for SCD30 sensor)
extern bool auto_calibrate_sensor; // [true / false]
extern uint16_t co2_calibration_level; // [ppm]
extern const float temperature_offset; // [K] Sign isn't relevant.
}
namespace sensor {
extern uint16_t co2;
extern float temperature;
......
#include "csv_writer.h"
#include "config.h"
#include "web_config.h"
#include "ntp.h"
#include "led_effects.h"
......
......@@ -9,6 +9,8 @@
#include "config.h"
#include "util.h"
#include "sensor_console.h"
#include <IotWebConfTParameter.h>
#include <IotWebConf.h>
#include <IotWebConfOptionalGroup.h>
......@@ -264,6 +266,17 @@ namespace web_config {
}
}
/***
* Define all the corresponding config values as reference, so that they can be updated.
*/
namespace config {
// CSV
uint16_t *csv_interval = &web_config::csvTimestepParam.value();
// Sensor
uint16_t *measurement_timestep = &web_config::timestepParam.value(); // [s] Value between 2 and 1800 (range for SCD30 sensor).
uint16_t *altitude_above_sea_level = &web_config::altitudeParam.value(); // [m]
uint16_t *co2_calibration_level = &web_config::atmosphericCO2Param.value(); // [ppm]
bool *auto_calibrate_sensor = &web_config::autoCalibrateParam.value(); // [true / false]
float *temperature_offset = &web_config::temperatureOffsetParam.value(); // [K] Sign isn't relevant.
}
\ No newline at end of file
......@@ -9,10 +9,15 @@
# include <WebServer.h>
#endif
#include <IotWebConfTParameter.h>
namespace config {
extern uint16_t *csv_interval; // [s]
// Sensor
extern uint16_t *measurement_timestep; // [s] Value between 2 and 1800 (range for SCD30 sensor).
extern uint16_t *altitude_above_sea_level; // [m]
extern uint16_t *co2_calibration_level; // [ppm]
extern bool *auto_calibrate_sensor; // [true / false]
extern float *temperature_offset; // [K] Sign isn't relevant.
}
namespace web_config {
......@@ -20,6 +25,7 @@ namespace web_config {
void setWifiConnectionCallback(void (*function)());
void setWifiConnectionFailedCallback(void (*function)());
void update();
//TODO: Add saveConfig(), for e.g. after custom setters. Or simply reset after each configchange?
#if defined(ESP8266)
extern ESP8266WebServer http;
......
......@@ -245,7 +245,7 @@ namespace web_server {
// Body
snprintf_P(content, sizeof(content), body_template, ampel.sensorId, sensor::co2, sensor::temperature,
sensor::humidity, sensor::timestamp, config::measurement_timestep,
sensor::humidity, sensor::timestamp, *config::measurement_timestep,
#ifdef AMPEL_CSV
csv_writer::last_successful_write, *config::csv_interval, csv_writer::getAvailableSpace() / 1024,
#endif
......@@ -256,7 +256,7 @@ namespace web_server {
lorawan::connected ? "Yes" : "No", config::lorawan_frequency_plan, lorawan::last_transmission,
config::lorawan_sending_interval,
#endif
config::temperature_offset, config::auto_calibrate_sensor ? "Yes" : "No", ampel.sensorId, ampel.sensorId,
*config::temperature_offset, *config::auto_calibrate_sensor ? "Yes" : "No", ampel.sensorId, ampel.sensorId,
wifi::local_ip, wifi::local_ip, ampel.macAddress, ESP.getFreeHeap(), esp_get_max_free_block_size(), esp_get_heap_fragmentation(),
ampel.max_loop_duration, ampel.board, ampel.version, dd, hh, mm, ss);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment