Okay, I hope it’s not too big;
As you can see I’m only interested in speed and course but the $GPVTG string outputs those values directly whereas the TinyGPS code uses multipliers to change the speed in Knots to other units.
/*
TinyGPS - a small GPS library for Arduino providing basic NMEA parsing
Copyright (C) 2008-9 Mikal Hart
All rights reserved
NewSoftSerial.h - Multi-instance software serial library
Copyright (c) 2006 David A. Mellis. All rights reserved.
– Interrupt-driven receive and other improvements by ladyada
– Tuning, circular buffer, derivation from class Print,
multi-instance support, porting to 8MHz processors,
various optimizations, PROGMEM delay tables, inverse logic and
direct port writing by Mikal Hart
Most of this code has been taken from Mikal Hart’s normal use of
TinyGPS example code
This modification by Matthew Gray
*/
#include <NewSoftSerial.h>
#include <TinyGPS.h>
TinyGPS gps;
NewSoftSerial lcd(2, 3);
void gpsdump(TinyGPS &gps);
bool feedgps();
void printFloat(double f, int digits = 1);
void setup()
{
Serial.begin(57600);
lcd.begin(115200);
lcd.print(0x7C,BYTE);
lcd.print(0x00,BYTE); // clear LCD
lcd.print(0x7C,BYTE);
lcd.print(0x02,BYTE);
lcd.print(0x64,BYTE); // set backlight to 50%
lcd.print(" SPEEDO TEST "); // print title
lcd.print(0x7C,BYTE);
lcd.print(0x18,BYTE);
lcd.print(0x00,BYTE);
lcd.print(0x7C,BYTE);
lcd.print(0x19,BYTE);
lcd.print(0x35,BYTE);
lcd.print("Course: "); // write heading
lcd.print(0x7C,BYTE);
lcd.print(0x18,BYTE);
lcd.print(0x00,BYTE);
lcd.print(0x7C,BYTE);
lcd.print(0x19,BYTE);
lcd.print(0x2B,BYTE);
lcd.print("Knots : "); // write heading
lcd.print(0x7C,BYTE);
lcd.print(0x18,BYTE);
lcd.print(0x00,BYTE);
lcd.print(0x7C,BYTE);
lcd.print(0x19,BYTE);
lcd.print(0x21,BYTE);
lcd.print("Mph : "); // write heading
delay(10000); // delay needed so the GPS doesn’t write initial values to LCD
}
void loop()
{
bool newdata = false;
{
if (feedgps())
newdata = true;
}
if (newdata)
{
gpsdump(gps);
}
}
void printFloat(double number, int digits)
{
// Handle negative numbers
if (number < 0.0)
{
lcd.print(’-’);
number = -number;
}
// Feed single digit space to keep decimal point aligned
if (number < 100.0)
{
lcd.print(’ ');
}
// Feed single digit space to keep decimal point aligned
if (number < 10.0)
{
lcd.print(’ ');
}
// 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)
{
feedgps();
// Display Course
lcd.print(0x7C,BYTE);
lcd.print(0x18,BYTE);
lcd.print(0x3C,BYTE);
lcd.print(0x7C,BYTE);
lcd.print(0x19,BYTE);
lcd.print(0x35,BYTE);
printFloat(gps.f_course());
// Display Speed in Knots
lcd.print(0x7C,BYTE);
lcd.print(0x18,BYTE);
lcd.print(0x3C,BYTE);
lcd.print(0x7C,BYTE);
lcd.print(0x19,BYTE);
lcd.print(0x2B,BYTE);
printFloat(gps.f_speed_knots());
// Display speed in Miles Per Hour
lcd.print(0x7C,BYTE);
lcd.print(0x18,BYTE);
lcd.print(0x3C,BYTE);
lcd.print(0x7C,BYTE);
lcd.print(0x19,BYTE);
lcd.print(0x21,BYTE);
printFloat(gps.f_speed_mph());
delay(500); // So the values don’t change too often to be read by the user
}
bool feedgps()
{
while (Serial.available())
{
if (gps.encode(Serial.read()))
return true;
}
return false;
}