implemented async PM sensor sampling
This commit is contained in:
parent
89d6acf181
commit
fe18044edd
3 changed files with 48 additions and 28 deletions
|
|
@ -14,11 +14,16 @@ Sensor *pmSensor;
|
||||||
BluetoothServer *server;
|
BluetoothServer *server;
|
||||||
bool makeDiscoverable = false;
|
bool makeDiscoverable = false;
|
||||||
|
|
||||||
|
//interrupt handler for sensor being pressed
|
||||||
void IRAM_ATTR startBleServerAdvertising() {
|
void IRAM_ATTR startBleServerAdvertising() {
|
||||||
makeDiscoverable = true;
|
makeDiscoverable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//helper function to create task for PM measurement
|
||||||
|
void startPmAsyncSampling(void * param){
|
||||||
|
((PmSensor *) pmSensor)->startAsyncSampling();
|
||||||
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
//initialize a Serial Connection
|
//initialize a Serial Connection
|
||||||
Serial.begin(BAUD_RATE);
|
Serial.begin(BAUD_RATE);
|
||||||
|
|
@ -38,17 +43,25 @@ void setup() {
|
||||||
attachInterrupt(digitalPinToInterrupt(INTERRUPT_MAKE_DISCOVERABLE_PIN),
|
attachInterrupt(digitalPinToInterrupt(INTERRUPT_MAKE_DISCOVERABLE_PIN),
|
||||||
startBleServerAdvertising,
|
startBleServerAdvertising,
|
||||||
RISING);
|
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() {
|
void loop() {
|
||||||
|
//check if the button has been pressed and handle appropriately
|
||||||
if (makeDiscoverable) {
|
if (makeDiscoverable) {
|
||||||
server->startAdvertising();
|
server->startAdvertising();
|
||||||
makeDiscoverable = false;
|
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
|
//obtain measurement from BMP280 Sensor
|
||||||
sensor_data_t sample = ((BmpSensor *) bmpSensor)->sampleLowEnergy();
|
sensor_data_t sample = ((BmpSensor *) bmpSensor)->sampleLowEnergy();
|
||||||
server->setPressure(sample.pressure);
|
server->setPressure(sample.pressure);
|
||||||
|
|
@ -62,6 +75,7 @@ void loop() {
|
||||||
sample.temperature,
|
sample.temperature,
|
||||||
pmSample.pm10,
|
pmSample.pm10,
|
||||||
pmSample.pm25);
|
pmSample.pm25);
|
||||||
|
|
||||||
//wait for one measurement cycle
|
//wait for one measurement cycle
|
||||||
delay(SLEEP_TIME * 1000);
|
delay(SLEEP_TIME * 1000);
|
||||||
}
|
}
|
||||||
|
|
@ -21,19 +21,35 @@ PmSensor::PmSensor() {
|
||||||
this->PmSensor::sensor_setup();
|
this->PmSensor::sensor_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PmSensor::startAsyncSampling() {
|
[[noreturn]] void PmSensor::startAsyncSampling() {
|
||||||
|
|
||||||
this->enableStandbyMode();
|
Serial.println("Started async task for PM sensor sampling.");
|
||||||
PmSensor::sensorWait(SLEEP_TIME);
|
|
||||||
|
|
||||||
|
while (true) {
|
||||||
this->wakeUp();
|
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)) {
|
if (!sds011.query_data_auto_async(pm_tablesize, pm25_table, pm10_table)) {
|
||||||
Serial.println("measurement capture start failed");
|
Serial.println("measurement capture start failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
PmSensor::sensorWait(MEASURE_TIME);
|
PmSensor::sensorWait(MEASURE_TIME);
|
||||||
|
|
||||||
|
this->enableStandbyMode();
|
||||||
|
PmSensor::sensorWait(SLEEP_TIME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,6 +57,7 @@ void PmSensor::startAsyncSampling() {
|
||||||
*/
|
*/
|
||||||
void PmSensor::enableStandbyMode() {
|
void PmSensor::enableStandbyMode() {
|
||||||
if (sds011.set_sleep(true)) { this->state = SensorState::ASLEEP; }
|
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() {
|
void PmSensor::wakeUp() {
|
||||||
if (sds011.set_sleep(false)) { this->state = SensorState::AWAKE; }
|
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
|
//put the sensor into standby mode initially
|
||||||
this->PmSensor::enableStandbyMode();
|
this->PmSensor::enableStandbyMode();
|
||||||
Serial.println("SDS011 sensor initialized to standby mode.");
|
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) {
|
void PmSensor::sensorWait(int time) {
|
||||||
uint32_t deadline = millis() + time * 1000;
|
uint32_t deadline = millis() + time * 1000;
|
||||||
while (static_cast<int32_t>(deadline - millis()) > 0) {
|
while (static_cast<int32_t>(deadline - millis()) > 0) {
|
||||||
delay(1000);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
sds011.perform_work();
|
sds011.perform_work();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ public:
|
||||||
|
|
||||||
sensor_data_t sample() override;
|
sensor_data_t sample() override;
|
||||||
|
|
||||||
void startAsyncSampling();
|
[[noreturn]] void startAsyncSampling();
|
||||||
|
|
||||||
|
|
||||||
void enableStandbyMode() override;
|
void enableStandbyMode() override;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue