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;
|
||||
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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public:
|
|||
|
||||
sensor_data_t sample() override;
|
||||
|
||||
void startAsyncSampling();
|
||||
[[noreturn]] void startAsyncSampling();
|
||||
|
||||
|
||||
void enableStandbyMode() override;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue