mirror of
https://github.com/meshtastic/firmware.git
synced 2025-07-31 02:45:41 +00:00
Add dynamic measurement interval for SEN5X
This commit is contained in:
parent
e712200509
commit
2c72d94325
@ -47,6 +47,7 @@ int32_t AirQualityTelemetryModule::runOnce()
|
||||
}
|
||||
|
||||
uint32_t result = UINT32_MAX;
|
||||
uint32_t sen5xPendingForReady;
|
||||
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
@ -102,6 +103,14 @@ int32_t AirQualityTelemetryModule::runOnce()
|
||||
return sen5xSensor.wakeUp();
|
||||
}
|
||||
|
||||
// Check if sen5x is ready to return data, or if it needs more time because of the low concentration threshold
|
||||
if (sen5xSensor.hasSensor() && sen5xSensor.isActive()) {
|
||||
sen5xPendingForReady = sen5xSensor.pendingForReady();
|
||||
if (sen5xPendingForReady) {
|
||||
return sen5xPendingForReady;
|
||||
}
|
||||
}
|
||||
|
||||
if (((lastSentToMesh == 0) ||
|
||||
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
|
||||
moduleConfig.telemetry.air_quality_interval,
|
||||
@ -118,14 +127,13 @@ int32_t AirQualityTelemetryModule::runOnce()
|
||||
lastSentToPhone = millis();
|
||||
}
|
||||
|
||||
|
||||
// TODO - Add logic here to send the sensor to idle ONLY if there is enough time to wake it up before the next reading cycle
|
||||
#ifdef PMSA003I_ENABLE_PIN
|
||||
pmsa003iSensor.sleep();
|
||||
#endif /* PMSA003I_ENABLE_PIN */
|
||||
|
||||
if (sen5xSensor.hasSensor() && sen5xSensor.isActive())
|
||||
sen5xSensor.idle();
|
||||
if (sen5xSensor.hasSensor() && sen5xSensor.isActive() )
|
||||
sen5xSensor.idle();
|
||||
}
|
||||
return min(sendToPhoneIntervalMs, result);
|
||||
}
|
||||
|
@ -570,6 +570,44 @@ uint8_t SEN5XSensor::getMeasurements()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SEN5XSensor::pendingForReady(){
|
||||
uint32_t now;
|
||||
now = getTime();
|
||||
uint32_t sinceMeasureStarted = (now - measureStarted)*1000;
|
||||
LOG_INFO("Since measure started: %u", sinceMeasureStarted);
|
||||
switch (state) {
|
||||
case SEN5X_MEASUREMENT: {
|
||||
|
||||
if (sinceMeasureStarted < SEN5X_WARMUP_MS_1) {
|
||||
LOG_INFO("SEN5X: not enough time passed since starting measurement");
|
||||
return SEN5X_WARMUP_MS_1 - sinceMeasureStarted;
|
||||
}
|
||||
|
||||
// Get PN values to check if we are above or below threshold
|
||||
readPnValues();
|
||||
|
||||
// If the reading is low (the tyhreshold is in #/cm3) and second warmUp hasn't passed we return to come back later
|
||||
if ((sen5xmeasurement.pN4p0 / 100) < SEN5X_PN4P0_CONC_THD && sinceMeasureStarted < SEN5X_WARMUP_MS_2) {
|
||||
LOG_INFO("SEN5X: Concentration is low, we will ask again in the second warm up period");
|
||||
state = SEN5X_MEASUREMENT_2;
|
||||
// Report how many seconds are pending to cover the first warm up period
|
||||
return SEN5X_WARMUP_MS_2 - sinceMeasureStarted;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case SEN5X_MEASUREMENT_2: {
|
||||
if (sinceMeasureStarted < SEN5X_WARMUP_MS_2) {
|
||||
// Report how many seconds are pending to cover the first warm up period
|
||||
return SEN5X_WARMUP_MS_2 - sinceMeasureStarted;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SEN5XSensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
LOG_INFO("SEN5X: Attempting to get metrics");
|
||||
|
@ -7,15 +7,12 @@
|
||||
#include "Wire.h"
|
||||
#include "RTC.h"
|
||||
|
||||
// Warm up times for SEN5X from the datasheet
|
||||
#ifndef SEN5X_WARMUP_MS_1
|
||||
// from the SEN5X datasheet
|
||||
// #define SEN5X_WARMUP_MS_1 15000 - Change to this
|
||||
#define SEN5X_WARMUP_MS_1 30000
|
||||
#define SEN5X_WARMUP_MS_1 15000
|
||||
#endif
|
||||
|
||||
// TODO - For now, we ignore this threshold, and we only use the MS_1 (to 30000)
|
||||
#ifndef SEN5X_WARMUP_MS_2
|
||||
// from the SEN5X datasheet
|
||||
#define SEN5X_WARMUP_MS_2 30000
|
||||
#endif
|
||||
|
||||
@ -76,17 +73,10 @@ class SEN5XSensor : public TelemetrySensor
|
||||
|
||||
enum SEN5XState { SEN5X_OFF, SEN5X_IDLE, SEN5X_MEASUREMENT, SEN5X_MEASUREMENT_2, SEN5X_CLEANING, SEN5X_NOT_DETECTED };
|
||||
SEN5XState state = SEN5X_OFF;
|
||||
|
||||
// TODO - Remove
|
||||
bool continousMode = false;
|
||||
bool forcedContinousMode = false;
|
||||
|
||||
// TODO
|
||||
// Sensirion recommends taking a reading after 16 seconds, if the Perticle number reading is over 100#/cm3 the reading is OK, but if it is lower wait until 30 seconds and take it again.
|
||||
// https://sensirion.com/resource/application_note/low_power_mode/sen5x
|
||||
// TODO Implement logic for this concentrationThreshold
|
||||
// This can reduce battery consumption by a lot
|
||||
// uint16_t concentrationThreshold = 100;
|
||||
|
||||
bool sendCommand(uint16_t wichCommand);
|
||||
bool sendCommand(uint16_t wichCommand, uint8_t* buffer, uint8_t byteNumber=0);
|
||||
uint8_t readBuffer(uint8_t* buffer, uint8_t byteNumber); // Return number of bytes received
|
||||
@ -131,6 +121,12 @@ class SEN5XSensor : public TelemetrySensor
|
||||
bool idle();
|
||||
virtual int32_t runOnce() override;
|
||||
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
|
||||
|
||||
// Sensirion recommends taking a reading after 15 seconds, if the Particle number reading is over 100#/cm3 the reading is OK, but if it is lower wait until 30 seconds and take it again.
|
||||
// https://sensirion.com/resource/application_note/low_power_mode/sen5x
|
||||
#define SEN5X_PN4P0_CONC_THD 100
|
||||
// This value represents the time needed for pending data
|
||||
int32_t pendingForReady();
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user