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

co2_sensor: 2s measurements should not be used for forced calibration.

* Trying 10s instead.
* Adding warning if timestep < 10s

Forced calibration should hopefully be more reliable now.
parent ab3e5689
Pipeline #3448 passed with stage
in 1 minute and 41 seconds
#include "co2_sensor.h" #include "co2_sensor.h"
namespace config { namespace config {
// Values should be defined in config.h // UPPERCASE values should be defined in config.h
uint16_t measurement_timestep = MEASUREMENT_TIMESTEP; // [s] Value between 2 and 1800 (range for SCD30 sensor) 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] const uint16_t altitude_above_sea_level = ALTITUDE_ABOVE_SEA_LEVEL; // [m]
uint16_t co2_calibration_level = ATMOSPHERIC_CO2_CONCENTRATION; // [ppm] uint16_t co2_calibration_level = ATMOSPHERIC_CO2_CONCENTRATION; // [ppm]
int8_t max_deviation_during_calibration = 30; // [ppm] const uint16_t measurement_timestep_bootup = 5; // [s] Measurement timestep during acclimatization.
int8_t enough_stable_measurements = 60;
const uint8_t max_deviation_during_bootup = 20; // [%] 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.
#ifdef TEMPERATURE_OFFSET #ifdef TEMPERATURE_OFFSET
// Residual heat from CO2 sensor seems to be high enough to change the temperature reading. How much should it be 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. // NOTE: Sign isn't relevant. The returned temperature will always be shifted down.
...@@ -131,14 +133,16 @@ namespace sensor { ...@@ -131,14 +133,16 @@ namespace sensor {
&& co2 < (previous_co2 + config::max_deviation_during_calibration)) { && co2 < (previous_co2 + config::max_deviation_during_calibration)) {
stable_measurements++; stable_measurements++;
Serial.print(F("Number of stable measurements : ")); Serial.print(F("Number of stable measurements : "));
Serial.println(stable_measurements); Serial.print(stable_measurements);
Serial.print(F(" / "));
Serial.println(config::stable_measurements_before_calibration);
switchState(PREPARE_CALIBRATION_STABLE); switchState(PREPARE_CALIBRATION_STABLE);
} else { } else {
stable_measurements = 0; stable_measurements = 0;
switchState(PREPARE_CALIBRATION_UNSTABLE); switchState(PREPARE_CALIBRATION_UNSTABLE);
} }
previous_co2 = co2; previous_co2 = co2;
return (stable_measurements == config::enough_stable_measurements); return (stable_measurements == config::stable_measurements_before_calibration);
} }
void startCalibrationProcess() { void startCalibrationProcess() {
...@@ -146,8 +150,10 @@ namespace sensor { ...@@ -146,8 +150,10 @@ namespace sensor {
* For best results, the sensor has to be run in a stable environment in continuous mode at * For best results, the sensor has to be run in a stable environment in continuous mode at
* a measurement rate of 2s for at least two minutes before applying the FRC command and sending the reference value. * a measurement rate of 2s for at least two minutes before applying the FRC command and sending the reference value.
*/ */
Serial.println(F("Setting SCD30 timestep to 2s, prior to calibration.")); Serial.print(F("Setting SCD30 timestep to "));
scd30.setMeasurementInterval(2); // [s] The change will only take effect after next measurement. Serial.print(config::timestep_during_calibration);
Serial.println(F("s, prior to calibration."));
scd30.setMeasurementInterval(config::timestep_during_calibration); // [s] The change will only take effect after next measurement.
Serial.println(F("Waiting until the measurements are stable for at least 2 minutes.")); Serial.println(F("Waiting until the measurements are stable for at least 2 minutes."));
Serial.println(F("It could take a very long time.")); Serial.println(F("It could take a very long time."));
switchState(PREPARE_CALIBRATION_UNSTABLE); switchState(PREPARE_CALIBRATION_UNSTABLE);
...@@ -195,6 +201,9 @@ namespace sensor { ...@@ -195,6 +201,9 @@ namespace sensor {
Serial.print(F("Setting SCD30 timestep to ")); Serial.print(F("Setting SCD30 timestep to "));
Serial.print(config::measurement_timestep); Serial.print(config::measurement_timestep);
Serial.println(F(" s.")); Serial.println(F(" s."));
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]
} }
if ((current_state == PREPARE_CALIBRATION_UNSTABLE) || (current_state == PREPARE_CALIBRATION_STABLE)) { if ((current_state == PREPARE_CALIBRATION_UNSTABLE) || (current_state == PREPARE_CALIBRATION_STABLE)) {
...@@ -313,7 +322,7 @@ namespace sensor { ...@@ -313,7 +322,7 @@ namespace sensor {
} }
void calibrateSensorRightNow(int32_t calibrationLevel) { void calibrateSensorRightNow(int32_t calibrationLevel) {
stable_measurements = config::enough_stable_measurements; stable_measurements = config::stable_measurements_before_calibration;
calibrateSensorToSpecificPPM(calibrationLevel); calibrateSensorToSpecificPPM(calibrationLevel);
} }
} }
...@@ -27,7 +27,9 @@ ...@@ -27,7 +27,9 @@
*/ */
// How often should measurement be performed, and displayed? // How often should measurement be performed, and displayed?
//NOTE: SCD30 timer does not seem to be very precise. Variations may occur. //WARNING: On some sensors, measurements become very unreliable when timestep is set to 2s.
//NOTE: 10s or longer should be fine in order to get reliable results.
//NOTE: SCD30 timer does not seem to be very precise. Time variations may occur.
# define MEASUREMENT_TIMESTEP 60 // [s] Value between 2 and 1800 (range for SCD30 sensor) # define MEASUREMENT_TIMESTEP 60 // [s] Value between 2 and 1800 (range for SCD30 sensor)
// How often should measurements be appended to CSV ? // How often should measurements be appended to CSV ?
......
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