Hi, I am getting a new problem. If I use Arduino Mega with Honeywell HPMA-215S0, I am getting pm2.5-10ug/m3 and pm10-12ug/m3 [Sensor Refresh Rate:1Sec]. If I use ESP32 with the same sensor at the same time with the same code in the same room, I am getting pm2.5- 48ug/m3 and pm10-50ug/m3 [Refresh rate: 1 Sec].
Another point, If I use, Arduino mega with refresh rate:10Sec, sensor reading is reduced[ pm2.5- 1 ug/m3, pm10- 2 ug/m3].
But, with ESP32, with changing the refresh rate, all readings are close.
N.B: I did all the test in the same closed room with the same power supply.
Please Help!!!
I am attaching the code, for better understanding.
ARDUINO MEGA CODE
#define HPM_CMD_RESP_HEAD 0x40
#define HPM_MAX_RESP_SIZE 8 // max command response size is 8 bytes
#define HPM_READ_PARTICLE_MEASURMENT_LEN 5
unsigned int _pm2_5 = 0;
//Latest PM 10 reading
unsigned int _pm10 = 0;
enum CMD_TYPE_T {
READ_PARTICLE_MEASURMENT = 0x04,
START_PARTICLE_MEASURMENT = 0x01,
STOP_PARTICLE_MEASURMENT = 0x02,
SET_ADJUSTMENT_COEFFICIENT = 0x08,
READ_ADJUSTMENT_COEFFICIENT = 0x08,
STOP_AUTO_SEND = 0x20,
ENABLE_AUTO_SEND = 0x40,
};
enum HPM_PACKET_T {
HPM_HEAD_IDX,
HPM_LEN_IDX,
HPM_CMD_IDX,
HPM_DATA_START_IDX
};
void SendCmd(unsigned char * cmdBuf, unsigned int cmdSize) {
//Clear RX
Serial.println("Serial Printing before sendCmd");
while (Serial2.available())
Serial.print(Serial2.read());
Serial.print("PS- Sending cmd: ");
unsigned int index = 0;
for (index = 0; index < cmdSize; index++) {
Serial.print(cmdBuf[index], HEX);
Serial.print(" ");
Serial2.write(cmdBuf[index]);
}
Serial.println("");
return;
}
void Init() {
Serial.println("PS- Initializing...");
delay(100);
StartParticleMeasurement();
delay(100);
DisableAutoSend();
}
int ReadCmdResp(unsigned char * dataBuf, unsigned int dataBufSize, unsigned int cmdType) {
static unsigned char respBuf[HPM_MAX_RESP_SIZE];
static unsigned int respIdx = 0;
static unsigned int calChecksum = 0;
//Read response
respIdx = 0;
calChecksum = 0;
memset(respBuf, 0, sizeof(respBuf));
Serial2.setTimeout(100);
Serial.println("PS- Waiting for cmd resp...");
if (Serial2.readStringUntil(HPM_CMD_RESP_HEAD)) {
delay(1); //wait for the rest of the bytes to arrive
respBuf[HPM_HEAD_IDX] = HPM_CMD_RESP_HEAD;
respBuf[HPM_LEN_IDX] = Serial2.read();
Serial.print("Length:");
Serial.print(respBuf[HPM_LEN_IDX]);
if (respBuf[HPM_LEN_IDX] && ((respBuf[HPM_LEN_IDX] + 1) <= sizeof(respBuf) - 2) && (respBuf[HPM_LEN_IDX] - 1) <= dataBufSize ) {
if (Serial2.readBytes(&respBuf[HPM_CMD_IDX], respBuf[HPM_LEN_IDX] + 1) == (respBuf[HPM_LEN_IDX] + 1)) {
if (respBuf[HPM_CMD_IDX] == cmdType) { //check if CMD type matches
for (respIdx = 0; respIdx < (2 + respBuf[HPM_LEN_IDX]); respIdx++) {
calChecksum += respBuf[respIdx];
}
calChecksum = (65536 - calChecksum) % 256;
if (calChecksum == respBuf[2 + respBuf[HPM_LEN_IDX]]) {
Serial.println("PS- Received valid data!!!");
memset(dataBuf, 0, dataBufSize);
memcpy(dataBuf, &respBuf[HPM_DATA_START_IDX], respBuf[HPM_LEN_IDX] - 1);
return (respBuf[HPM_LEN_IDX] - 1);
}
}
}
}
}
while(Serial2.available()>0)
Serial.print(Serial2.read());
return true;
return false;
}
void StartParticleMeasurement() {
char cmd[] = {0x68, 0x01, 0x01, 0x96};
SendCmd(cmd, 4);
}
void StopParticleMeasurement() {
char cmd[] = {0x68, 0x01, 0x02, 0x95};
SendCmd(cmd, 4);
}
boolean ReadParticleMeasurement(unsigned int * pm2_5, unsigned int * pm10) {
char cmdBuf[] = {0x68, 0x01, 0x04, 0x93};
static unsigned char dataBuf[HPM_READ_PARTICLE_MEASURMENT_LEN - 1];
Serial.println("PS- Reading Particle Measurements..." );
SendCmd(cmdBuf, 4);
if (ReadCmdResp(dataBuf, sizeof(dataBuf), READ_PARTICLE_MEASURMENT) == (HPM_READ_PARTICLE_MEASURMENT_LEN - 1)) {
_pm2_5 = dataBuf[0] * 256 + dataBuf[1];
_pm10 = dataBuf[2] * 256 + dataBuf[3];
*pm2_5 = _pm2_5;
*pm10 = _pm10;
return true;
}
return false;
}
void DisableAutoSend() {
char cmd[] = {0x68, 0x01, 0x20, 0x77};
SendCmd(cmd, 4);
}
void setup() {
Serial.begin(9600);
Serial2.begin(9600);
Init();
StartParticleMeasurement();
}
void loop() {
unsigned int pm2_5, pm10;
if (ReadParticleMeasurement(&pm2_5, &pm10)) {
Serial.println("PM 2.5: " + String(pm2_5) + " ug/m3" );
Serial.println("PM 10: " + String(pm10) + " ug/m3" );
}
delay(1000);
}
ESPRESSIF ESP32 DEV MODULE CODE
#define HPM_CMD_RESP_HEAD 0x40
#define HPM_MAX_RESP_SIZE 8 // max command response size is 8 bytes
#define HPM_READ_PARTICLE_MEASURMENT_LEN 5
unsigned int _pm2_5 = 0;
//Latest PM 10 reading
unsigned int _pm10 = 0;
enum CMD_TYPE_T {
READ_PARTICLE_MEASURMENT = 0x04,
START_PARTICLE_MEASURMENT = 0x01,
STOP_PARTICLE_MEASURMENT = 0x02,
SET_ADJUSTMENT_COEFFICIENT = 0x08,
READ_ADJUSTMENT_COEFFICIENT = 0x08,
STOP_AUTO_SEND = 0x20,
ENABLE_AUTO_SEND = 0x40,
};
enum HPM_PACKET_T {
HPM_HEAD_IDX,
HPM_LEN_IDX,
HPM_CMD_IDX,
HPM_DATA_START_IDX
};
void SendCmd(char * cmdBuf, unsigned int cmdSize) {
//Clear RX
Serial.println("Serial Printing before sendCmd");
while (Serial2.available())
Serial.print(Serial2.read());
//Send command
Serial.print("PS- Sending cmd: ");
unsigned int index = 0;
for (index = 0; index < cmdSize; index++) {
Serial.print(cmdBuf[index], HEX);
Serial.print(" ");
Serial2.write(cmdBuf[index]);
}
Serial.println("");
return;
}
void Init() {
Serial.println("PS- Initializing...");
delay(100);
StartParticleMeasurement();
delay(100);
DisableAutoSend();
}
int ReadCmdResp(unsigned char * dataBuf, unsigned int dataBufSize, unsigned int cmdType) {
static unsigned char respBuf[HPM_MAX_RESP_SIZE];
static unsigned int respIdx = 0;
static unsigned int calChecksum = 0;
respIdx = 0;
calChecksum = 0;
memset(respBuf, 0, sizeof(respBuf));
Serial2.setTimeout(100);
Serial.println("PS- Waiting for cmd resp...");
if (Serial2.readStringUntil(HPM_CMD_RESP_HEAD)) {
delay(1); //wait for the rest of the bytes to arrive
respBuf[HPM_HEAD_IDX] = HPM_CMD_RESP_HEAD;
respBuf[HPM_LEN_IDX] = Serial2.read(); //Read the command length
if (respBuf[HPM_LEN_IDX] && ((respBuf[HPM_LEN_IDX] + 1) <= sizeof(respBuf) - 2) && (respBuf[HPM_LEN_IDX] - 1) <= dataBufSize ) {
if (Serial2.readBytes(&respBuf[HPM_CMD_IDX], respBuf[HPM_LEN_IDX] + 1) == (respBuf[HPM_LEN_IDX] + 1)) {
if (respBuf[HPM_CMD_IDX] == cmdType) {
//Calculate and validate checksum
for (respIdx = 0; respIdx < (2 + respBuf[HPM_LEN_IDX]); respIdx++) {
calChecksum += respBuf[respIdx];
}
calChecksum = (65536 - calChecksum) % 256;
if (calChecksum == respBuf[2 + respBuf[HPM_LEN_IDX]]) {
Serial.println("PS- Received valid data!!!");
memset(dataBuf, 0, dataBufSize);
memcpy(dataBuf, &respBuf[HPM_DATA_START_IDX], respBuf[HPM_LEN_IDX] - 1);
return (respBuf[HPM_LEN_IDX] - 1);
}
}
}
}
}
while(Serial2.available()>0)
Serial.print(Serial2.read());
return true;
return false;
}
void StartParticleMeasurement() {
char cmd[] = {0x68, 0x01, 0x01, 0x96};
SendCmd(cmd, 4);
}
void StopParticleMeasurement() {
char cmd[] = {0x68, 0x01, 0x02, 0x95};
SendCmd(cmd, 4);
}
boolean ReadParticleMeasurement(unsigned int * pm2_5, unsigned int * pm10) {
char cmdBuf[] = {0x68, 0x01, 0x04, 0x93};
static unsigned char dataBuf[HPM_READ_PARTICLE_MEASURMENT_LEN - 1];
Serial.println("PS- Reading Particle Measurements..." );
//Send command
SendCmd(cmdBuf, 4);
//Read response
if (ReadCmdResp(dataBuf, sizeof(dataBuf), READ_PARTICLE_MEASURMENT) == (HPM_READ_PARTICLE_MEASURMENT_LEN - 1)) {
_pm2_5 = dataBuf[0] * 256 + dataBuf[1];
_pm10 = dataBuf[2] * 256 + dataBuf[3];
*pm2_5 = _pm2_5;
*pm10 = _pm10;
return true;
}
return false;
}
void DisableAutoSend() {
char cmd[] = {0x68, 0x01, 0x20, 0x77};
SendCmd(cmd, 4);
}
void setup() {
Serial.begin(9600);
Serial2.begin(9600);
Init();
StartParticleMeasurement();
}
void loop() {
unsigned int pm2_5, pm10;
if (ReadParticleMeasurement(&pm2_5, &pm10)) {
Serial.println("PM 2.5: " + String(pm2_5) + " ug/m3" );
Serial.println("PM 10: " + String(pm10) + " ug/m3" );
}
delay(1000);
}