diff --git a/README.md b/README.md index 73c6279..b810332 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ If you have any questions or problems, check out [our forum](https://forum.airgr - [Sensirion Core](https://github.com/Sensirion/arduino-core/) - [Sensirion I2C SGP41](https://github.com/Sensirion/arduino-i2c-sgp41) - [Sensirion I2C SHT](https://github.com/Sensirion/arduino-sht) -- [PMS](https://github.com/fu-hsi/pms) ## License CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License diff --git a/examples/BASIC/BASIC.ino b/examples/BASIC/BASIC.ino index 45c29d7..45c9312 100644 --- a/examples/BASIC/BASIC.ino +++ b/examples/BASIC/BASIC.ino @@ -457,6 +457,9 @@ void loop() { } updateWiFiConnect(); + + /** Read PMS on loop */ + ag.pms5003.handle(); } static void sendPing() { @@ -629,7 +632,7 @@ static void co2Update() { } void pmUpdate() { - if (ag.pms5003.readData()) { + if (ag.pms5003.isFailed() == false) { pm25 = ag.pms5003.getPm25Ae(); Serial.printf("PMS2.5: %d\r\n", pm25); pmFailCount = 0; diff --git a/examples/ONE/ONE.ino b/examples/ONE/ONE.ino index 8768adc..5622076 100644 --- a/examples/ONE/ONE.ino +++ b/examples/ONE/ONE.ino @@ -845,6 +845,11 @@ void loop() { /** factory reset handle */ factoryConfigReset(); + + /** Read PMS on loop */ + if (hasSensorPMS) { + ag.pms5003.handle(); + } } static void setTestColor(char color) { @@ -2240,7 +2245,7 @@ static void tvocUpdate(void) { * */ static void pmUpdate(void) { - if (ag.pms5003.readData()) { + if (ag.pms5003.isFailed() == false) { pm01 = ag.pms5003.getPm01Ae(); pm25 = ag.pms5003.getPm25Ae(); pm10 = ag.pms5003.getPm10Ae(); diff --git a/examples/Open_Air/Open_Air.ino b/examples/Open_Air/Open_Air.ino index d8fe616..e39da41 100644 --- a/examples/Open_Air/Open_Air.ino +++ b/examples/Open_Air/Open_Air.ino @@ -57,7 +57,7 @@ enum { phone */ APP_SM_WIFI_MANAGER_STA_CONNECTING, /** After SSID and PW entered and OK clicked, connection to WiFI network is - attempted*/ + attempted*/ APP_SM_WIFI_MANAGER_STA_CONNECTED, /** Connecting to WiFi worked */ APP_SM_WIFI_OK_SERVER_CONNECTING, /** Once connected to WiFi an attempt to reach the server is performed */ @@ -802,6 +802,13 @@ void loop() { updateWiFiConnect(); factoryConfigReset(); + + if (hasSensorPMS1) { + ag.pms5003t_1.handle(); + } + if (hasSensorPMS2) { + ag.pms5003t_2.handle(); + } } void sendPing() { @@ -1101,7 +1108,7 @@ static void tvocUpdate(void) { static void pmUpdate(void) { bool pmsResult_1 = false; bool pmsResult_2 = false; - if (hasSensorPMS1 && ag.pms5003t_1.readData()) { + if (hasSensorPMS1 && (ag.pms5003t_1.isFailed() == false)) { pm01_1 = ag.pms5003t_1.getPm01Ae(); pm25_1 = ag.pms5003t_1.getPm25Ae(); pm10_1 = ag.pms5003t_1.getPm10Ae(); @@ -1127,7 +1134,7 @@ static void pmUpdate(void) { hum_1 = -1; } - if (hasSensorPMS2 && ag.pms5003t_2.readData()) { + if (hasSensorPMS2 && (ag.pms5003t_2.isFailed() == false)) { pm01_2 = ag.pms5003t_2.getPm01Ae(); pm25_2 = ag.pms5003t_2.getPm25Ae(); pm10_2 = ag.pms5003t_2.getPm10Ae(); diff --git a/examples/TestPM/TestPM.ino b/examples/TestPM/TestPM.ino index 556d1cf..db84f24 100644 --- a/examples/TestPM/TestPM.ino +++ b/examples/TestPM/TestPM.ino @@ -10,8 +10,8 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License #ifdef ESP8266 AirGradient ag = AirGradient(DIY_BASIC); #else -// AirGradient ag = AirGradient(ONE_INDOOR); -AirGradient ag = AirGradient(OPEN_AIR_OUTDOOR); +AirGradient ag = AirGradient(ONE_INDOOR); +// AirGradient ag = AirGradient(OPEN_AIR_OUTDOOR); #endif void failedHandler(String msg); @@ -35,42 +35,56 @@ void setup() { #endif } +uint32_t lastRead = 0; void loop() { int PM2; bool readResul = false; -#ifdef ESP8266 - if (ag.pms5003.readData()) { - PM2 = ag.pms5003.getPm25Ae(); - Serial.printf("PM2.5 in ug/m3: %d\r\n", PM2); - Serial.printf("PM2.5 in US AQI: %d\r\n", - ag.pms5003.convertPm25ToUsAqi(PM2)); - } -#else - if (ag.getBoardType() == OPEN_AIR_OUTDOOR) { - if (ag.pms5003t_1.readData()) { - PM2 = ag.pms5003t_1.getPm25Ae(); - readResul = true; - } - } else { - if (ag.pms5003.readData()) { - PM2 = ag.pms5003.getPm25Ae(); - readResul = true; - } - } - if (readResul) { - Serial.printf("PM2.5 in ug/m3: %d\r\n", PM2); - if (ag.getBoardType() == OPEN_AIR_OUTDOOR) { - Serial.printf("PM2.5 in US AQI: %d\r\n", - ag.pms5003t_1.convertPm25ToUsAqi(PM2)); - } else { + uint32_t ms = (uint32_t)(millis() - lastRead); + if (ms >= 5000) { + lastRead = millis(); +#ifdef ESP8266 + if (ag.pms5003.isFailed() == false) { + PM2 = ag.pms5003.getPm25Ae(); + Serial.printf("PM2.5 in ug/m3: %d\r\n", PM2); Serial.printf("PM2.5 in US AQI: %d\r\n", ag.pms5003.convertPm25ToUsAqi(PM2)); + } else { + Serial.println("PMS sensor failed"); + } +#else + if (ag.getBoardType() == OPEN_AIR_OUTDOOR) { + if (ag.pms5003t_1.isFailed() == false) { + PM2 = ag.pms5003t_1.getPm25Ae(); + readResul = true; + } + } else { + if (ag.pms5003.isFailed() == false) { + PM2 = ag.pms5003.getPm25Ae(); + readResul = true; + } } - } -#endif - delay(5000); + if (readResul) { + Serial.printf("PM2.5 in ug/m3: %d\r\n", PM2); + if (ag.getBoardType() == OPEN_AIR_OUTDOOR) { + Serial.printf("PM2.5 in US AQI: %d\r\n", + ag.pms5003t_1.convertPm25ToUsAqi(PM2)); + } else { + Serial.printf("PM2.5 in US AQI: %d\r\n", + ag.pms5003.convertPm25ToUsAqi(PM2)); + } + } else { + Serial.println("PMS sensor failed"); + } +#endif + } + + if (ag.getBoardType() == OPEN_AIR_OUTDOOR) { + ag.pms5003t_1.handle(); + } else { + ag.pms5003.handle(); + } } void failedHandler(String msg) { diff --git a/src/PMS/PMS.cpp b/src/PMS/PMS.cpp index be7e919..84a6a35 100644 --- a/src/PMS/PMS.cpp +++ b/src/PMS/PMS.cpp @@ -1,164 +1,288 @@ #include "PMS.h" +#include "../Main/BoardDef.h" -bool PMS::begin(Stream *stream) { - _stream = stream; +bool PMSBase::begin(Stream *stream) { + this->stream = stream; - DATA data; - if (readUntil(data, 5000)) { - return true; + failed = true; + lastRead = 0; // To read buffer on handle without wait after 1.5sec + + this->stream->flush(); + + // Run and check sensor data for 4sec + while (1) { + handle(); + if (failed == false) { + return true; + } + + delay(1); + uint32_t ms = (uint32_t)(millis() - lastRead); + if (ms >= 4000) { + break; + } } - return false; } -// Standby mode. For low power consumption and prolong the life of the sensor. -void PMS::sleep() { - uint8_t command[] = {0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73}; - _stream->write(command, sizeof(command)); -} - -// Operating mode. Stable data should be got at least 30 seconds after the -// sensor wakeup from the sleep mode because of the fan's performance. -void PMS::wakeUp() { - uint8_t command[] = {0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74}; - _stream->write(command, sizeof(command)); -} - -// Active mode. Default mode after power up. In this mode sensor would send -// serial data to the host automatically. -void PMS::activeMode() { - uint8_t command[] = {0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71}; - _stream->write(command, sizeof(command)); - _mode = MODE_ACTIVE; -} - -// Passive mode. In this mode sensor would send serial data to the host only for -// request. -void PMS::passiveMode() { - uint8_t command[] = {0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70}; - _stream->write(command, sizeof(command)); - _mode = MODE_PASSIVE; -} - -// Request read in Passive Mode. -void PMS::requestRead() { - if (_mode == MODE_PASSIVE) { - uint8_t command[] = {0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71}; - _stream->write(command, sizeof(command)); +/** + * @brief Read PMS data as 1.5sec period + */ +void PMSBase::handle() { + uint32_t ms; + if (lastRead == 0) { + lastRead = millis(); + if (lastRead == 0) { + lastRead = 1; + } + } else { + ms = (uint32_t)(millis() - lastRead); + /** Ignore read data if two time call less then 1sec. In active mode the + * data sync perido is 1sec. Two times read must be large or equal 2.5sec */ + if (ms < 2500) { + return; + } } -} + bool result = false; + char buf[32]; + int bufIndex; + int step = 0; + int len = 0; + int bcount = 0; -// Non-blocking function for parse response. -bool PMS::read(DATA &data) { - _data = &data; - loop(); - - return _status == STATUS_OK; -} - -// Blocking function for parse response. Default timeout is 1s. -bool PMS::readUntil(DATA &data, uint16_t timeout) { - _data = &data; - uint32_t start = millis(); - do { - loop(); - if (_status == STATUS_OK) { + while (stream->available()) { + char value = stream->read(); + switch (step) { + case 0: { + if (value == 0x42) { + step = 1; + bufIndex = 0; + buf[bufIndex++] = value; + } break; } - - /** Relax task to avoid watchdog reset */ - delay(1); - } while (millis() - start < timeout); - - return _status == STATUS_OK; -} - -void PMS::loop() { - _status = STATUS_WAITING; - if (_stream->available()) { - uint8_t ch = _stream->read(); - - switch (_index) { - case 0: - if (ch != 0x42) { - return; - } - _calculatedChecksum = ch; - break; - - case 1: - if (ch != 0x4D) { - _index = 0; - return; - } - _calculatedChecksum += ch; - break; - - case 2: - _calculatedChecksum += ch; - _frameLen = ch << 8; - break; - - case 3: - _frameLen |= ch; - // Unsupported sensor, different frame length, transmission error e.t.c. - if (_frameLen != 2 * 9 + 2 && _frameLen != 2 * 13 + 2) { - _index = 0; - return; - } - _calculatedChecksum += ch; - break; - - default: - if (_index == _frameLen + 2) { - _checksum = ch << 8; - } else if (_index == _frameLen + 2 + 1) { - _checksum |= ch; - - if (_calculatedChecksum == _checksum) { - _status = STATUS_OK; - - // Standard Particles, CF=1. - _data->PM_SP_UG_1_0 = makeWord(_payload[0], _payload[1]); - _data->PM_SP_UG_2_5 = makeWord(_payload[2], _payload[3]); - _data->PM_SP_UG_10_0 = makeWord(_payload[4], _payload[5]); - - // Atmospheric Environment. - _data->PM_AE_UG_1_0 = makeWord(_payload[6], _payload[7]); - _data->PM_AE_UG_2_5 = makeWord(_payload[8], _payload[9]); - _data->PM_AE_UG_10_0 = makeWord(_payload[10], _payload[11]); - - // Total particles count per 100ml air - _data->PM_RAW_0_3 = makeWord(_payload[12], _payload[13]); - _data->PM_RAW_0_5 = makeWord(_payload[14], _payload[15]); - _data->PM_RAW_1_0 = makeWord(_payload[16], _payload[17]); - _data->PM_RAW_2_5 = makeWord(_payload[18], _payload[19]); - _data->PM_RAW_5_0 = makeWord(_payload[20], _payload[21]); - _data->PM_RAW_10_0 = makeWord(_payload[22], _payload[23]); - - // Formaldehyde concentration (PMSxxxxST units only) - _data->AMB_HCHO = makeWord(_payload[24], _payload[25]) / 1000; - - // Temperature & humidity (PMSxxxxST units only) - _data->AMB_TMP = makeWord(_payload[20], _payload[21]); - _data->AMB_HUM = makeWord(_payload[22], _payload[23]); - } - - _index = 0; - return; + case 1: { + if (value == 0x4d) { + step = 2; + buf[bufIndex++] = value; + // Serial.println("Got 0x4d"); } else { - _calculatedChecksum += ch; - uint8_t payloadIndex = _index - 4; - - // Payload is common to all sensors (first 2x6 bytes). - if (payloadIndex < sizeof(_payload)) { - _payload[payloadIndex] = ch; + step = 0; + } + break; + } + case 2: { + buf[bufIndex++] = value; + if (bufIndex >= 4) { + len = toValue(&buf[2]); + if (len != 28) { + // Serial.printf("Got good bad len %d\r\n", len); + len += 4; + step = 3; + } else { + // Serial.println("Got good len"); + step = 4; } } - + break; + } + case 3: { + bufIndex++; + if (bufIndex >= len) { + step = 0; + // Serial.println("Bad lengh read all buffer"); + } + break; + } + case 4: { + buf[bufIndex++] = value; + if (bufIndex >= 32) { + result |= validate(buf); + step = 0; + // Serial.println("Got data"); + } + break; + } + default: break; } - _index++; + // Reduce core panic: delay 1 ms each 32bytes data + bcount++; + if((bcount % 32) == 0){ + delay(1); + } + } + + if (result) { + lastRead = millis(); + if (lastRead == 0) { + lastRead = 1; + } + failed = false; + } else { + if (ms > 5000) { + failed = true; + } } } + +/** + * @brief Check that PMS send is failed or disconnected + * + * @return true Failed + * @return false No problem + */ +bool PMSBase::isFailed(void) { return failed; } + +/** + * @brief Read PMS 0.1 ug/m3 with CF = 1 PM estimates + * + * @return uint16_t + */ +uint16_t PMSBase::getRaw0_1(void) { return toValue(&package[4]); } + +/** + * @brief Read PMS 2.5 ug/m3 with CF = 1 PM estimates + * + * @return uint16_t + */ +uint16_t PMSBase::getRaw2_5(void) { return toValue(&package[6]); } + +/** + * @brief Read PMS 10 ug/m3 with CF = 1 PM estimates + * + * @return uint16_t + */ +uint16_t PMSBase::getRaw10(void) { return toValue(&package[8]); } + +/** + * @brief Read PMS 0.1 ug/m3 + * + * @return uint16_t + */ +uint16_t PMSBase::getPM0_1(void) { return toValue(&package[10]); } + +/** + * @brief Read PMS 2.5 ug/m3 + * + * @return uint16_t + */ +uint16_t PMSBase::getPM2_5(void) { return toValue(&package[12]); } + +/** + * @brief Read PMS 10 ug/m3 + * + * @return uint16_t + */ +uint16_t PMSBase::getPM10(void) { return toValue(&package[14]); } + +/** + * @brief Get numnber concentrations over 0.3 um/0.1L + * + * @return uint16_t + */ +uint16_t PMSBase::getCount0_3(void) { return toValue(&package[16]); } + +/** + * @brief Get numnber concentrations over 0.5 um/0.1L + * + * @return uint16_t + */ +uint16_t PMSBase::getCount0_5(void) { return toValue(&package[18]); } + +/** + * @brief Get numnber concentrations over 1.0 um/0.1L + * + * @return uint16_t + */ +uint16_t PMSBase::getCount1_0(void) { return toValue(&package[20]); } + +/** + * @brief Get numnber concentrations over 2.5 um/0.1L + * + * @return uint16_t + */ +uint16_t PMSBase::getCount2_5(void) { return toValue(&package[22]); } + +/** + * @brief Get numnber concentrations over 5.0 um/0.1L (only PMS5003) + * + * @return uint16_t + */ +uint16_t PMSBase::getCount5_0(void) { return toValue(&package[24]); } + +/** + * @brief Get numnber concentrations over 10.0 um/0.1L (only PMS5003) + * + * @return uint16_t + */ +uint16_t PMSBase::getCount10(void) { return toValue(&package[26]); } + +/** + * @brief Get temperature (only PMS5003T) + * + * @return uint16_t + */ +uint16_t PMSBase::getTemp(void) { return toValue(&package[24]); } + +/** + * @brief Get humidity (only PMS5003T) + * + * @return uint16_t + */ +uint16_t PMSBase::getHum(void) { return toValue(&package[26]); } + +/** + * @brief Convert PMS2.5 to US AQI unit + * + * @param pm02 + * @return int + */ +int PMSBase::pm25ToAQI(int pm02) { + if (pm02 <= 12.0) + return ((50 - 0) / (12.0 - .0) * (pm02 - .0) + 0); + else if (pm02 <= 35.4) + return ((100 - 50) / (35.4 - 12.0) * (pm02 - 12.0) + 50); + else if (pm02 <= 55.4) + return ((150 - 100) / (55.4 - 35.4) * (pm02 - 35.4) + 100); + else if (pm02 <= 150.4) + return ((200 - 150) / (150.4 - 55.4) * (pm02 - 55.4) + 150); + else if (pm02 <= 250.4) + return ((300 - 200) / (250.4 - 150.4) * (pm02 - 150.4) + 200); + else if (pm02 <= 350.4) + return ((400 - 300) / (350.4 - 250.4) * (pm02 - 250.4) + 300); + else if (pm02 <= 500.4) + return ((500 - 400) / (500.4 - 350.4) * (pm02 - 350.4) + 400); + else + return 500; +} + +/** + * @brief Convert two byte value to uint16_t value + * + * @param buf bytes array (must be >= 2) + * @return uint16_t + */ +uint16_t PMSBase::toValue(char *buf) { return (buf[0] << 8) | buf[1]; } + +/** + * @brief Validate package data + * + * @param buf Package buffer + * @return true Success + * @return false Failed + */ +bool PMSBase::validate(char *buf) { + uint16_t sum = 0; + for (int i = 0; i < 30; i++) { + sum += buf[i]; + } + if (sum == toValue(&buf[30])) { + for (int i = 0; i < 32; i++) { + package[i] = buf[i]; + } + return true; + } + return false; +} diff --git a/src/PMS/PMS.h b/src/PMS/PMS.h index f1f32dc..4fa086a 100644 --- a/src/PMS/PMS.h +++ b/src/PMS/PMS.h @@ -1,75 +1,43 @@ -#ifndef _PMS_BASE_H_ -#define _PMS_BASE_H_ +#ifndef _PMS5003_BASE_H_ +#define _PMS5003_BASE_H_ #include -/** - * @brief Class define how to handle plantower PMS sensor it's upport for - * PMS5003 and PMS5003T series. The data @ref AMB_TMP and @ref AMB_HUM only - * valid on PMS5003T - */ -class PMS { +class PMSBase { public: - static const uint16_t SINGLE_RESPONSE_TIME = 1000; - static const uint16_t TOTAL_RESPONSE_TIME = 1000 * 10; - static const uint16_t STEADY_RESPONSE_TIME = 1000 * 30; - - // static const uint16_t BAUD_RATE = 9600; - - struct DATA { - // Standard Particles, CF=1 - uint16_t PM_SP_UG_1_0; - uint16_t PM_SP_UG_2_5; - uint16_t PM_SP_UG_10_0; - - // Atmospheric environment - uint16_t PM_AE_UG_1_0; - uint16_t PM_AE_UG_2_5; - uint16_t PM_AE_UG_10_0; - - // Raw particles count (number of particles in 0.1l of air - uint16_t PM_RAW_0_3; - uint16_t PM_RAW_0_5; - uint16_t PM_RAW_1_0; - uint16_t PM_RAW_2_5; - uint16_t PM_RAW_5_0; - uint16_t PM_RAW_10_0; - - // Formaldehyde (HCHO) concentration in mg/m^3 - PMSxxxxST units only - uint16_t AMB_HCHO; - - // Temperature & humidity - PMSxxxxST units only - int16_t AMB_TMP; - uint16_t AMB_HUM; - }; - bool begin(Stream *stream); - void sleep(); - void wakeUp(); - void activeMode(); - void passiveMode(); + void handle(); + bool isFailed(void); + uint16_t getRaw0_1(void); + uint16_t getRaw2_5(void); + uint16_t getRaw10(void); + uint16_t getPM0_1(void); + uint16_t getPM2_5(void); + uint16_t getPM10(void); + uint16_t getCount0_3(void); + uint16_t getCount0_5(void); + uint16_t getCount1_0(void); + uint16_t getCount2_5(void); - void requestRead(); - bool read(DATA &data); - bool readUntil(DATA &data, uint16_t timeout = SINGLE_RESPONSE_TIME); + /** For PMS5003 */ + uint16_t getCount5_0(void); + uint16_t getCount10(void); + + /** For PMS5003T*/ + uint16_t getTemp(void); + uint16_t getHum(void); + + int pm25ToAQI(int pm02); private: - enum STATUS { STATUS_WAITING, STATUS_OK }; - enum MODE { MODE_ACTIVE, MODE_PASSIVE }; + Stream *stream; + char package[32]; + int packageIndex; + bool failed = false; + uint32_t lastRead; - uint8_t _payload[50]; - Stream *_stream; - DATA *_data; - STATUS _status; - MODE _mode = MODE_ACTIVE; - - uint8_t _index = 0; - uint16_t _frameLen; - uint16_t _checksum; - uint16_t _calculatedChecksum; - - void loop(); - char Char_PM2[10]; + uint16_t toValue(char *buf); + bool validate(char *buf); }; -#endif +#endif /** _PMS5003_BASE_H_ */ diff --git a/src/PMS/PMS5003.cpp b/src/PMS/PMS5003.cpp index 268f9bb..d3e2e65 100644 --- a/src/PMS/PMS5003.cpp +++ b/src/PMS/PMS5003.cpp @@ -1,6 +1,5 @@ #include "PMS5003.h" #include "Arduino.h" -#include "PMSUtils.h" #if defined(ESP8266) #include @@ -83,48 +82,33 @@ bool PMS5003::begin(void) { return true; } -/** - * @brief Read all package data then call to @ref getPMxxx to get the target - * data - * - * @return true Success - * @return false Failure - */ -bool PMS5003::readData(void) { - if (this->isBegin() == false) { - return false; - } - - return pms.readUntil(pmsData); -} - /** * @brief Read PM1.0 must call this function after @ref readData success * * @return int PM1.0 index */ -int PMS5003::getPm01Ae(void) { return pmsData.PM_AE_UG_1_0; } +int PMS5003::getPm01Ae(void) { return pms.getPM0_1(); } /** * @brief Read PM2.5 must call this function after @ref readData success * * @return int PM2.5 index */ -int PMS5003::getPm25Ae(void) { return pmsData.PM_AE_UG_2_5; } +int PMS5003::getPm25Ae(void) { return pms.getPM2_5(); } /** * @brief Read PM10.0 must call this function after @ref readData success * * @return int PM10.0 index */ -int PMS5003::getPm10Ae(void) { return pmsData.PM_AE_UG_10_0; } +int PMS5003::getPm10Ae(void) { return pms.getPM10(); } /** - * @brief Read PM3.0 must call this function after @ref readData success + * @brief Read PM0.3 must call this function after @ref readData success * - * @return int PM3.0 index + * @return int PM0.3 index */ -int PMS5003::getPm03ParticleCount(void) { return pmsData.PM_RAW_0_3; } +int PMS5003::getPm03ParticleCount(void) { return pms.getCount0_3(); } /** * @brief Convert PM2.5 to US AQI @@ -132,7 +116,7 @@ int PMS5003::getPm03ParticleCount(void) { return pmsData.PM_RAW_0_3; } * @param pm25 PM2.5 index * @return int PM2.5 US AQI */ -int PMS5003::convertPm25ToUsAqi(int pm25) { return pm25ToAQI(pm25); } +int PMS5003::convertPm25ToUsAqi(int pm25) { return pms.pm25ToAQI(pm25); } /** * @brief Check device initialized or not @@ -163,3 +147,7 @@ void PMS5003::end(void) { #endif AgLog("De-initialize"); } + +void PMS5003::handle(void) { pms.handle(); } + +bool PMS5003::isFailed(void) { return pms.isFailed(); } diff --git a/src/PMS/PMS5003.h b/src/PMS/PMS5003.h index 15b907c..cd66b07 100644 --- a/src/PMS/PMS5003.h +++ b/src/PMS/PMS5003.h @@ -17,8 +17,8 @@ public: bool begin(HardwareSerial &serial); #endif void end(void); - - bool readData(void); + void handle(void); + bool isFailed(void); int getPm01Ae(void); int getPm25Ae(void); int getPm10Ae(void); @@ -28,7 +28,7 @@ public: private: bool _isBegin = false; BoardType _boardDef; - PMS pms; + PMSBase pms; const BoardDef *bsp; #if defined(ESP8266) Stream *_debugStream; @@ -36,9 +36,6 @@ private: #else HardwareSerial *_serial; #endif - // Conplug_PMS5003T *pms; - PMS::DATA pmsData; - bool begin(void); bool isBegin(void); }; diff --git a/src/PMS/PMS5003T.cpp b/src/PMS/PMS5003T.cpp index 6d44528..b16513c 100644 --- a/src/PMS/PMS5003T.cpp +++ b/src/PMS/PMS5003T.cpp @@ -1,6 +1,5 @@ #include "PMS5003T.h" #include "Arduino.h" -#include "PMSUtils.h" #if defined(ESP8266) #include @@ -108,48 +107,33 @@ bool PMS5003T::begin(void) { return true; } -/** - * @brief Read all package data then call to @ref getPMxxx to get the target - * data - * - * @return true Success - * @return false Failure - */ -bool PMS5003T::readData(void) { - if (this->isBegin() == false) { - return false; - } - - return pms.readUntil(pmsData); -} - /** * @brief Read PM1.0 must call this function after @ref readData success * * @return int PM1.0 index */ -int PMS5003T::getPm01Ae(void) { return pmsData.PM_AE_UG_1_0; } +int PMS5003T::getPm01Ae(void) { return pms.getPM0_1(); } /** * @brief Read PM2.5 must call this function after @ref readData success * * @return int PM2.5 index */ -int PMS5003T::getPm25Ae(void) { return pmsData.PM_AE_UG_2_5; } +int PMS5003T::getPm25Ae(void) { return pms.getPM2_5(); } /** * @brief Read PM10.0 must call this function after @ref readData success * * @return int PM10.0 index */ -int PMS5003T::getPm10Ae(void) { return pmsData.PM_AE_UG_10_0; } +int PMS5003T::getPm10Ae(void) { return pms.getPM10(); } /** - * @brief Read PM3.0 must call this function after @ref readData success + * @brief Read PM 0.3 Count must call this function after @ref readData success * - * @return int PM3.0 index + * @return int PM 0.3 Count index */ -int PMS5003T::getPm03ParticleCount(void) { return pmsData.PM_RAW_0_3; } +int PMS5003T::getPm03ParticleCount(void) { return pms.getCount0_3(); } /** * @brief Convert PM2.5 to US AQI @@ -157,7 +141,7 @@ int PMS5003T::getPm03ParticleCount(void) { return pmsData.PM_RAW_0_3; } * @param pm25 PM2.5 index * @return int PM2.5 US AQI */ -int PMS5003T::convertPm25ToUsAqi(int pm25) { return pm25ToAQI(pm25); } +int PMS5003T::convertPm25ToUsAqi(int pm25) { return pms.pm25ToAQI(pm25); } /** * @brief Get temperature, Must call this method after @ref readData() success @@ -165,7 +149,7 @@ int PMS5003T::convertPm25ToUsAqi(int pm25) { return pm25ToAQI(pm25); } * @return float Degree Celcius */ float PMS5003T::getTemperature(void) { - float temp = pmsData.AMB_TMP; + float temp = pms.getTemp(); return correctionTemperature(temp / 10.0f); } @@ -175,7 +159,7 @@ float PMS5003T::getTemperature(void) { * @return float Percent (%) */ float PMS5003T::getRelativeHumidity(void) { - float hum = pmsData.AMB_HUM; + float hum = pms.getHum(); return correctionRelativeHumidity(hum / 10.0f); } @@ -213,6 +197,23 @@ void PMS5003T::end(void) { AgLog("De-initialize"); } +/** + * @brief Read PMS on loop + * + */ +void PMS5003T::handle(void) { pms.handle(); } + +/** + * @brief Get PMS status + * @return true Failed + * @return false No Problem + */ +bool PMS5003T::isFailed(void) { return pms.isFailed(); } + float PMS5003T::correctionRelativeHumidity(float inHum) { - return inHum * 1.259 + 7.34; + float hum = inHum * 1.259 + 7.34; + if (hum > 100.0f) { + hum = 100.0f; + } + return hum; } diff --git a/src/PMS/PMS5003T.h b/src/PMS/PMS5003T.h index ec4d78e..151a8b8 100644 --- a/src/PMS/PMS5003T.h +++ b/src/PMS/PMS5003T.h @@ -19,7 +19,8 @@ public: #endif void end(void); - bool readData(void); + void handle(void); + bool isFailed(void); int getPm01Ae(void); int getPm25Ae(void); int getPm10Ae(void); @@ -40,10 +41,8 @@ private: #else HardwareSerial *_serial; #endif - + PMSBase pms; bool begin(void); - PMS pms; - PMS::DATA pmsData; bool isBegin(void); float correctionTemperature(float inTemp); float correctionRelativeHumidity(float inHum); diff --git a/src/PMS/PMSUtils.cpp b/src/PMS/PMSUtils.cpp deleted file mode 100644 index f47813f..0000000 --- a/src/PMS/PMSUtils.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "PMSUtils.h" - -/** - * @brief Convert PM2.5 to US AQI - * - * @param pm02 - * @return int - */ -int pm25ToAQI(int pm02) { - if (pm02 <= 12.0) - return ((50 - 0) / (12.0 - .0) * (pm02 - .0) + 0); - else if (pm02 <= 35.4) - return ((100 - 50) / (35.4 - 12.0) * (pm02 - 12.0) + 50); - else if (pm02 <= 55.4) - return ((150 - 100) / (55.4 - 35.4) * (pm02 - 35.4) + 100); - else if (pm02 <= 150.4) - return ((200 - 150) / (150.4 - 55.4) * (pm02 - 55.4) + 150); - else if (pm02 <= 250.4) - return ((300 - 200) / (250.4 - 150.4) * (pm02 - 150.4) + 200); - else if (pm02 <= 350.4) - return ((400 - 300) / (350.4 - 250.4) * (pm02 - 250.4) + 300); - else if (pm02 <= 500.4) - return ((500 - 400) / (500.4 - 350.4) * (pm02 - 350.4) + 400); - else - return 500; -} diff --git a/src/PMS/PMSUtils.h b/src/PMS/PMSUtils.h deleted file mode 100644 index ffb5a84..0000000 --- a/src/PMS/PMSUtils.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PMS_UTILS_H_ -#define _PMS_UTILS_H_ - -int pm25ToAQI(int pm02); - -#endif /** _PMS_UTILS_H_ */