Add PM2.5 correction formula, #182

This commit is contained in:
Phat Nguyen
2024-07-21 07:13:34 +07:00
parent e58ce1cbea
commit 4b2a5f5540
8 changed files with 90 additions and 4 deletions

View File

@ -10,7 +10,7 @@
* @param hasStatus
*/
void OledDisplay::showTempHum(bool hasStatus) {
char buf[10];
char buf[16];
if (value.Temperature > -1001) {
if (config.isTemperatureUnitInF()) {
float tempF = (value.Temperature * 9) / 5 + 32;
@ -307,10 +307,14 @@ void OledDisplay::showDashboard(const char *status) {
DISP()->drawStr(48, 27, "PM2.5");
/** Draw PM2.5 value */
int pm25 = value.pm25_1;
if (config.hasSensorSHT) {
pm25 = ag->pms5003.pm25Compensated(pm25, value.Humidity);
}
DISP()->setFont(u8g2_font_t0_22b_tf);
if (config.isPmStandardInUSAQI()) {
if (value.pm25_1 >= 0) {
sprintf(strBuf, "%d", ag->pms5003.convertPm25ToUsAqi(value.pm25_1));
sprintf(strBuf, "%d", ag->pms5003.convertPm25ToUsAqi(pm25));
} else {
sprintf(strBuf, "%s", "-");
}
@ -319,7 +323,7 @@ void OledDisplay::showDashboard(const char *status) {
DISP()->drawUTF8(48, 61, "AQI");
} else {
if (value.pm25_1 >= 0) {
sprintf(strBuf, "%d", value.pm25_1);
sprintf(strBuf, "%d", pm25);
} else {
sprintf(strBuf, "%s", "-");
}
@ -358,8 +362,12 @@ void OledDisplay::showDashboard(const char *status) {
ag->display.setText(strBuf);
/** Set PM */
int pm25 = value.pm25_1;
if(config.hasSensorSHT) {
pm25 = (int)ag->pms5003.pm25Compensated(pm25, value.Humidity);
}
ag->display.setCursor(0, 12);
snprintf(strBuf, sizeof(strBuf), "PM2.5:%d", value.pm25_1);
snprintf(strBuf, sizeof(strBuf), "PM2.5:%d", pm25);
ag->display.setText(strBuf);
/** Set temperature and humidity */

View File

@ -50,6 +50,13 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
}
if (config->hasSensorSHT && config->hasSensorPMS1) {
int pm25 = ag->pms5003.pm25Compensated(this->pm25_1, this->Humidity);
if (pm25 >= 0) {
root["pm02Compensated"] = pm25;
}
}
} else {
if (config->hasSensorPMS1 && config->hasSensorPMS2) {
root["pm01"] = ag->round2((this->pm01_1 + this->pm01_2) / 2.0);
@ -66,6 +73,11 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["rhumCompensated"] = (int)ag->pms5003t_2.humidityCompensated(
(this->hum_1 + this->hum_2) / 2.0f);
}
int pm25 = (ag->pms5003t_1.pm25Compensated(this->pm25_1, this->temp_1) +
ag->pms5003t_2.pm25Compensated(this->pm25_2, this->temp_2)) /
2;
root["pm02Compensated"] = pm25;
}
if (fwMode == FW_MODE_O_1PS || fwMode == FW_MODE_O_1PST) {
@ -82,6 +94,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["rhumCompensated"] =
(int)ag->pms5003t_1.humidityCompensated(this->hum_1);
}
root["pm02Compensated"] = ag->pms5003t_1.pm25Compensated(this->pm25_1, this->temp_1);
}
if (config->hasSensorPMS2) {
root["pm01"] = this->pm01_2;
@ -96,6 +109,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["rhumCompensated"] =
(int)ag->pms5003t_2.humidityCompensated(this->hum_2);
}
root["pm02Compensated"] = ag->pms5003t_2.pm25Compensated(this->pm25_2, this->temp_2);
}
} else {
if (fwMode == FW_MODE_O_1P) {
@ -112,6 +126,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["rhumCompensated"] =
(int)ag->pms5003t_1.humidityCompensated(this->hum_1);
}
root["pm02Compensated"] = ag->pms5003t_1.pm25Compensated(this->pm25_1, this->temp_1);
} else if (config->hasSensorPMS2) {
root["pm01"] = this->pm01_2;
root["pm02"] = this->pm25_2;
@ -125,6 +140,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["rhumCompensated"] =
(int)ag->pms5003t_1.humidityCompensated(this->hum_2);
}
root["pm02Compensated"] = ag->pms5003t_1.pm25Compensated(this->pm25_1, this->temp_1);
}
} else {
if (config->hasSensorPMS1) {
@ -140,6 +156,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["channels"]["1"]["rhumCompensated"] =
(int)ag->pms5003t_1.humidityCompensated(this->hum_1);
}
root["channels"]["1"]["pm02Compensated"] = ag->pms5003t_1.pm25Compensated(this->pm25_1, this->temp_1);
}
if (config->hasSensorPMS2) {
root["channels"]["2"]["pm01"] = this->pm01_2;
@ -154,6 +171,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["channels"]["2"]["rhumCompensated"] =
(int)ag->pms5003t_1.humidityCompensated(this->hum_2);
}
root["channels"]["2"]["pm02Compensated"] = ag->pms5003t_2.pm25Compensated(this->pm25_2, this->temp_2);
}
}
}

View File

@ -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 float
*/
int PMSBase::pm25Compensated(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
*

View File

@ -28,6 +28,7 @@ public:
uint16_t getHum(void);
int pm25ToAQI(int pm02);
int pm25Compensated(int pm25, float humidity);
private:
Stream *stream;

View File

@ -118,6 +118,17 @@ int PMS5003::getPm03ParticleCount(void) { return pms.getCount0_3(); }
*/
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::pm25Compensated(int pm25, float humidity) {
return pms.pm25Compensated(pm25, humidity);
}
/**
* @brief Check device initialized or not
*

View File

@ -24,6 +24,7 @@ public:
int getPm10Ae(void);
int getPm03ParticleCount(void);
int convertPm25ToUsAqi(int pm25);
int pm25Compensated(int pm25, float humidity);
private:
bool _isBegin = false;

View File

@ -161,6 +161,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::pm25Compensated(int pm25, float humidity) {
return pms.pm25Compensated(pm25, humidity);
}
/**
* @brief Check device initialized or not
*

View File

@ -29,6 +29,7 @@ public:
int convertPm25ToUsAqi(int pm25);
float getTemperature(void);
float getRelativeHumidity(void);
float pm25Compensated(int pm25, float humidity);
private:
bool _isBegin = false;