Start TinyGPSPlus function

I am using the TinyGPSPlus library with a Quectel L80 GPS module.
I use a mosfet to switch the L80 power and this works well.
Running an edited version of TinyGPSPlus example "DeviceExample.ino" with the example code in "loop", all is good and I receive the following on the Serial Monitor:

DeviceExample.ino
A simple demonstration of TinyGPSPlus with an attached GPS module
Testing TinyGPSPlus library v. 1.0.3
by Mikal Hart

msgGPS: -25.856111667#+28.179370000#002#
msgGPS: -25.856141667#+28.179316667#000#
msgGPS: -25.856151667#+28.179305000#000#
msgGPS: -25.856138333#+28.179308333#000#
msgGPS: -25.856133333#+28.179305000#000#
msgGPS: -25.856133333#+28.179298333#000#
msgGPS: -25.856148333#+28.179301667#000#

However, if I comment the code in "loop" out and call the function "getGPS()" from "setup", I get to the functions, but TinyGPSPlus code does not run.
Serial Monitor output:

DeviceExample.ino
A simple demonstration of TinyGPSPlus with an attached GPS module
Testing TinyGPSPlus library v. 1.0.3
by Mikal Hart

Got to getGPS

This is my full code:

#include <TinyGPSPlus.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPSPlus (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

// The TinyGPSPlus object
TinyGPSPlus gps;

String msgGPS;

void setup()
{
  Serial.begin(9600);

  pinMode(5, OUTPUT);// GPS Pin
  digitalWrite(5, LOW);// GPS ON

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPSPlus with an attached GPS module"));
  Serial.print(F("Testing TinyGPSPlus library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();

  getGPS();
}

void loop()
{
//  String myLat = "";
//  String myLon = "";
//  msgGPS = "";
//
//  // This sketch displays information every time a new sentence is correctly encoded.
//  while (Serial.available() > 0)
//    if (gps.encode(Serial.read()))
//      // GET LAT
//      myLat = String((gps.location.rawLat().negative ? "-" : "+")) + String((gps.location.rawLat().deg)) + "." + String((gps.location.rawLat().billionths));
//  // GET LON
//  myLon = String((gps.location.rawLng().negative ? "-" : "+")) + String((gps.location.rawLng().deg)) + "." + String((gps.location.rawLng().billionths));
//  // GET SPEED
//  char txSpeed[4];
//  int mySpeed;
//  mySpeed = (gps.speed.kmph());
//  sprintf(txSpeed, "%03d", mySpeed);
//
//  if ((myLat.length() > 6) && (myLon.length() > 6) && (txSpeed != "")) {
//    msgGPS += myLat;
//    msgGPS += "#";
//    msgGPS += myLon;
//    msgGPS += "#";
//    msgGPS += txSpeed;
//    msgGPS += "#";
//    Serial.print("msgGPS: ");
//    Serial.println(msgGPS);
//  }


}

void getGPS()
{

// Confirm code got here
Serial.println("Got to getGPS");
  
  String myLat = "";
  String myLon = "";
  msgGPS = "";

  // This sketch displays information every time a new sentence is correctly encoded.
  while (Serial.available() > 0)
    if (gps.encode(Serial.read()))
      // GET LAT
      myLat = String((gps.location.rawLat().negative ? "-" : "+")) + String((gps.location.rawLat().deg)) + "." + String((gps.location.rawLat().billionths));
  // GET LON
  myLon = String((gps.location.rawLng().negative ? "-" : "+")) + String((gps.location.rawLng().deg)) + "." + String((gps.location.rawLng().billionths));
  // GET SPEED
  char txSpeed[4];
  int mySpeed;
  mySpeed = (gps.speed.kmph());
  sprintf(txSpeed, "%03d", mySpeed);

  if ((myLat.length() > 6) && (myLon.length() > 6) && (txSpeed != "")) {
    msgGPS += myLat;
    msgGPS += "#";
    msgGPS += myLon;
    msgGPS += "#";
    msgGPS += txSpeed;
    msgGPS += "#";
    Serial.print("msgGPS: ");
    Serial.println(msgGPS);
  }
}

Could someone point out what I am doing incorrectly that prevents the code in "getGPS()" from reading the Serial port?

The original DeviceExample works well does it not ?

So why overcomplicate it by using Strings when a few simple Serial.prints() would appear to be enough ?

Yes, but I am trying to move the code from "loop()" and call the code in "getGPS()" from "setup()"

I need to assemble a String to send via HTTP

If you call getGPS() from the setup this code is only executed once

Assuming there is part of a NMEA sentence available on the serial port, the while loop will start extracting each letter and feed the gps instance but the read is super fast so you’ll empty the serial buffer in no time, probably faster than the gps characters come in.
As nothing is left for reading, the while loop terminates and you never got a fix so did not read the latitude / longitude

If you want to read the fix in the setup your function has to read the serial port until a fix is found, not until the serial buffer is empty

(The demo code works because the loop does its job, it loops and thus keeps reading the GPS characters as they come until the sentence is complete and a fix can be extracted)

Alternatively use a flag in the loop where you don’t proceed in the main code until a fix has been found

Many thanks
How would I implement this?

Define a global Boolean flag

byte firstFixReceived = false;

Then in the loop

void loop() {
  bool newFixReady;

  while (ss.available() > 0)
    newFixReady = gps.encode(ss.read());

  if (! firstFixReceived && newFixReady) {
    // do here what you want to do after first fix is received 
    •••
    firstFixReceived = true; // remember it
  } 
  else if (newFixReady) {
    // do here what needs to happen after the first fix when you get further fixes
    displayInfo();
    •••
  }

  if(firstFixReceived) {
    // do here what needs to happen always after the first fix has been received 
    •••
  }

  // do here what needs to always happen regardless of the presence of a new fix 
  •••

}

Ok, when I inset the above code, I get:
Serial Monitor:

DeviceExample.ino
A simple demonstration of TinyGPSPlus with an attached GPS module
Testing TinyGPSPlus library v. 1.0.3
by Mikal Hart

Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS
Got to getGPS

My Code:

#include <TinyGPSPlus.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPSPlus (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

// The TinyGPSPlus object
TinyGPSPlus gps;

String msgGPS;
byte firstFixReceived = false;

void setup()
{
  Serial.begin(9600);

  pinMode(5, OUTPUT);// GPS Pin
  digitalWrite(5, LOW);// GPS ON

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPSPlus with an attached GPS module"));
  Serial.print(F("Testing TinyGPSPlus library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();

  getGPS();
}

void loop()
{
  bool newFixReady;

  while (Serial.available() > 0)
    newFixReady = gps.encode(Serial.read());

  if (! firstFixReceived && newFixReady) {
    // do here what you want to do after first fix is received 
//    •••
    firstFixReceived = true; // remember it
  } 
  else if (newFixReady) {
    // do here what needs to happen after the first fix when you get further fixes
    getGPS();
//    •••
  }

  if(firstFixReceived) {
    // do here what needs to happen always after the first fix has been received 
//    •••
  }

  
//  String myLat = "";
//  String myLon = "";
//  msgGPS = "";
//
//  // This sketch displays information every time a new sentence is correctly encoded.
//  while (Serial.available() > 0)
//    if (gps.encode(Serial.read()))
//      // GET LAT
//      myLat = String((gps.location.rawLat().negative ? "-" : "+")) + String((gps.location.rawLat().deg)) + "." + String((gps.location.rawLat().billionths));
//  // GET LON
//  myLon = String((gps.location.rawLng().negative ? "-" : "+")) + String((gps.location.rawLng().deg)) + "." + String((gps.location.rawLng().billionths));
//  // GET SPEED
//  char txSpeed[4];
//  int mySpeed;
//  mySpeed = (gps.speed.kmph());
//  sprintf(txSpeed, "%03d", mySpeed);
//
//  if ((myLat.length() > 6) && (myLon.length() > 6) && (txSpeed != "")) {
//    msgGPS += myLat;
//    msgGPS += "#";
//    msgGPS += myLon;
//    msgGPS += "#";
//    msgGPS += txSpeed;
//    msgGPS += "#";
//    Serial.print("msgGPS: ");
//    Serial.println(msgGPS);
//  }


}

void getGPS()
{

// Confirm code got here
Serial.println("Got to getGPS");
  
  String myLat = "";
  String myLon = "";
  msgGPS = "";

  // This sketch displays information every time a new sentence is correctly encoded.
  while (Serial.available() > 0)
    if (gps.encode(Serial.read()))
      // GET LAT
      myLat = String((gps.location.rawLat().negative ? "-" : "+")) + String((gps.location.rawLat().deg)) + "." + String((gps.location.rawLat().billionths));
  // GET LON
  myLon = String((gps.location.rawLng().negative ? "-" : "+")) + String((gps.location.rawLng().deg)) + "." + String((gps.location.rawLng().billionths));
  // GET SPEED
  char txSpeed[4];
  int mySpeed;
  mySpeed = (gps.speed.kmph());
  sprintf(txSpeed, "%03d", mySpeed);

  if ((myLat.length() > 6) && (myLon.length() > 6) && (txSpeed != "")) {
    msgGPS += myLat;
    msgGPS += "#";
    msgGPS += myLon;
    msgGPS += "#";
    msgGPS += txSpeed;
    msgGPS += "#";
    Serial.print("msgGPS: ");
    Serial.println(msgGPS);
  }
}

the ••• is where the code needs to go... get rid of the getGPS() call and function

try something like that

#include <TinyGPSPlus.h>
TinyGPSPlus gps;
byte firstFixReceived = false;


void displayInfo()
{
  Serial.println(F("this is what I got"));
  if (gps.location.isValid()) {
    Serial.print(F("Location: "));
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.println(gps.location.lng(), 6);
  }

  if (gps.date.isValid()) {
    Serial.print(F("Date: "));
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.println(gps.date.year());
  }

  if (gps.time.isValid()) {
    Serial.print(F("Time: "));
    if (gps.time.hour() < 10) Serial.write('0');
    Serial.print(gps.time.hour());
    Serial.write(':');
    if (gps.time.minute() < 10) Serial.write('0');
    Serial.print(gps.time.minute());
    Serial.write(':');
    if (gps.time.second() < 10) Serial.write('0');
    Serial.print(gps.time.second());
    Serial.write(':');
    if (gps.time.centisecond() < 10) Serial.write('0');
    Serial.println(gps.time.centisecond());
  }
}



void setup() {
  Serial.begin(115200);
  Serial.println();

  pinMode(5, OUTPUT);   // GPS Pin
  digitalWrite(5, LOW); // GPS ON
}

void loop()
{
  bool newFixReady = false;

  while (Serial.available() > 0)
    newFixReady = gps.encode(Serial.read());

  if (! firstFixReceived && newFixReady) {
    // do here what you want to do after first fix is received
    Serial.println("I got my first fix");
    displayInfo();
    firstFixReceived = true; // remember it
  }
  else if (newFixReady) {
    // do here what needs to happen after the first fix when you get further fixes
    Serial.println("I got another fix");
    displayInfo();
  }
}


Great, that works.
Is there any way that I can move all the code in "loop()" to "displayInfo()"
In my final sketch, I have a lot going on in "loop()".

well you need to at least poll the GPS in the loop, so at least one function call.

#include <TinyGPSPlus.h>
TinyGPSPlus gps;
byte firstFixReceived = false;


void displayInfo()
{
  Serial.println(F("this is what I got"));
  if (gps.location.isValid()) {
    Serial.print(F("Location: "));
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.println(gps.location.lng(), 6);
  }

  if (gps.date.isValid()) {
    Serial.print(F("Date: "));
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.println(gps.date.year());
  }

  if (gps.time.isValid()) {
    Serial.print(F("Time: "));
    if (gps.time.hour() < 10) Serial.write('0');
    Serial.print(gps.time.hour());
    Serial.write(':');
    if (gps.time.minute() < 10) Serial.write('0');
    Serial.print(gps.time.minute());
    Serial.write(':');
    if (gps.time.second() < 10) Serial.write('0');
    Serial.print(gps.time.second());
    Serial.write(':');
    if (gps.time.centisecond() < 10) Serial.write('0');
    Serial.println(gps.time.centisecond());
  }
}

void pollGPS() {
  bool newFixReady = false;

  while (Serial.available() > 0)
    newFixReady = gps.encode(Serial.read());

  if (! firstFixReceived && newFixReady) {
    // do here what you want to do after first fix is received
    Serial.println("I got my first fix");
    displayInfo();
    firstFixReceived = true; // remember it
  }
  else if (newFixReady) {
    // do here what needs to happen after the first fix when you get further fixes
    Serial.println("I got another fix");
    displayInfo();
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();

  pinMode(5, OUTPUT);   // GPS Pin
  digitalWrite(5, LOW); // GPS ON
}

void loop() {
  pollGPS();
 // other stuff here not relying on the GPS
}

Thank you - I will try that later.
Appreciate your input

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