/*
GPS parser
Language: Processing
This program takes in NMEA 0183 serial data and parses
out the date, time, latitude, and longitude using the GPRMC sentence.
*/
// import the serial library:
import processing.serial.*;
Serial myPort; // The serial port
float latitude = 0.0; // the latitude reading in degrees
String northSouth; // north or south?
float longitude = 0.0; // the longitude reading in degrees
String eastWest; // east or west?
float heading = 0.0; // the heading in degrees
int hrs, mins, secs; // time units
int thisDay, thisMonth, thisYear;
void setup() {
size(300, 300); // window size
// create a font with the second font available to the system:
PFont myFont = createFont(PFont.list()[2], 14);
textFont(myFont);
// settings for drawing arrow:
noStroke();
smooth();
// List all the available serial ports
println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my Keyspan adaptor, so I open Serial.list()[0].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 4800);
// read bytes into a buffer until you get a carriage
// return (ASCII 13):
myPort.bufferUntil('\r');
}
void draw() {
background(0);
// make the text white:
fill(255);
// print the date and time from the GPS sentence:
text(thisMonth+ "/"+ thisDay+ "/"+ thisYear , 50, 30);
text(hrs+ ":"+ mins+ ":"+ secs + " GMT ", 50, 50);
// print the position from the GPS sentence:
text(latitude + " " + northSouth + ", " +longitude +" "+ eastWest,
50, 70);
text("heading " + heading + " degrees", 50,90);
// draw an arrow using the heading:
drawArrow(heading);
}
void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
// if you got any bytes other than the linefeed, parse it:
if (myString != null) {
parseString(myString);
}
}
void parseString (String serialString) {
// split the string at the commas:
String items[] = (split(serialString, ','));
// if the first item in the sentence is the identifier, parse the rest
if (items[0].equals("$GPRMC")) {
// get time, date, position, course, and speed
getRMC(items);
}
}
void getRMC(String[] data) {
// move the items from the string into the variables:
int time = int(data[1]);
// first two digits of the time are hours:
hrs = time/10000;
// second two digits of the time are minutes:
mins = (time%10000)/100;
// last two digits of the time are seconds:
secs = (time%100);
// if you have a valid reading, parse the rest of it:
if (data[2].equals("A")) {
latitude = float(data[3])/100.0;
northSouth = data[4];
longitude = float(data[5])/100.0;
eastWest = data[6];
heading = float(data[8]);
int date = int(data[9]);
// last two digits of the date are year. Add the century too:
thisYear = date%100 + 2000;
// second two digits of the date are month:
thisMonth = (date%10000)/100;
// first two digits of the date are day:
thisDay = date/10000;
}
}
void drawArrow(float angle) {
// move whatever you draw next so that (0,0) is centered on the screen:
translate(width/2, height/2);
// draw a circle in light blue:
fill(80,200,230);
ellipse(0,0,50,50);
// make the arrow black:
fill(0);
// rotate using the heading:
rotate(radians(angle));
// draw the arrow. center of the arrow is at (0,0):
triangle(-10, 0, 0, -20, 10, 0);
rect(-2,0, 4,20);
}