I am trying to read serial data from a sensor PMS5003, which is used for environmental particulate matter parameters measurement; and a Neo-6M GPS module for GPS location data using two hardware serial ports of Arduino Mega micro-controller Board.
I have tried to fetch the data from these two devices individually and it successfully working. But the problem is arising when I am trying to read data from both serial devices at the same time, it is only printing the PMS5003 sensor data correctly, but it is not printing the NEO6M GPS data. I have checked that if(gps.encode(Serial1.read())) always false when both devices try to work.
When I am commenting out " Serial2.begin(9600);", it is printing GPS values correctly. I want to read data from both devices at the same time. Please check the code, if I have any mistakes, and suggest to me the right direction for this. I think both serial devices are not working simultaneously.
Thank you in advance.
Following is the code:
#include <TinyGPS.h>
float glat, glon;
TinyGPS gps; // create gps object
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial1.begin(9600);
Serial2.begin(9600);
}
struct pms5003data {
uint16_t framelen;
uint16_t pm10_standard, pm25_standard, pm100_standard;
uint16_t pm10_env, pm25_env, pm100_env;
uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
uint16_t unused;
uint16_t checksum;
};
struct pms5003data data;
void loop() {
// put your main code here, to run repeatedly:
if (Serial1.available()>0) { // check for GPS data
//Serial.println("GPS Data Available!!!");
if(gps.encode(Serial1.read()))
{
Serial.println("GPS Data Found!!!");
gps.f_get_position(&glat,&glon); // get latitude and longitude
Serial.println("Position: ");
//Latitude
Serial.print("Latitude: ");
Serial.println(glat,6);
//Longitude
Serial.print("Longitude: ");
Serial.println(glon,6);
}
}
if (Serial2.available()>0) { // check for PMS data
if(readPMSdata(&Serial2))
{
Serial.println("PM Data Found!!!");
Serial.println("Particle Matter: ");
Serial.print("PM 1.0: ");
Serial.println(data.pm10_env);
Serial.print("PM 2.5: ");
Serial.println(data.pm25_env);
Serial.print("PM 10: ");
Serial.println(data.pm100_env);
}
}
Serial.println();
Serial.println();
delay(100);
}
boolean readPMSdata(Stream *s) {
if (! s->available()) {
return false;
}
// Read a byte at a time until we get to the special '0x42' start-byte
if (s->peek() != 0x42) {
s->read();
return false;
}
// Now read all 32 bytes
if (s->available() < 32) {
return false;
}
uint8_t buffer[32];
uint16_t sum = 0;
s->readBytes(buffer, 32);
// get checksum ready
for (uint8_t i=0; i<30; i++) {
sum += buffer[i];
}
// The data comes in endian'd, this solves it so it works on all platforms
uint16_t buffer_u16[15];
for (uint8_t i=0; i<15; i++) {
buffer_u16[i] = buffer[2 + i*2 + 1];
buffer_u16[i] += (buffer[2 + i*2] << 8);
}
// put it into a nice struct :)
memcpy((void *)&data, (void *)buffer_u16, 30);
if (sum != data.checksum) {
Serial.println("Checksum failure");
return false;
}
// success!
return true;
}
pms_gps_v3.ino (2.5 KB)