#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; public: PM(uint8_t acd=4, unsigned long ri=30000) : auto_clean_days(acd), last_measurment_millis(0), read_interval_millis(ri) {} void start() { // this will try to re-init Wire, emit a warning, and carry on sensirion_i2c_init(); while (sps30_probe() != 0) { Serial.print("PM sensor probing failed\n"); 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.print("PM starting measurement error\n"); } } bool dataReady() { uint16_t data_ready; int16_t ret; // have we read recently? unsigned long now=millis(); // that first check is in case of overflow & rollover if (now > last_measurment_millis && (now - last_measurment_millis) < read_interval_millis) { return false; } sps30_wake_up(); sps30_start_measurement(); 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(); } };