mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-07-15 08:56:34 +02:00
Fix: PMS Read Failed
This commit is contained in:
414
src/PMS/PMS.cpp
414
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;
|
||||
}
|
||||
|
@ -1,75 +1,43 @@
|
||||
#ifndef _PMS_BASE_H_
|
||||
#define _PMS_BASE_H_
|
||||
#ifndef _PMS5003_BASE_H_
|
||||
#define _PMS5003_BASE_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/**
|
||||
* @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_ */
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "PMS5003.h"
|
||||
#include "Arduino.h"
|
||||
#include "PMSUtils.h"
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include <SoftwareSerial.h>
|
||||
@ -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(); }
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "PMS5003T.h"
|
||||
#include "Arduino.h"
|
||||
#include "PMSUtils.h"
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include <SoftwareSerial.h>
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef _PMS_UTILS_H_
|
||||
#define _PMS_UTILS_H_
|
||||
|
||||
int pm25ToAQI(int pm02);
|
||||
|
||||
#endif /** _PMS_UTILS_H_ */
|
Reference in New Issue
Block a user