implemented async PM sensor sampling

This commit is contained in:
CDaut 2022-02-14 20:09:10 +01:00 committed by CDaut
parent 89d6acf181
commit fe18044edd
3 changed files with 48 additions and 28 deletions

View file

@ -14,11 +14,16 @@ Sensor *pmSensor;
BluetoothServer *server;
bool makeDiscoverable = false;
//interrupt handler for sensor being pressed
void IRAM_ATTR startBleServerAdvertising() {
makeDiscoverable = true;
}
//helper function to create task for PM measurement
void startPmAsyncSampling(void * param){
((PmSensor *) pmSensor)->startAsyncSampling();
}
void setup() {
//initialize a Serial Connection
Serial.begin(BAUD_RATE);
@ -38,17 +43,25 @@ void setup() {
attachInterrupt(digitalPinToInterrupt(INTERRUPT_MAKE_DISCOVERABLE_PIN),
startBleServerAdvertising,
RISING);
//start an async task for measuring PM so the sensor won't block the whole system
xTaskCreate(
startPmAsyncSampling,
"Async PM sampling",
1024,
nullptr,
1,
nullptr
);
}
void loop() {
//check if the button has been pressed and handle appropriately
if (makeDiscoverable) {
server->startAdvertising();
makeDiscoverable = false;
}
//setup PM sensor measurement TODO: This blocks for 120 seconds and needs to be executed asynchronously
//((PmSensor *) pmSensor)->startAsyncSampling();
//obtain measurement from BMP280 Sensor
sensor_data_t sample = ((BmpSensor *) bmpSensor)->sampleLowEnergy();
server->setPressure(sample.pressure);
@ -62,6 +75,7 @@ void loop() {
sample.temperature,
pmSample.pm10,
pmSample.pm25);
//wait for one measurement cycle
delay(SLEEP_TIME * 1000);
}

View file

@ -21,19 +21,35 @@ PmSensor::PmSensor() {
this->PmSensor::sensor_setup();
}
void PmSensor::startAsyncSampling() {
[[noreturn]] void PmSensor::startAsyncSampling() {
this->enableStandbyMode();
PmSensor::sensorWait(SLEEP_TIME);
Serial.println("Started async task for PM sensor sampling.");
while (true) {
this->wakeUp();
sds011.perform_work();
//attach a callback on what to do when data sampling is complete
sds011.on_query_data_auto_completed([this](int n) {
Serial.println("Sampled new PM data.");
int pm25;
int pm10;
if (sds011.filter_data(n, pm25_table, pm10_table, pm25, pm10) &&
!isnan(pm10) && !isnan(pm25)) {
//set the right values
this->latestPM10 = float(pm10) / 10;
this->latestPM25 = float(pm25) / 10;
}
});
if (!sds011.query_data_auto_async(pm_tablesize, pm25_table, pm10_table)) {
Serial.println("measurement capture start failed");
}
PmSensor::sensorWait(MEASURE_TIME);
this->enableStandbyMode();
PmSensor::sensorWait(SLEEP_TIME);
}
}
/**
@ -41,6 +57,7 @@ void PmSensor::startAsyncSampling() {
*/
void PmSensor::enableStandbyMode() {
if (sds011.set_sleep(true)) { this->state = SensorState::ASLEEP; }
Serial.println("PM sensor went to sleep mode.");
}
/**
@ -48,6 +65,7 @@ void PmSensor::enableStandbyMode() {
*/
void PmSensor::wakeUp() {
if (sds011.set_sleep(false)) { this->state = SensorState::AWAKE; }
Serial.println("PM sensor woke up.");
}
/**
@ -64,18 +82,6 @@ void PmSensor::sensor_setup() {
//put the sensor into standby mode initially
this->PmSensor::enableStandbyMode();
Serial.println("SDS011 sensor initialized to standby mode.");
//attach a callback on what to do when data sampling is complete
sds011.on_query_data_auto_completed([this](int n) {
int pm25;
int pm10;
if (sds011.filter_data(n, pm25_table, pm10_table, pm25, pm10) &&
!isnan(pm10) && !isnan(pm25)) {
//set the right values
this->latestPM10 = float(pm10) / 10;
this->latestPM25 = float(pm25) / 10;
}
});
}
/**
@ -85,7 +91,7 @@ void PmSensor::sensor_setup() {
void PmSensor::sensorWait(int time) {
uint32_t deadline = millis() + time * 1000;
while (static_cast<int32_t>(deadline - millis()) > 0) {
delay(1000);
vTaskDelay(1000 / portTICK_PERIOD_MS);
sds011.perform_work();
}
}

View file

@ -17,7 +17,7 @@ public:
sensor_data_t sample() override;
void startAsyncSampling();
[[noreturn]] void startAsyncSampling();
void enableStandbyMode() override;