An error occurred while loading the file. Please try again.
-
Schaaf authored2dbd8f1f
#include "co2_sensor.h"
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 altitude_above_sea_level = ALTITUDE_ABOVE_SEA_LEVEL; // [m]
uint16_t co2_calibration_level = ATMOSPHERIC_CO2_CONCENTRATION; // [ppm]
#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
const bool auto_calibrate_sensor = AUTO_CALIBRATE_SENSOR; // [true / false]
}
namespace sensor {
SCD30 scd30;
int16_t co2 = 0;
float temperature = 0;
float humidity = 0;
String timestamp = "";
void initialize() {
#if defined(ESP8266)
Wire.begin(12, 14); // ESP8266 - D6, D5;
#endif
#if defined(ESP32)
Wire.begin(21, 22); // ESP32
/**
* SCD30 ESP32
* VCC --- 3V3
* GND --- GND
* SCL --- SCL (GPIO22) //NOTE: GPIO3 Would be more convenient (right next to GND)
* SDA --- SDA (GPIO21) //NOTE: GPIO1 would be more convenient (right next to GPO3)
*/
#endif
// CO2
if (scd30.begin(config::auto_calibrate_sensor) == false) {
Serial.println("Air sensor not detected. Please check wiring. Freezing...");
while (1) {
LedEffects::showWaitingLED(color::red);
}
}
// SCD30 has its own timer.
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(F("Setting temperature offset to -"));
Serial.print(abs(config::temperature_offset));
Serial.println(" K.");
scd30.setTemperatureOffset(abs(config::temperature_offset)); // setTemperatureOffset only accepts positive numbers, but shifts the temperature down.
delay(100);
Serial.print(F("Temperature offset is : -"));
Serial.print(scd30.getTemperatureOffset());
Serial.println(" K");
Serial.print(F("Auto-calibration is "));
Serial.println(config::auto_calibrate_sensor ? "ON." : "OFF.");
}
bool updateDataIfAvailable() {
//TODO: Save count of stable measurements
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//TODO: Compare time to previous measurements, check that it's not too far away from config::measurement_interval
if (scd30.dataAvailable()) {
co2 = scd30.getCO2();
temperature = scd30.getTemperature();
humidity = scd30.getHumidity();
return true;
}
return false;
}
void waitUntilMeasurementsAreStable() {
//TODO: Refactor completely, in order to avoid very long loop?
/** From the sensor documentation:
* 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.
*/
Serial.println(F("Setting SCD30 timestep to 2s, prior to calibration."));
scd30.setMeasurementInterval(2); // [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("It could take a very long time."));
//########################################################################################################
// (c) Mario Lukas
// https://github.com/mariolukas/Watterott-CO2-Ampel-Plus-Firmware/blob/main/CO2-Ampel_Plus/Sensor.cpp#L57
uint32_t last_color = color::blue;
int stable_measurements = 0, last_co2 = 0;
for (stable_measurements = 0; stable_measurements < 60;) {
if (scd30.dataAvailable()) {
co2 = scd30.getCO2();
//No more than +/-30ppm variation compared to previous measurement.
if ((co2 > (last_co2 - 30)) && (co2 < (last_co2 + 30))) {
last_color = color::green;
stable_measurements++;
} else {
last_color = color::red;
stable_measurements = 0;
}
last_co2 = co2;
}
LedEffects::showKITTWheel(last_color, 1);
}
//########################################################################################################
}
void startCalibrationProcess() {
waitUntilMeasurementsAreStable();
Serial.print("Starting SCD30 calibration...");
scd30.setAltitudeCompensation(config::altitude_above_sea_level);
scd30.setForcedRecalibrationFactor(config::co2_calibration_level);
Serial.println(" Done!");
Serial.println("Sensor calibrated.");
Serial.println("Sensor will now restart.");
LedEffects::showKITTWheel(color::green, 5);
//TODO: Add LEDs off and move to util::reset()
FS_LIB.end();
ESP.restart();
}
}