0

Excuse the crudity of this question but I'm having quite the trouble trying to run the two Adafruit Ultimate GPS v3 modules at 10Hz on the Teensy 3.2 board. The modules are connected over the hardware serial ports 1 and 3. There is also an IMU (MPU6050) connected over the I2C interface.

Aim:

-To determine the difference between the course over ground and the body attitude (yaw) of a vehicle

Issues:

-By default, the GPS modules only run at 1Hz and at 9600 baud. I'm sending the required PMTK commands over their respective serial ports 1 and 3 to increase those to 10Hz and 115200 baud. I'm using hardware serial because the SoftwareSerial library was messing up the interrupts for the I2C interface and wasn't reliable at the baud rate required for 10Hz.

-When using the TinyGPS++ library, it seems that the received chars for the GPS 1 and 2 modules were the same, which led me to believe that it wasn't behaving correctly, and I was getting no fixes. Since I also need to run a Kalman filter for each GPS module at 10Hz (which might not work at that speed on the Teensy), I switched to the NeoGPS library, which I'm told, requires much less system resources and is much faster.

-The NeoGPS library also does not return any successful fix messages due to possibly being misconfigured (I'm using the default configuration files)

Below is the code I'm using with the TinyGPS++ library (sans the IMU parts)

With this, I'm only getting stars (*), and the same number of received characters for both GPS 1 and 2, hence my assumption that it is faulty;

#include <TinyGPS++.h>

    static const uint32_t GPSBaud = 115200;

    // The TinyGPS++ object
    TinyGPSPlus gps;

    void setup()
    {
      // The serial connection to the GPS device
      #define GPS_1_Serial Serial1
      #define GPS_2_Serial Serial3
      GPS_1_Serial.begin(9600);
      GPS_1_Serial.write("$PMTK220,100*2F\r\n");
     //switch the GPS baud rate to 115200
      GPS_1_Serial.write("$PMTK251,115200*27\r\n");
     //change baud rate of serial port to 38400
      GPS_1_Serial.flush();
      delay(10);
      GPS_1_Serial.end();

      GPS_2_Serial.begin(9600);
      GPS_2_Serial.write("$PMTK220,100*2F\r\n");
     //switch the GPS baud rate to 115200
      GPS_2_Serial.write("$PMTK251,115200*27\r\n");
     //change baud rate of serial port to 38400
      GPS_2_Serial.flush();
      delay(10);
      GPS_2_Serial.end();

      Serial.begin(115200);

      while (!Serial);
      Serial.println(TinyGPSPlus::libraryVersion());
      Serial.println();
      Serial.println(F("   Fix  Date       Time     Date    Course Speed Card  Chars Sentences Checksum"));
      Serial.println(F("   Age                      Age     --- from GPS ----  RX    RX        Fail"));
      Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));


    }

    void loop()
    {
      static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
    //GPS________________________________________________________GPS_1___________________________________________________________________
      GPS_1_Serial.begin(GPSBaud);
      Serial.println("Listening to GPS_1");

      printDateTime(gps.date, gps.time);

      printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
      printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
      printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);



      printInt(gps.charsProcessed(), true, 6);
      printInt(gps.sentencesWithFix(), true, 10);
      printInt(gps.failedChecksum(), true, 9);
      Serial.println();



      if (millis() > 5000 && gps.charsProcessed() < 10)
        Serial.println(F("No GPS data received: check wiring"));
      smartDelay(100);
      GPS_1_Serial.end();
    // ---------------------------------GPS_2----------------------------


      GPS_2_Serial.begin(GPSBaud);

      Serial.println("Listening to GPS_2");

      printDateTime1(gps.date, gps.time);

      printFloat1(gps.course.deg(), gps.course.isValid(), 7, 2);
      printFloat1(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
      printStr1(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);



      printInt1(gps.charsProcessed(), true, 6);
      printInt1(gps.sentencesWithFix(), true, 10);
      printInt1(gps.failedChecksum(), true, 9);
      Serial.println();



      if (millis() > 5000 && gps.charsProcessed() < 10)
        Serial.println(F("No GPS data received: check wiring"));

      smartDelay1(100);
      GPS_2_Serial.end();


    }

    // This custom version of delay() ensures that the gps object
    // is being "fed".
    static void smartDelay(unsigned long ms)
    {
      unsigned long start = millis();
      do 
      {
        while (GPS_1_Serial.available())
          gps.encode(GPS_1_Serial.read());
      } while (millis() - start < ms);
    }

    static void smartDelay1(unsigned long ms)
    {
      unsigned long start = millis();
      do
      {
        while (GPS_2_Serial.available())
          gps.encode(GPS_2_Serial.read());

      } while (millis() - start < ms);
    }

    static void printFloat(float val, bool valid, int len, int prec)
    {
      if (!valid)
      {
        while (len-- > 1)
          Serial.print('*');
        Serial.print(' ');
      }
      else
      {
        Serial.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1); // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
        for (int i=flen; i<len; ++i)
          Serial.print(' ');
      }
      smartDelay(0);
    }

    static void printFloat1(float val, bool valid, int len, int prec)
    {
      if (!valid)
      {
        while (len-- > 1)
          Serial.print('*');
        Serial.print(' ');
      }
      else
      {
        Serial.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1); // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
        for (int i=flen; i<len; ++i)
          Serial.print(' ');
      }
      smartDelay1(0);
    }

    static void printInt(unsigned long val, bool valid, int len)
    {
      char sz[32] = "*****************";
      if (valid)
        sprintf(sz, "%ld", val);
      sz[len] = 0;
      for (int i=strlen(sz); i<len; ++i)
        sz[i] = ' ';
      if (len > 0) 
        sz[len-1] = ' ';
      Serial.print(sz);
      smartDelay(0);
    }

    static void printInt1(unsigned long val, bool valid, int len)
    {
      char sz[32] = "*****************";
      if (valid)
        sprintf(sz, "%ld", val);
      sz[len] = 0;
      for (int i=strlen(sz); i<len; ++i)
        sz[i] = ' ';
      if (len > 0) 
        sz[len-1] = ' ';
      Serial.print(sz);
      smartDelay1(0);
    }

    static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
    {
      if (!d.isValid())
      {
        Serial.print(F("********** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
        Serial.print(sz);
      }

      if (!t.isValid())
      {
        Serial.print(F("******** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
        Serial.print(sz);
      }

      printInt(d.age(), d.isValid(), 5);
      smartDelay(0);
    }

    static void printDateTime1(TinyGPSDate &d, TinyGPSTime &t)
    {
      if (!d.isValid())
      {
        Serial.print(F("********** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
        Serial.print(sz);
      }

      if (!t.isValid())
      {
        Serial.print(F("******** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
        Serial.print(sz);
      }

      printInt(d.age(), d.isValid(), 5);
      smartDelay1(0);
    }


    static void printStr(const char *str, int len)
    {
      int slen = strlen(str);
      for (int i=0; i<len; ++i)
        Serial.print(i<slen ? str[i] : ' ');
      smartDelay(0);
    }

    static void printStr1(const char *str, int len)
    {
      int slen = strlen(str);
      for (int i=0; i<len; ++i)
        Serial.print(i<slen ? str[i] : ' ');
      smartDelay1(0);
    }

This is the NeoGPS library version I've attempted, which does not output any indication that it is working successfully;

#include <NMEAGPS.h>

static const uint32_t GPSBaud = 115200;

// NMEAGPS object
NMEAGPS gps;


void setup()
{

  // The serial connection to the GPS device
  #define GPS_1_Serial Serial1
  #define GPS_2_Serial Serial3
  GPS_1_Serial.begin(9600);
  GPS_1_Serial.write("$PMTK220,100*2F\r\n");
 //switch the GPS baud rate to 115200
  GPS_1_Serial.write("$PMTK251,115200*27\r\n");
 //change baud rate of serial port to 38400
  GPS_1_Serial.flush();
  delay(10);
  GPS_1_Serial.end();
  GPS_1_Serial.begin(GPSBaud);



  GPS_2_Serial.begin(9600);
  GPS_2_Serial.write("$PMTK220,100*2F\r\n");
 //switch the GPS baud rate to 115200
  GPS_2_Serial.write("$PMTK251,115200*27\r\n");
 //change baud rate of serial port to 38400
  GPS_2_Serial.flush();
  delay(10);
  GPS_2_Serial.end();
  GPS_2_Serial.begin(GPSBaud);


  Serial.begin(115200);

  while (!Serial);
  Serial.println();
  //Serial.println(F("  Time     Date    Course Speed Card  Chars Sentences Checksum"));
  //Serial.println(F(""));
  Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));


}

void loop()
{

//GPS________________________________________________________GPS_1___________________________________________________________________

  Serial.println("Listening to GPS_1");
  while (gps.available(GPS_1_Serial)) {
    gps_fix fix_1 = gps.read();
    if (fix_1.valid.location){
      Serial.println("Successful Location");
    }
    if (fix_1.valid.time) {
      Serial.println("Successful Time");

    }
  }

  Serial.println();


// ---------------------------------GPS_2----------------------------

  Serial.println("Listening to GPS_2");
  while (gps.available(GPS_2_Serial)) {
    gps_fix fix_2 = gps.read();
    if (fix_2.valid.location){
      Serial.println("Successful Location");
    }
    if (fix_2.valid.time) {
      Serial.println("Successful Time");

    }
  }

}

I'm still a beginner when it comes to programming with an Arduino, and I appreciate any assistance to get on the right track.

Thank you for reading

Yours faithfully,

Cem Huray

3
  • were you successful in running one gps module?
    – jsotola
    Commented May 19, 2018 at 0:36
  • why are you switching the baud rate?
    – jsotola
    Commented May 19, 2018 at 0:44
  • I was able to run both modules at 1Hz at 9600 baud, I need to change the baud rate to ensure that there is no data loss at 10Hz
    – C. Huray
    Commented May 19, 2018 at 6:30

2 Answers 2

0

You just need two instances of the parser, too:

NMEAGPS gps_1, gps_2;

       ...

//___________________GPS_1______________________

  //Serial.println("Listening to GPS_1");  <-- don't print too much!
  while (gps_1.available(GPS_1_Serial)) {
    gps_fix fix_1 = gps_1.read();
          ...

//___________________GPS_2______________________

  //Serial.println("Listening to GPS_2");  <-- don't print too much!
  while (gps_2.available(GPS_2_Serial)) {
    gps_fix fix_2 = gps_2.read();
          ...

Also answered on the Arduino forum here.

2
  • Wow, thank you so much, sorry I couldn't reply, I'm trying to smooth some stuff out, but brilliant library I must say
    – C. Huray
    Commented May 20, 2018 at 13:29
  • @C.Huray, Thanks! If this solves your problem, click on the green triangle next to my answer to "accept" it. Otherwise, your question lingers on, haunting us forever.... ;)
    – slash-dev
    Commented May 21, 2018 at 1:23
0

What is processing_style in NMEAGPS ? My understanding is there is a PS_POLLING style that may not work well with two GPSes and PS_INTERRUPT, that I'm not sure can handle Teensy well.

Have you tried to read directly from the Serial without any library ? When it's working, you can try to plug the library back (or parse the strings from GPS, which is quite easy).

1
  • No problem for the NeoGPS INTERRUPT processing style: just make sure the separate ISRs call the separate gps1.handle(c) or gps2.handle(c).
    – slash-dev
    Commented May 20, 2018 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.