#pragma once #include #include "data.h" /* start measuring read once, stop, sleep ready? if (now-last measurements) < read_interval, no else: start measuring, return ready status */ class PM { private: uint8_t auto_clean_days; unsigned long last_measurment_millis; unsigned long read_interval_millis; bool awake; public: PM(uint8_t acd=4, unsigned long ri=30000) : auto_clean_days(acd), last_measurment_millis(0), read_interval_millis(ri), awake(false) {} void start() { // this will try to re-init Wire, emit a warning, and carry on sensirion_i2c_init(); while (sps30_probe() != 0) { Serial.println("! PM sensor probing failed"); delay(500); } int16_t ret; ret = sps30_set_fan_auto_cleaning_interval_days(auto_clean_days); if (ret) { Serial.print("! PM setting the auto-clean interval error: "); Serial.println(ret); } ret = sps30_start_measurement(); if (ret < 0) { Serial.println("! PM starting measurement error"); } awake=true; } bool dataReady() { uint16_t data_ready; int16_t ret; // have we read recently? unsigned long now=millis(); if ( last_measurment_millis > 0 && // have we measured once at least? now > last_measurment_millis && // has there been no overflow & rollover? (now - last_measurment_millis) < read_interval_millis // is it too soon? ) { return false; } if (!awake) { sps30_wake_up(); sps30_start_measurement(); awake=true; } ret = sps30_read_data_ready(&data_ready); if (ret < 0) { Serial.print("! PM reading data-ready flag error: "); Serial.println(ret); return false; } else if (!data_ready) { return false; } return true; } void read(SensorData *data) { char serial[SPS30_MAX_SERIAL_LEN]; int16_t ret; ret = sps30_read_measurement(&(data->pm)); if (ret <0) { Serial.print("! PM reading measurement error: "); Serial.println(ret); return; } last_measurment_millis = millis(); sps30_stop_measurement(); sps30_sleep(); awake=false; } bool serialCommand(const String &tag, const String &command) { return false; } };