// GPS v3 module and LCD display
// display is limited to 16 x 2, so some data truncated
// Antony Watts 2014
/* GPS Pin connections
Module - Arduino
GND - GND
RX - Pin 11 TXPIN
TX - Pin 10 RXPIN
VCC - 3.3V !!!!!
*/
// libraries
#include "SoftwareSerial.h"
#include "LiquidCrystal.h"
// GPS connections
#define RXPIN 10
#define TXPIN 11
#define BAUD 9600
// $GPRMC field positions in NMEA stream
#define RMCUTC 1
#define RMCLAT 3
#define RMCNS 4
#define RMCLON 5
#define RMCEW 6
#define RMCSOG 7
#define RMCCOG 8
#define RMCDATE 9
// LCD connections
#define RS 2
#define EN 3
#define D4 4
#define D5 5
#define D6 6
#define D7 7
// set up serial comms for GPS
SoftwareSerial gps(RXPIN, TXPIN); // serial comms to GPS UART
// Create LCD object
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
void setup()
{
gps.begin(BAUD); // start GPS serial
lcd.begin(16, 2); // start LCD 16 col x 2 row
}
void loop()
{
// main data buffers, NMEA read and field extract
char gpsbuf[200];
char ebuf[20];
readgps(gpsbuf); // read each $GPxxx NMEAstrings+CRLF into gpsbuf
// use $GPRMC string
if(strncmp(gpsbuf, "$GPRMC", 6) == 0)
{
extract(RMCUTC, gpsbuf, ebuf); // get utc
lcdrpt(ebuf, 9, 0, "**:**"); // display lcd at col 9, row 0, in format hh:mm
extract(RMCLAT, gpsbuf, ebuf); // get lat
lcdrpt(ebuf, 0, 1, "** ****"); // display lcd at col 0 row 1, in format dd mmmm
extract(RMCNS, gpsbuf, ebuf); // get N|S
lcdrpt(ebuf, 7, 1, "* ");
extract(RMCLON, gpsbuf, ebuf); // get lon
lcdrpt(ebuf, 9, 1, "*** **");
extract(RMCEW, gpsbuf, ebuf); // get E|W
lcdrpt(ebuf, 15, 1, "* ");
// extract(RMCSOG, gpsbuf, ebuf); // get SOG
// extract(RMCCOG, gpsbuf, ebuf); // get COG
extract(RMCDATE, gpsbuf, ebuf); // get date
lcdrpt(ebuf, 0, 0, "**-**-**");
}
}
// read GPxxx NMEA string into buffer
void readgps(char *buffer)
{
int bp;
char c;
bp = 0;
do
{
c = gps.read();
if(c == -1) continue; // gps sends -1 when idle
buffer[bp++] = c;
} while(c != '\n'); // ends with LF
buffer[bp] = '\0'; // add '\0'
}
// extract string from field 0-10 from inbuf to outbuf
void extract(int field, char *inbuf, char *outbuf)
{
int fcount; // field counter
int ip; // inbuf pointer
int op; // outbuf ptr
fcount = 0;
ip = 0;
op = 0;
while(fcount != field) // find field
{
while(inbuf[ip++] != ',');
fcount++;
}
while(inbuf[ip] != ',') // copy inbuf to outbuf
{
outbuf[op++] = inbuf[ip++];
}
outbuf[op] = '\0'; // mark end of string
}
// display inbuf at col row in fmtbuf format
// display: * = use inbuf character, otherwise use fmtbuf character
int lcdrpt(char *inbuf, int col, int row, char *fmtbuf)
{
int inp; // pointers to inbuf and format
int fmtp;
inp = 0; // start at buffers beginning
fmtp = 0;
lcd.setCursor(col, row);// start writing here
while(fmtbuf[fmtp] != '\0') // continue until '\0' of format
{
if(fmtbuf[fmtp] == '*') // use inbuf character
{
lcd.write(inbuf[inp++]); // write inbuf char to lcd
}
else
{
lcd.write(fmtbuf[fmtp]); // format character
}
fmtp++;
}
}
Friday, 24 January 2014
GPS Version 3
Here's an update to the code:
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment