Commit dcba0a6a authored by Käppler's avatar Käppler
Browse files

co2_sensor: wait for acclimatization after startup

The SCD30 sensor has a response time of 20 s to reach
67 % of its final reading. The first measurement
can thus be unreliable, if the environment changed
shortly prior to startup. Set measurement interval to the
shortest possible value (2 s) and wait then, until the
measurements have stabilized. Show a blue led effect in
the meanwhile.
parent 6ad8554c
......@@ -3,10 +3,12 @@
namespace config {
// 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 measurement_timestep_bootup = 2; // [s] Measurement timestep during acclimatization
const uint16_t altitude_above_sea_level = ALTITUDE_ABOVE_SEA_LEVEL; // [m]
uint16_t co2_calibration_level = ATMOSPHERIC_CO2_CONCENTRATION; // [ppm]
int8_t max_deviation_during_calibration = 30; // [ppm]
int8_t enough_stable_measurements = 60;
const uint8_t max_deviation_during_bootup = 20; // [%]
#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.
......@@ -97,9 +99,9 @@ namespace sensor {
//NOTE: The timer seems to be inaccurate, though, possibly depending on voltage. Should it be offset?
Serial.println();
Serial.print(F("Setting SCD30 timestep to "));
Serial.print(config::measurement_timestep);
Serial.println(" s.");
scd30.setMeasurementInterval(config::measurement_timestep); // [s]
Serial.print(config::measurement_timestep_bootup);
Serial.println(" s during acclimatization.");
scd30.setMeasurementInterval(config::measurement_timestep_bootup); // [s]
sensor_console::defineIntCommand("co2", setCO2forDebugging, F(" 1500 (Sets co2 level, for debugging purposes)"));
sensor_console::defineIntCommand("timer", setTimer, F(" 30 (Sets measurement interval, in s)"));
......@@ -122,6 +124,16 @@ namespace sensor {
previous_measurement_at = now;
}
bool hasSensorSettled() {
static uint16_t last_co2 = 0;
uint16_t delta;
delta = abs(co2 - last_co2);
last_co2 = co2;
// We assume the sensor has acclimated to the environment if measurements
// change less than a specified percentage of the current value.
return (co2 > 0 && delta < ((uint32_t)co2 * config::max_deviation_during_bootup / 100));
}
bool countStableMeasurements() {
// Returns true, if a sufficient number of stable measurements has been observed.
static int16_t previous_co2 = 0;
......@@ -185,6 +197,15 @@ namespace sensor {
}
void switchStateForCurrentPPM() {
if (current_state == BOOTUP) {
if (!hasSensorSettled()) return;
switchState(READY);
Serial.println(F("Sensor acclimatization finished."));
Serial.print(F("Setting SCD30 timestep to "));
Serial.print(config::measurement_timestep);
Serial.println(" s.");
scd30.setMeasurementInterval(config::measurement_timestep); // [s]
}
if (co2 == 0) {
// NOTE: Data is available, but it's sometimes erroneous: the sensor outputs
// zero ppm but non-zero temperature and non-zero humidity.
......
Markdown is supported
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