#include #include #include #include #define LILYGO_T5_V213 // needed for the display libraries #include #include #include // screen model, probably correct #include #include #include GxIO_Class io(SPI, EPD_CS, EPD_DC, EPD_RSET); GxEPD_Class display(io, EPD_RSET, EPD_BUSY); SPIClass SDSPI(VSPI); // for sdcard SensirionI2CScd4x scd4x; uint16_t co2 = 0; float temperature = 0.0f; float humidity = 0.0f; struct sps30_measurement m; void showThings(bool all=false) { display.fillScreen(GxEPD_WHITE); display.setCursor(0,20); display.print("Co2:"); display.println(co2); display.print("T:"); display.print(temperature); display.print(" H:"); display.println(humidity); display.print("PM 1:"); display.print(m.mc_1p0); display.print(" PM 2.5:"); display.println(m.mc_2p5); display.print("PM 4:"); display.print(m.mc_4p0); display.print(" PM 10:"); display.println(m.mc_10p0); // "partial" update display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false); } unsigned long startTime; bool frcDone = false; void setup() { Serial.begin(115200); while (!Serial) { delay(100); } // the board's definition says SCL=23, but I have SCL=22 Wire.begin(21,22); SPI.begin(EPD_SCLK, EPD_MISO, EPD_MOSI); display.init(); display.setTextColor(GxEPD_BLACK); display.setRotation(3); display.setFont(&FreeMonoBold9pt7b); showThings(); uint16_t error; char errorMessage[256]; scd4x.begin(Wire); // stop potentially previously started measurement error = scd4x.stopPeriodicMeasurement(); if (error) { Serial.print("Error trying to execute stopPeriodicMeasurement(): "); errorToString(error, errorMessage, 256); Serial.println(errorMessage); } error = scd4x.setAutomaticSelfCalibration(1); if (error) { Serial.print("Error trying to execute setAutomaticSelfCalibration(): "); errorToString(error, errorMessage, 256); Serial.println(errorMessage); } // Start Measurement error = scd4x.startPeriodicMeasurement(); if (error) { Serial.print("Error trying to execute startPeriodicMeasurement(): "); errorToString(error, errorMessage, 256); Serial.println(errorMessage); } startTime = millis(); // this will try to re-init Wire, emit a warning, and carry on sensirion_i2c_init(); while (sps30_probe() != 0) { Serial.print("SPS sensor probing failed\n"); delay(500); } int16_t ret; uint8_t auto_clean_days = 4; uint32_t auto_clean; ret = sps30_set_fan_auto_cleaning_interval_days(auto_clean_days); if (ret) { Serial.print("error setting the auto-clean interval: "); Serial.println(ret); } ret = sps30_start_measurement(); if (ret < 0) { Serial.print("error starting measurement\n"); } Serial.println("Waiting for first measurement... (5 sec)"); } void loop() { uint16_t error; char errorMessage[256]; delay(5000); Serial.println(millis()); if (!frcDone && (millis() - startTime > (3*60 + 30)*1000)) { // 3½ minutes Serial.println("calibration"); frcDone=true; display.fillScreen(GxEPD_WHITE); display.setCursor(0,20); display.print("FRC"); display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false); scd4x.stopPeriodicMeasurement(); delay(500); uint16_t frcCorrection; error = scd4x.performForcedRecalibration(420,frcCorrection); if (error != 0) { Serial.print("scd4x error "); errorToString(error, errorMessage, 256); Serial.println(errorMessage); } Serial.println(frcCorrection); Serial.println(frcCorrection - 0x8000); display.fillScreen(GxEPD_WHITE); display.setCursor(0,20); display.print("FRC ");display.print(frcCorrection); display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false); delay(500); scd4x.startPeriodicMeasurement(); delay(2000); } error = scd4x.readMeasurement(co2, temperature, humidity); if (error != 0) { Serial.print("scd4x error "); errorToString(error, errorMessage, 256); Serial.println(errorMessage); } char serial[SPS30_MAX_SERIAL_LEN]; uint16_t data_ready; int16_t ret; do { ret = sps30_read_data_ready(&data_ready); if (ret < 0) { Serial.print("error reading data-ready flag: "); Serial.println(ret); } else if (!data_ready) Serial.print("data not ready, no new measurement available\n"); else break; delay(100); /* retry in 100ms */ } while (1); ret = sps30_read_measurement(&m); if (error || ret <0) { return; } showThings(); }