diff --git a/src/AgOledDisplay.cpp b/src/AgOledDisplay.cpp index 05f54f6..8b07ada 100644 --- a/src/AgOledDisplay.cpp +++ b/src/AgOledDisplay.cpp @@ -304,6 +304,10 @@ void OledDisplay::showDashboard(const char *status) { DISP()->drawStr(55, 27, "PM2.5"); /** Draw PM2.5 value */ + int pm25 = value.pm25_1; + if (config.hasSensorSHT) { + pm25 = ag->pms5003.compensated(pm25, value.Humidity); + } DISP()->setFont(u8g2_font_t0_22b_tf); if (config.isPmStandardInUSAQI()) { if (utils::isValidPMS(value.pm25_1)) { @@ -360,6 +364,10 @@ void OledDisplay::showDashboard(const char *status) { ag->display.setText(strBuf); /** Set PM */ + int pm25 = value.pm25_1; + if(config.hasSensorSHT) { + pm25 = (int)ag->pms5003.compensated(pm25, value.Humidity); + } ag->display.setCursor(0, 12); if (utils::isValidPMS(value.pm25_1)) { snprintf(strBuf, sizeof(strBuf), "PM2.5:%d", value.pm25_1); diff --git a/src/AgValue.cpp b/src/AgValue.cpp index b0cd3a0..015a788 100644 --- a/src/AgValue.cpp +++ b/src/AgValue.cpp @@ -50,6 +50,13 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } + if (config->hasSensorSHT && config->hasSensorPMS1) { + int pm25 = ag->pms5003.compensated(this->pm25_1, this->Humidity); + if (pm25 >= 0) { + root["pm02Compensated"] = pm25; + } + } + } else { if (config->hasSensorPMS1 && config->hasSensorPMS2) { if (utils::isValidPMS(this->pm01_1) && utils::isValidPMS(this->pm01_2)) { @@ -84,6 +91,11 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } } + + int pm25 = (ag->pms5003t_1.compensated(this->pm25_1, this->temp_1) + + ag->pms5003t_2.compensated(this->pm25_2, this->temp_2)) / + 2; + root["pm02Compensated"] = pm25; } if (fwMode == FW_MODE_O_1PS || fwMode == FW_MODE_O_1PST) { @@ -121,6 +133,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } } + root["pm02Compensated"] = ag->pms5003t_1.compensated(this->pm25_1, this->temp_1); } if (config->hasSensorPMS2) { if(utils::isValidPMS(this->pm01_2)) { @@ -157,6 +170,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } } + root["pm02Compensated"] = ag->pms5003t_2.compensated(this->pm25_2, this->temp_2); } } else { if (fwMode == FW_MODE_O_1P) { @@ -193,6 +207,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } } + root["pm02Compensated"] = ag->pms5003t_1.compensated(this->pm25_1, this->temp_1); } else if (config->hasSensorPMS2) { if(utils::isValidPMS(this->pm01_2)) { root["pm01"] = this->pm01_2; @@ -226,6 +241,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } } + root["pm02Compensated"] = ag->pms5003t_1.compensated(this->pm25_1, this->temp_1); } } else { float val; @@ -262,6 +278,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } } + root["channels"]["1"]["pm02Compensated"] = ag->pms5003t_1.compensated(this->pm25_1, this->temp_1); } if (config->hasSensorPMS2) { float val; @@ -297,6 +314,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } } + root["channels"]["2"]["pm02Compensated"] = ag->pms5003t_2.compensated(this->pm25_2, this->temp_2); } } } diff --git a/src/PMS/PMS.cpp b/src/PMS/PMS.cpp index d4101fe..50b3dac 100644 --- a/src/PMS/PMS.cpp +++ b/src/PMS/PMS.cpp @@ -270,6 +270,41 @@ int PMSBase::pm25ToAQI(int pm02) { return 500; } +/** + * @brief Correction PM2.5 + * + * @param pm25 Raw PM2.5 value + * @param humidity Humidity value (%) + * @return int + */ +int PMSBase::compensated(int pm25, float humidity) { + float value; + if (humidity < 0) { + humidity = 0; + } + if (humidity > 100) { + humidity = 100; + } + + if(pm25 < 30) { + value = (pm25 * 0.524f) - (humidity * 0.0862f) + 5.75f; + } else if(pm25 < 50) { + value = (0.786f * (pm25 / 20 - 3 / 2) + 0.524f * (1 - (pm25 / 20 - 3 / 2))) * pm25 - (0.0862f * humidity) + 5.75f; + } else if(pm25 < 210) { + value = (0.786f * pm25) - (0.0862f * humidity) + 5.75f; + } else if(pm25 < 260) { + value = (0.69f * (pm25/50 - 21/5) + 0.786f * (1 - (pm25/50 - 21/5))) * pm25 - (0.0862f * humidity * (1 - (pm25/50 - 21/5))) + (2.966f * (pm25/50 -21/5)) + (5.75f * (1 - (pm25/50 - 21/5))) + (8.84f * (1.e-4) * pm25* (pm25/50 - 21/5)); + } else { + value = 2.966f + (0.69f * pm25) + (8.84f * (1.e-4) * pm25); + } + + if(value < 0) { + value = 0; + } + + return (int)value; +} + /** * @brief Convert two byte value to uint16_t value * diff --git a/src/PMS/PMS.h b/src/PMS/PMS.h index 2e65930..e89693f 100644 --- a/src/PMS/PMS.h +++ b/src/PMS/PMS.h @@ -28,6 +28,7 @@ public: uint16_t getHum(void); int pm25ToAQI(int pm02); + int compensated(int pm25, float humidity); private: Stream *stream; diff --git a/src/PMS/PMS5003.cpp b/src/PMS/PMS5003.cpp index 0c1ea83..8a49550 100644 --- a/src/PMS/PMS5003.cpp +++ b/src/PMS/PMS5003.cpp @@ -121,6 +121,17 @@ int PMS5003::getPm03ParticleCount(void) { */ int PMS5003::convertPm25ToUsAqi(int pm25) { return pms.pm25ToAQI(pm25); } +/** + * @brief Correct PM2.5 + * + * @param pm25 PM2.5 raw value + * @param humidity Humidity value + * @return float + */ +int PMS5003::compensated(int pm25, float humidity) { + return pms.compensated(pm25, humidity); +} + /** * @brief Check device initialized or not * diff --git a/src/PMS/PMS5003.h b/src/PMS/PMS5003.h index cd66b07..aa6fcd9 100644 --- a/src/PMS/PMS5003.h +++ b/src/PMS/PMS5003.h @@ -24,6 +24,7 @@ public: int getPm10Ae(void); int getPm03ParticleCount(void); int convertPm25ToUsAqi(int pm25); + int compensated(int pm25, float humidity); private: bool _isBegin = false; diff --git a/src/PMS/PMS5003T.cpp b/src/PMS/PMS5003T.cpp index 4f427fd..97cc9c7 100644 --- a/src/PMS/PMS5003T.cpp +++ b/src/PMS/PMS5003T.cpp @@ -164,6 +164,17 @@ float PMS5003T::getRelativeHumidity(void) { return pms.getHum() / 10.0f; } +/** + * @brief Correct PM2.5 + * + * @param pm25 PM2.5 raw value + * @param humidity Humidity value + * @return float + */ +float PMS5003T::compensated(int pm25, float humidity) { + return pms.compensated(pm25, humidity); +} + /** * @brief Check device initialized or not * diff --git a/src/PMS/PMS5003T.h b/src/PMS/PMS5003T.h index 2c99b7e..3d2d567 100644 --- a/src/PMS/PMS5003T.h +++ b/src/PMS/PMS5003T.h @@ -29,6 +29,7 @@ public: int convertPm25ToUsAqi(int pm25); float getTemperature(void); float getRelativeHumidity(void); + float compensated(int pm25, float humidity); private: bool _isBegin = false;