Compensate function use float data type

This commit is contained in:
samuelbles07
2024-10-21 01:49:01 +07:00
parent 8548d3e9f4
commit 63bb5f8ddb
8 changed files with 50 additions and 39 deletions

View File

@ -169,6 +169,9 @@ void setup() {
boardInit(); boardInit();
setMeasurementMaxPeriod(); setMeasurementMaxPeriod();
// Uncomment below line to print every measurements reading update
// measurements.setDebug(true);
/** Connecting wifi */ /** Connecting wifi */
bool connectToWifi = false; bool connectToWifi = false;
if (ag->isOne()) { if (ag->isOne()) {

View File

@ -480,9 +480,9 @@ JSONVar Measurements::buildIndoor(bool localServer, AirGradient &ag, Configurati
// Add pm25 compensated value only if PM2.5 and humidity value is valid // Add pm25 compensated value only if PM2.5 and humidity value is valid
if (config.hasSensorPMS1 && utils::isValidPm(_pm_25[0].update.avg)) { if (config.hasSensorPMS1 && utils::isValidPm(_pm_25[0].update.avg)) {
if (config.hasSensorSHT && utils::isValidHumidity(_humidity[0].update.avg)) { if (config.hasSensorSHT && utils::isValidHumidity(_humidity[0].update.avg)) {
int pm25 = ag.pms5003.compensate(_pm_25[0].update.avg, _humidity[0].update.avg); float pm25 = ag.pms5003.compensate(_pm_25[0].update.avg, _humidity[0].update.avg);
if (utils::isValidPm(pm25)) { if (utils::isValidPm(pm25)) {
indoor["pm02Compensated"] = pm25; indoor["pm02Compensated"] = ag.round2(pm25);
} }
} }
} }
@ -546,9 +546,10 @@ JSONVar Measurements::buildPMS(AirGradient &ag, int ch, bool allCh, bool withTem
utils::isValidHumidity(_humidity[ch].update.avg)) { utils::isValidHumidity(_humidity[ch].update.avg)) {
// Note: the pms5003t object is not matter either for channel 1 or 2, compensate points to // Note: the pms5003t object is not matter either for channel 1 or 2, compensate points to
// the same base function // the same base function
int pm25 = ag.pms5003t_1.compensate(_pm_25[ch].update.avg, _humidity[ch].update.avg); // TODO: Need to use compensated humidity?
float pm25 = ag.pms5003t_1.compensate(_pm_25[ch].update.avg, _humidity[ch].update.avg);
if (utils::isValidPm(pm25)) { if (utils::isValidPm(pm25)) {
pms["pm02Compensated"] = pm25; pms["pm02Compensated"] = ag.round2(pm25);
} }
} }
} }
@ -703,26 +704,26 @@ JSONVar Measurements::buildPMS(AirGradient &ag, int ch, bool allCh, bool withTem
if (compensate) { if (compensate) {
// Add pm25 compensated value // Add pm25 compensated value
/// First get both channel compensated value /// First get both channel compensated value
int pm25_comp1 = utils::getInvalidPmValue(); float pm25_comp1 = utils::getInvalidPmValue();
int pm25_comp2 = utils::getInvalidPmValue(); float pm25_comp2 = utils::getInvalidPmValue();
if (utils::isValidPm(_pm_25[0].update.avg) && if (utils::isValidPm(_pm_25[0].update.avg) &&
utils::isValidHumidity(_humidity[0].update.avg)) { utils::isValidHumidity(_humidity[0].update.avg)) {
pm25_comp1 = ag.pms5003t_1.compensate(_pm_25[0].update.avg, _humidity[0].update.avg); pm25_comp1 = ag.pms5003t_1.compensate(_pm_25[0].update.avg, _humidity[0].update.avg);
pms["channels"]["1"]["pm02Compensated"] = pm25_comp1; pms["channels"]["1"]["pm02Compensated"] = ag.round2(pm25_comp1);
} }
if (utils::isValidPm(_pm_25[1].update.avg) && if (utils::isValidPm(_pm_25[1].update.avg) &&
utils::isValidHumidity(_humidity[1].update.avg)) { utils::isValidHumidity(_humidity[1].update.avg)) {
pm25_comp2 = ag.pms5003t_2.compensate(_pm_25[1].update.avg, _humidity[1].update.avg); pm25_comp2 = ag.pms5003t_2.compensate(_pm_25[1].update.avg, _humidity[1].update.avg);
pms["channels"]["2"]["pm02Compensated"] = pm25_comp2; pms["channels"]["2"]["pm02Compensated"] = ag.round2(pm25_comp2);
} }
/// Get average or one of the channel compensated value if only one channel is valid /// Get average or one of the channel compensated value if only one channel is valid
if (utils::isValidPm(pm25_comp1) && utils::isValidPm(pm25_comp2)) { if (utils::isValidPm(pm25_comp1) && utils::isValidPm(pm25_comp2)) {
pms["pm02Compensated"] = ag.round2((pm25_comp1 / pm25_comp2) / 2.0f); pms["pm02Compensated"] = ag.round2((pm25_comp1 / pm25_comp2) / 2.0f);
} else if (utils::isValidPm(pm25_comp1)) { } else if (utils::isValidPm(pm25_comp1)) {
pms["pm02Compensated"] = pm25_comp1; pms["pm02Compensated"] = ag.round2(pm25_comp1);
} else if (utils::isValidPm(pm25_comp2)) { } else if (utils::isValidPm(pm25_comp2)) {
pms["pm02Compensated"] = pm25_comp2; pms["pm02Compensated"] = ag.round2(pm25_comp2);
} }
} }
} }

View File

@ -322,11 +322,12 @@ int PMSBase::pm25ToAQI(int pm02) {
* *
* @param pm25 Raw PM2.5 value * @param pm25 Raw PM2.5 value
* @param humidity Humidity value (%) * @param humidity Humidity value (%)
* @return int * @return compensated pm25 value
*/ */
int PMSBase::compensate(int pm25, float humidity) { float PMSBase::compensate(float pm25, float humidity) {
float value; float value;
float fpm25 = pm25;
// Correct invalid humidity value
if (humidity < 0) { if (humidity < 0) {
humidity = 0; humidity = 0;
} }
@ -334,23 +335,33 @@ int PMSBase::compensate(int pm25, float humidity) {
humidity = 100.0f; humidity = 100.0f;
} }
if(pm25 < 30) { /** pm2.5 < 30 */ // If its already 0, do not proceed
value = (fpm25 * 0.524f) - (humidity * 0.0862f) + 5.75f; if (pm25 == 0) {
} else if(pm25 < 50) { /** 30 <= pm2.5 < 50 */ return 0.0;
value = (0.786f * (fpm25 * 0.05f - 1.5f) + 0.524f * (1.0f - (fpm25 * 0.05f - 1.5f))) * fpm25 - (0.0862f * humidity) + 5.75f; }
} else if(pm25 < 210) { /** 50 <= pm2.5 < 210 */
value = (0.786f * fpm25) - (0.0862f * humidity) + 5.75f; if (pm25 < 30) { /** pm2.5 < 30 */
} else if(pm25 < 260) { /** 210 <= pm2.5 < 260 */ value = (pm25 * 0.524f) - (humidity * 0.0862f) + 5.75f;
value = (0.69f * (fpm25 * 0.02f - 4.2f) + 0.786f * (1.0f - (fpm25 * 0.02f - 4.2f))) * fpm25 - (0.0862f * humidity * (1.0f - (fpm25 * 0.02f - 4.2f))) + (2.966f * (fpm25 * 0.02f - 4.2f)) + (5.75f * (1.0f - (fpm25 * 0.02f - 4.2f))) + (8.84f * (1.e-4) * fpm25 * fpm25 * (fpm25 * 0.02f - 4.2f)); } else if (pm25 < 50) { /** 30 <= pm2.5 < 50 */
value = (0.786f * (pm25 * 0.05f - 1.5f) + 0.524f * (1.0f - (pm25 * 0.05f - 1.5f))) * pm25 -
(0.0862f * humidity) + 5.75f;
} else if (pm25 < 210) { /** 50 <= pm2.5 < 210 */
value = (0.786f * pm25) - (0.0862f * humidity) + 5.75f;
} else if (pm25 < 260) { /** 210 <= pm2.5 < 260 */
value = (0.69f * (pm25 * 0.02f - 4.2f) + 0.786f * (1.0f - (pm25 * 0.02f - 4.2f))) * pm25 -
(0.0862f * humidity * (1.0f - (pm25 * 0.02f - 4.2f))) +
(2.966f * (pm25 * 0.02f - 4.2f)) + (5.75f * (1.0f - (pm25 * 0.02f - 4.2f))) +
(8.84f * (1.e-4) * pm25 * pm25 * (pm25 * 0.02f - 4.2f));
} else { /** 260 <= pm2.5 */ } else { /** 260 <= pm2.5 */
value = 2.966f + (0.69f * fpm25) + (8.84f * (1.e-4) * fpm25 * fpm25); value = 2.966f + (0.69f * pm25) + (8.84f * (1.e-4) * pm25 * pm25);
} }
// No negative value for pm2.5
if (value < 0) { if (value < 0) {
value = 0; return 0.0;
} }
return (int)value; return value;
} }
/** /**

View File

@ -39,7 +39,7 @@ public:
uint8_t getErrorCode(void); uint8_t getErrorCode(void);
int pm25ToAQI(int pm02); int pm25ToAQI(int pm02);
int compensate(int pm25, float humidity); float compensate(float pm25, float humidity);
private: private:
static const uint8_t package_size = 32; static const uint8_t package_size = 32;

View File

@ -118,16 +118,14 @@ int PMS5003::convertPm25ToUsAqi(int pm25) { return pms.pm25ToAQI(pm25); }
/** /**
* @brief Correct PM2.5 * @brief Correct PM2.5
* *
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/ * Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
* *
* @param pm25 PM2.5 raw value * @param pm25 PM2.5 raw value
* @param humidity Humidity value * @param humidity Humidity value
* @return int * @return compensated value in float
*/ */
int PMS5003::compensate(int pm25, float humidity) { float PMS5003::compensate(float pm25, float humidity) { return pms.compensate(pm25, humidity); }
return pms.compensate(pm25, humidity);
}
/** /**
* @brief Get sensor firmware version * @brief Get sensor firmware version

View File

@ -30,7 +30,7 @@ public:
int getPm10Ae(void); int getPm10Ae(void);
int getPm03ParticleCount(void); int getPm03ParticleCount(void);
int convertPm25ToUsAqi(int pm25); int convertPm25ToUsAqi(int pm25);
int compensate(int pm25, float humidity); float compensate(float pm25, float humidity);
int getFirmwareVersion(void); int getFirmwareVersion(void);
uint8_t getErrorCode(void); uint8_t getErrorCode(void);
bool connected(void); bool connected(void);

View File

@ -165,16 +165,14 @@ float PMS5003T::getRelativeHumidity(void) {
/** /**
* @brief Correct PM2.5 * @brief Correct PM2.5
* *
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/ * Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
* *
* @param pm25 PM2.5 raw value * @param pm25 PM2.5 raw value
* @param humidity Humidity value * @param humidity Humidity value
* @return int * @return compensated value
*/ */
int PMS5003T::compensate(int pm25, float humidity) { float PMS5003T::compensate(float pm25, float humidity) { return pms.compensate(pm25, humidity); }
return pms.compensate(pm25, humidity);
}
/** /**
* @brief Get module(s) firmware version * @brief Get module(s) firmware version

View File

@ -35,7 +35,7 @@ public:
int convertPm25ToUsAqi(int pm25); int convertPm25ToUsAqi(int pm25);
float getTemperature(void); float getTemperature(void);
float getRelativeHumidity(void); float getRelativeHumidity(void);
int compensate(int pm25, float humidity); float compensate(float pm25, float humidity);
int getFirmwareVersion(void); int getFirmwareVersion(void);
uint8_t getErrorCode(void); uint8_t getErrorCode(void);
bool connected(void); bool connected(void);