diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index 5244aec..4db7022 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -169,6 +169,9 @@ void setup() { boardInit(); setMeasurementMaxPeriod(); + // Uncomment below line to print every measurements reading update + // measurements.setDebug(true); + /** Connecting wifi */ bool connectToWifi = false; if (ag->isOne()) { diff --git a/src/AgValue.cpp b/src/AgValue.cpp index 0b003c6..6e9584e 100644 --- a/src/AgValue.cpp +++ b/src/AgValue.cpp @@ -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 if (config.hasSensorPMS1 && utils::isValidPm(_pm_25[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)) { - 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)) { // Note: the pms5003t object is not matter either for channel 1 or 2, compensate points to // 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)) { - 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) { // Add pm25 compensated value /// First get both channel compensated value - int pm25_comp1 = utils::getInvalidPmValue(); - int pm25_comp2 = utils::getInvalidPmValue(); + float pm25_comp1 = utils::getInvalidPmValue(); + float pm25_comp2 = utils::getInvalidPmValue(); if (utils::isValidPm(_pm_25[0].update.avg) && utils::isValidHumidity(_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) && utils::isValidHumidity(_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 if (utils::isValidPm(pm25_comp1) && utils::isValidPm(pm25_comp2)) { pms["pm02Compensated"] = ag.round2((pm25_comp1 / pm25_comp2) / 2.0f); } else if (utils::isValidPm(pm25_comp1)) { - pms["pm02Compensated"] = pm25_comp1; + pms["pm02Compensated"] = ag.round2(pm25_comp1); } else if (utils::isValidPm(pm25_comp2)) { - pms["pm02Compensated"] = pm25_comp2; + pms["pm02Compensated"] = ag.round2(pm25_comp2); } } } diff --git a/src/PMS/PMS.cpp b/src/PMS/PMS.cpp index 4bf4da6..b788dae 100644 --- a/src/PMS/PMS.cpp +++ b/src/PMS/PMS.cpp @@ -322,11 +322,12 @@ int PMSBase::pm25ToAQI(int pm02) { * * @param pm25 Raw PM2.5 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 fpm25 = pm25; + + // Correct invalid humidity value if (humidity < 0) { humidity = 0; } @@ -334,23 +335,33 @@ int PMSBase::compensate(int pm25, float humidity) { humidity = 100.0f; } - if(pm25 < 30) { /** pm2.5 < 30 */ - value = (fpm25 * 0.524f) - (humidity * 0.0862f) + 5.75f; - } else if(pm25 < 50) { /** 30 <= pm2.5 < 50 */ - 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; - } else if(pm25 < 260) { /** 210 <= pm2.5 < 260 */ - 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)); + // If its already 0, do not proceed + if (pm25 == 0) { + return 0.0; + } + + if (pm25 < 30) { /** pm2.5 < 30 */ + value = (pm25 * 0.524f) - (humidity * 0.0862f) + 5.75f; + } 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 */ - 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) { - value = 0; + return 0.0; } - return (int)value; + return value; } /** diff --git a/src/PMS/PMS.h b/src/PMS/PMS.h index d381d69..460a87a 100644 --- a/src/PMS/PMS.h +++ b/src/PMS/PMS.h @@ -39,7 +39,7 @@ public: uint8_t getErrorCode(void); int pm25ToAQI(int pm02); - int compensate(int pm25, float humidity); + float compensate(float pm25, float humidity); private: static const uint8_t package_size = 32; diff --git a/src/PMS/PMS5003.cpp b/src/PMS/PMS5003.cpp index 7488bd6..7b021bf 100644 --- a/src/PMS/PMS5003.cpp +++ b/src/PMS/PMS5003.cpp @@ -118,16 +118,14 @@ int PMS5003::convertPm25ToUsAqi(int pm25) { return pms.pm25ToAQI(pm25); } /** * @brief Correct PM2.5 - * + * * Reference formula: https://www.airgradient.com/documentation/correction-algorithms/ - * + * * @param pm25 PM2.5 raw value * @param humidity Humidity value - * @return int + * @return compensated value in float */ -int PMS5003::compensate(int pm25, float humidity) { - return pms.compensate(pm25, humidity); -} +float PMS5003::compensate(float pm25, float humidity) { return pms.compensate(pm25, humidity); } /** * @brief Get sensor firmware version diff --git a/src/PMS/PMS5003.h b/src/PMS/PMS5003.h index 5bfadde..d8fc862 100644 --- a/src/PMS/PMS5003.h +++ b/src/PMS/PMS5003.h @@ -30,7 +30,7 @@ public: int getPm10Ae(void); int getPm03ParticleCount(void); int convertPm25ToUsAqi(int pm25); - int compensate(int pm25, float humidity); + float compensate(float pm25, float humidity); int getFirmwareVersion(void); uint8_t getErrorCode(void); bool connected(void); diff --git a/src/PMS/PMS5003T.cpp b/src/PMS/PMS5003T.cpp index 4294ec5..38ce259 100644 --- a/src/PMS/PMS5003T.cpp +++ b/src/PMS/PMS5003T.cpp @@ -165,16 +165,14 @@ float PMS5003T::getRelativeHumidity(void) { /** * @brief Correct PM2.5 - * + * * Reference formula: https://www.airgradient.com/documentation/correction-algorithms/ - * + * * @param pm25 PM2.5 raw value * @param humidity Humidity value - * @return int + * @return compensated value */ -int PMS5003T::compensate(int pm25, float humidity) { - return pms.compensate(pm25, humidity); -} +float PMS5003T::compensate(float pm25, float humidity) { return pms.compensate(pm25, humidity); } /** * @brief Get module(s) firmware version diff --git a/src/PMS/PMS5003T.h b/src/PMS/PMS5003T.h index 7c3e0df..eac4a8d 100644 --- a/src/PMS/PMS5003T.h +++ b/src/PMS/PMS5003T.h @@ -35,7 +35,7 @@ public: int convertPm25ToUsAqi(int pm25); float getTemperature(void); float getRelativeHumidity(void); - int compensate(int pm25, float humidity); + float compensate(float pm25, float humidity); int getFirmwareVersion(void); uint8_t getErrorCode(void); bool connected(void);