#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("\nSetting SCD30 timestep to " + String(config::measurement_timestep) + " s."); scd30.setMeasurementInterval(config::measurement_timestep); // [s] Serial.print("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. Serial.print("Temperature offset is : -"); Serial.print(scd30.getTemperatureOffset()); Serial.println(" K"); Serial.print("Auto-calibration is "); Serial.println(config::auto_calibrate_sensor ? "ON." : "OFF."); } // Force SCD30 calibration with countdown. void startCalibrationProcess() { /** 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("Setting SCD30 timestep to 2s, prior to calibration."); scd30.setMeasurementInterval(2); // [s] The change will only take effect after next measurement. LedEffects::showKITTWheel(color::blue, config::measurement_timestep); Serial.println("Waiting 2 minutes."); LedEffects::showKITTWheel(color::blue, 120); 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); FS_LIB.end(); ESP.restart(); } }