I got the code working nicely, but sometimes my GPS needs to be reset and I cannot tell.
In the code below, I tried adding either of the two commented else statements, but that just made the output stuck in that state, even though the GPS was outputting valid data.
I'd like to print on the LCD "Wait for GPS Fix" the time of waiting, and a status of wheather the GPS is sending data at all (this is the bool variable added to the feedgps function at the bottom.
Maybe I just need to make the first else statement an if (gpsData = 0) statement?
#include <NewSoftSerial.h>
#include <TinyGPS.h>
#include <string.h>
#include <ctype.h>
/* This sample code demonstrates the normal use of a TinyGPS object.
It requires the use of NewSoftSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 2(rx) and 3(tx).
*/
TinyGPS gps;
NewSoftSerial nss(2, 3);
void gpsdump(TinyGPS &gps);
bool feedgps();
void printFloat(double f, int digits = 2);
int tzone = -7;
bool gpsData = false;
//connect LCD
#define rxLCDPin 4 // rxPin is immaterial - not used - just make this an unused Arduino pin number
#define txLCDPin 14 // pin 14 is analog pin 0, on a BBB just use a servo cable :), see Reference pinMode
//SoftwareSerial LCD = SoftwareSerial(rxLCDPin, txLCDPin);
NewSoftSerial LCD = NewSoftSerial(rxLCDPin, txLCDPin);
int ledPin=13; //LED test pin
void setup()
{
Serial.begin(115200);
nss.begin(4800);
Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
Serial.println("by Mikal Hart");
Serial.println();
Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
Serial.println();
//set up LCD
pinMode(txLCDPin, OUTPUT);
LCD.begin(9600); // 9600 baud is chip comm speed
LCD.print("?G216"); // set display geometry, 2 x 16 characters in this case
delay(500); // pause to allow LCD EEPROM to program
LCD.print("?B50"); // set backlight from 00 to ff hex (minimum to maximum brightness)
delay(1000); // pause to allow LCD EEPROM to program
LCD.print("?s05"); // set tabs to five spaces
delay(1000); // pause to allow LCD EEPROM to program
LCD.print("?c0"); // set cursor style, 0= none 2= blinking 3=underline
delay(5);
LCD.print("?f"); // clear the LCD
delay(5);
LCD.print("Hello GPS");
delay(1000);
LCD.print("?f"); // clear the LCD
LCD.print("Wait for GPS Fix");
}
void loop()
{
// gpsData = false;
digitalWrite(ledPin, HIGH);
bool newdata = false;
unsigned long start = millis();
// Every 5 seconds we print an update
//while (millis() - start < 5000) {
if (feedgps()) {
newdata = true;
digitalWrite(ledPin, LOW);
}
/********************************
else {
LCD.print("?x00?y0Wait for GPS Fix");
LCD.print("?x00?y1"); LCD.print(millis() / 1000);
LCD.print("?x11?y1"); LCD.print(gpsData);
}
********************************/
if (newdata) {
Serial.println("Acquired Data");
Serial.println("-------------");
gpsdump(gps);
Serial.println("-------------");
Serial.println();
wait = 0;
}
/**********************
else {
LCD.print("?x00?y0Wait for GPS Fix");
LCD.print("?x00?y1"); LCD.print(millis() / 1000);
LCD.print("?x11?y1"); LCD.print(gpsData);
}
// ************************/
}
void printFloat(double number, int digits) {
// Handle negative numbers
if (number < 0.0) {
Serial.print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
Serial.print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
Serial.print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
Serial.print(toPrint);
remainder -= toPrint;
}
}
void LCDprintFloat(double number, int digits)
{
// Handle negative numbers
if (number < 0.0)
{
LCD.print("-");
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
LCD.print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
LCD.print(".");
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
LCD.print(toPrint);
remainder -= toPrint;
}
}
void gpsdump(TinyGPS &gps)
{
long lat, lon;
float flat, flon;
unsigned long age, date, time, chars;
int year;
byte month, day, hour, minute, second, hundredths;
unsigned short sentences, failed;
gps.get_position(&lat, &lon, &age);
Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon);
Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
//LCD.print("?x00?y0"); LCD.print(lat);
//LCD.print("?x00?y1"); LCD.print(lon);
feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors
gps.f_get_position(&flat, &flon, &age);
Serial.print("Lat/Long(float): "); printFloat(flat, 5); LCD.print("?x00?y0"); LCDprintFloat(flat, 5); Serial.print(", "); printFloat(flon, 5); LCD.print("?x00?y1"); LCDprintFloat(flon, 5);
Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
//LCD.print("?x00?y0"); LCD.print(flat);
//LCD.print("?x00?y1");LCD.print(flon);
feedgps();
gps.get_datetime(&date, &time, &age);
Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): "); Serial.print(time);
Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
//LCD.print("?x08?y0"); LCD.print(time);
LCD.print("?x10?y1");LCD.print(date);
feedgps();
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
if (hour > 7)
hour = hour + tzone;
if (hour < 8)
hour = hour + (tzone + 24);
Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
Serial.print(" Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print("."); Serial.print(static_cast<int>(hundredths));
Serial.println(millis());
LCD.print("?x08?y0");
if ((static_cast<int>(hour)) < 10)
LCD.print("0");
LCD.print(static_cast<int>(hour));
LCD.print("?x10?y0"); LCD.print(":");
if ((static_cast<int>(minute)) < 10)
LCD.print("0");
LCD.print(static_cast<int>(minute));
LCD.print("?x13?y0"); LCD.print(":");
if ((static_cast<int>(second)) < 10)
LCD.print("0");
LCD.print(static_cast<int>(second));
Serial.println(millis());
Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
feedgps();
Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): "); Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed());
Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): "); printFloat(gps.f_course()); Serial.println();
Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): "); printFloat(gps.f_speed_mph());
Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): "); printFloat(gps.f_speed_kmph()); Serial.println();
feedgps();
gps.stats(&chars, &sentences, &failed);
Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
}
bool feedgps()
{
while (nss.available()) {
if (gps.encode(nss.read()))
// gpsData = true;
return true;
}
return false;
// gpsData = false;
}