Problems integrating MKR GPS shield on I2C and separate sensor on Serial1

Hi all,

I am trying to integrate the MKR GPS shield (on I2C) and Air Quality Monitor (on Serial1) together on an MKR 1400. Using examples provided for each, both execute fine when run separately. However when I try and run the two in the same sketch, i don't have any GPS data coming through (only the Serial1 data is printed). Is anyone aware of a known issue with MKR GPS shield and a separate serial input, or am i missing something basic in my syntax? I've spent a while trying to figure it out, but cant find a solution.

With regard to wiring:

Air quality sensor

VCC--5v
GND--GND
Tx--Rx (pin 13 on MKR 1400)
Rx--Tx (pin 14 on MKR 1400)
RST--RESET

MKR GPS shield is connected directly into I2C on the MKR 1400

Below is my full code:

#include <Arduino_MKRGPS.h>

char col;
unsigned int PMSa = 0,FMHDSa = 0,TPSa = 0,HDSa = 0,PMSb = 0,FMHDSb = 0,TPSb = 0,HDSb = 0;
unsigned int PMS = 0,FMHDS = 0,TPS = 0,HDS = 0,CR1 = 0,CR2 = 0;
unsigned char buffer_RTT[40]={};   //Serial buffer; Received Data
char tempStr[15];


void setup() {
  // initialize serial communications and wait for port to open:
  Serial.begin(112500);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial1.begin(9600);

  // If you are using the MKR GPS as shield, change the next line to pass
  // the GPS_MODE_SHIELD parameter to the GPS.begin(...)
  if (!GPS.begin()) {
    Serial.println("Failed to initialize GPS!");
    while (1);
  }
}

void loop() {
  // check if there is new GPS data available
  if (GPS.available()) {
    // read GPS values
    float latitude   = GPS.latitude();
    float longitude  = GPS.longitude();
    float altitude   = GPS.altitude();
    float speed      = GPS.speed();
    int   satellites = GPS.satellites();

    // print GPS values
    Serial.print("Location: ");
    Serial.print(latitude, 7);
    Serial.print(", ");
    Serial.println(longitude, 7);

    Serial.print("Altitude: ");
    Serial.print(altitude);
    Serial.println("m");

    Serial.print("Ground speed: ");
    Serial.print(speed);
    Serial.println(" km/h");

    Serial.print("Number of satellites: ");
    Serial.println(satellites);

    Serial.println();
  }

  while(!Serial1.available());
  while(Serial1.available()>0)   //Data check: weather there is any Data in Serial1
  {
    for(int i=0;i<40;i++)
    {
      col =Serial1.read();
      buffer_RTT[i]=(char)col;
      delay(2);
    }

    Serial1.flush();

    CR1 =(buffer_RTT[38]<<8) + buffer_RTT[39];
    CR2 = 0;
    for(int i=0;i<38;i++)
      CR2 += buffer_RTT[i];
    if(CR1 == CR2)                //Check
    {
      PMSa=buffer_RTT[12];         //Read PM2.5 High 8-bit
      PMSb=buffer_RTT[13];         //Read PM2.5 Low 8-bit
      PMS=(PMSa<<8)+PMSb;          //PM2.5 value
      FMHDSa=buffer_RTT[28];         //Read Formaldehyde High 8-bit
      FMHDSb=buffer_RTT[29];         //Read Formaldehyde Low 8-bit
      FMHDS=(FMHDSa<<8)+FMHDSb;     //Formaldehyde value
      TPSa=buffer_RTT[30];          //Read Temperature High 8-bit
      TPSb=buffer_RTT[31];          //Read Temperature Low 8-bit
      TPS=(TPSa<<8)+TPSb;        //Temperature value
      HDSa=buffer_RTT[32];          //Read Humidity High 8-bit
      HDSb=buffer_RTT[33];          //Read Humidity Low 8-bit
      HDS=(HDSa<<8)+HDSb;      //Humidity value
    }
    else
    {
      PMS = 0;
      FMHDS = 0;
      TPS = 0;
      HDS = 0;
    }
  }

  Serial.println("-----------------------uart--------------------------");
  Serial.print("Temp : ");
  sprintf(tempStr,"%d%d.%d",TPS/100,(TPS/10)%10,TPS%10);
  Serial.print(tempStr);
  Serial.println("C");               //Serial pring Temperature
  Serial.print("RH   : ");
  sprintf(tempStr,"%d%d.%d",HDS/100,(HDS/10)%10,HDS%10);
  Serial.print(tempStr);            //Serial print humidity
  Serial.println(" %");               //"%"
  Serial.print("HCHO : ");
  Serial.print(FMHDS);
  Serial.println(" ug/m3");        // Serial print formaldehyde, unit: ug/m³
  Serial.print("PM2.5: ");
  Serial.print(PMS);
  Serial.println(" ug/m3");       // Serial print PM2.5, unit: ug/m³
  Serial.println();
}

can you modify the GPS library and enable debug?

remove the comment on this line ➜ https://github.com/arduino-libraries/Arduino_MKRGPS/blob/d85ac67cb0398f2bb5914a8001931003c9badd83/src/GPS.cpp#L26

GPS data will get printed every time it's polled.

I suspect this issue comes from this part

this is a blocking call until something is available on Serial1 and during that time you don't listen to the GPS stream and thus you are likely loosing data and thus the sentence does not make sense.

Thanks for the reply. I have removed the comment in the library as suggested, and when running the GPS example on its own, debug information is coming in.

However, when i execute the sketch posted here i only get one letter of the debug per loop?

On the blocking call, would you then recommend that I remove it and just read whatever is there regardless?

yes, if you look at where the debug is used, it's in the poll() function which is called by available().

This extracts only one bye of the stream and proceed.

that's why you can't block the main loop for too long and you need to callGPS.available() often to accumulate the GPS data

that's the proper way to deal with Serial input. You don't want to second guess timing, you get data as it comes and when you receive some sort of end marker or count then you proceed with the analysis of the information.

for example that's how the GPS library works too : get one byte, check if the NMEA sentence is complete and if so extract the position and other relevant info

You would need to do the same for your Air Quality Monitor and I would suggest to study Serial Input Basics to understand how to correctly deal with an asynchronous input

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.