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?
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
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();
}
}
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
}