I am trying to read serial data from two sensors: PMS5003, for particulate matter measurement parameters; and Neo-6M GPS module for GPS location data using Arduino UNO micro-controller Board.
I have tried to fetch the data from these two sensors individually and it successfully working but the problem is arising when I am trying to read data from both the sensors at the same time, it is printing every value of the parameters as "0", defined in my function: displayData(). When I am commenting out "gpsSerial.begin(9600);", it is printing PMS5003 sensor values correctly. And When I am commenting out "pmsSerial.begin(9600);", it is printing GPS values correctly. I want to read data from both sensors at the same time. Please suggest to me the right direction for this. Thank you.
Following is the code:
#include <TinyGPS++.h>
TinyGPSPlus gps;
#include <SoftwareSerial.h>
const int RX1 = 4;
const int TX1 = 5;
const int RX2 = 2;
const int TX2 = 3;
SoftwareSerial gpsSerial(RX1,TX1);
SoftwareSerial pmsSerial(RX2,TX2);
uint16_t pm_10 = 0;
uint16_t pm_25 = 0;
uint16_t pm_100 = 0;
double glat = 0;
double glng = 0;
void setup() {
// our debugging output
Serial.begin(115200);
//sensor baud rates
gpsSerial.begin(9600);
pmsSerial.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() {
gpsSerial.listen();
while(gpsSerial.available() > 0) {
//Serial.println("GPS Available!!!");
if (gps.encode(gpsSerial.read()))
{
if (gps.location.isValid())
{
glat = gps.location.lat();
glng = gps.location.lng();
}
else
{
Serial.println("Location : Not Available.");
}
}
}
pmsSerial.listen();
while (pmsSerial.available() > 0) {
Serial.println("PMS Available!!!");
if (readPMSdata(&pmsSerial))
{
pm_10 = data.pm10_env;
pm_25 = data.pm25_env;
pm_100 = data.pm100_env;
}
}
delay(500);
displayData();
}
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;
}
void displayData() {
Serial.print("Latitude: ");
Serial.println(glat);
Serial.print("Longitude: ");
Serial.println(glng);
Serial.print("PM10: ");
Serial.println(pm_10);
Serial.print("PM25: ");
Serial.println(pm_25);
Serial.print("PM100: ");
Serial.println(pm_100);
Serial.println();
Serial.println();
}