I have been wanting a GPS for a long time, I just find them interesting. I just bought a GPS module from SparkFun along with a 16x2 LCD screen with the sole intention of creating my own along with the help from arduino.
I have owned an arduino for many months yet I had no real projects to engage in due to my lack of money. Now I had the perfect thing to challenge myself and get a working GPS on top of that. I made an oath to myself that I would not use the internet to do the work for me and I succeeded.
Parts:
arduino
GDM1602K LCD
EM-406A GPS Module
err... a button
I have spent about 6-8 hours total over the course of our school vacation and I have to say it was a great learning experience. The whole idea is fairly simple. It reads the data sent by the module and waits for a '$' which signifies the beginning of a protocol line, then it verifies that it is the GPRMC line. The arduino takes the rest of the string and parses out the section you want by using the number of commas that have passed using an implementation String library. I have built in several functions that easily parse and format the data for the LCD using LiquidCrystal library. It uses an interrupt through the button to change pages between: Lat/Lon, Speed/Heading, and Time/Date at the prime meridian.
Any feedback on the code is appreciated!
#include <WString.h>
#include <LiquidCrystal.h>
String chkStr = String(5);
String dataStr = String(65);
String returnStr = String(12);
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
char chkByte;
char inByte;
int i = 5;
int page = 1;
void setup() {
attachInterrupt(0, button, RISING);
Serial.begin(4800);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("--Arduino GPS--");
lcd.setCursor(0, 1);
lcd.print("------v2.0------");
}
void loop() {
chkStr = '\0';
if (Serial.available() > 0) {
chkByte = Serial.read();
while (chkByte == '
) {
if (i > 0) {
if (Serial.available() > 0) {
inByte = Serial.read();
chkStr.append(inByte);
i--;
}
else {
waitForByte();
}
}
else {
i = 5;
break;
}
while (chkStr.equals("GPRMC")) {
if (Serial.available() > 0) {
if (dataStr.length() == dataStr.capacity()) {
break;
}
else {
inByte = Serial.read();
dataStr.append(inByte);
}
}
else {
waitForByte();
}
if (dataStr.length() == dataStr.capacity()) {
if(dataStr.charAt(12) == 'A') {
lcd.clear();
if (page == 1) {
printLat(0);
printLon(1);
resetData();
break;
}
else if (page == 2) {
printSpeed(0);
printHeading(1);
resetData();
break;
}
else if (page == 3) {
printTime(0);
printDate(1);
resetData();
break;
}
}
else {
lcd.clear();
aquiringFix();
resetData();
break;
}
}
}
}
}
}
void waitForByte() {
while (true) {
if (Serial.available() > 0) {
break;
}
else {
continue;
}
}
}
void aquiringFix() {
lcd.setCursor(0, 0);
lcd.print("----Aquiring----");
lcd.setCursor(0, 1);
lcd.print("------Fix!------");
}
void button() {
if (page >= 3) {
page = 1;
}
else {
page++;
}
}
void dataParse(int section) {
char nextChar;
int commas = 0;
resetReturn();
for (int x = 0; x <= dataStr.length(); x++) {
nextChar = dataStr.charAt(x);
if (nextChar == ',') {
commas++;
continue;
}
if (commas == section) {
returnStr.append(nextChar);
}
else if (commas > section) {
break;
}
}
}
void printLat(int row) {
lcd.setCursor(0, row);
lcd.print("Lt: ");
dataParse(4);
lcd.print(returnStr);
lcd.print(' ');
dataParse(3);
lcd.print('0');
lcd.print(returnStr.charAt(0));
lcd.print(returnStr.charAt(1));
lcd.print(' ');
lcd.print(returnStr.charAt(2));
lcd.print(returnStr.charAt(3));
lcd.print(returnStr.charAt(4));
lcd.print(returnStr.charAt(5));
lcd.print(returnStr.charAt(6));
lcd.print(returnStr.charAt(7));
}
void printLon(int row) {
lcd.setCursor(0, row);
lcd.print("Ln: ");
dataParse(6);
lcd.print(returnStr);
lcd.print(' ');
dataParse(5);
lcd.print(returnStr.charAt(0));
lcd.print(returnStr.charAt(1));
lcd.print(returnStr.charAt(2));
lcd.print(' ');
lcd.print(returnStr.charAt(3));
lcd.print(returnStr.charAt(4));
lcd.print(returnStr.charAt(5));
lcd.print(returnStr.charAt(6));
lcd.print(returnStr.charAt(7));
lcd.print(returnStr.charAt(8));
}
void printSpeed(int row) {
lcd.setCursor(0, row);
dataParse(7);
lcd.print("Speed: ");
lcd.print(returnStr);
lcd.print("Kts");
}
void printHeading(int row) {
lcd.setCursor(0, row);
dataParse(8);
lcd.print("Heading: ");
lcd.print(returnStr);
}
void printDate(int row) {
lcd.setCursor(0, row);
dataParse(9);
lcd.print("Date: ");
lcd.print(returnStr.charAt(0));
lcd.print(returnStr.charAt(1));
lcd.print("-");
lcd.print(returnStr.charAt(2));
lcd.print(returnStr.charAt(3));
lcd.print("-");
lcd.print(returnStr.charAt(4));
lcd.print(returnStr.charAt(5));
}
void printTime(int row) {
lcd.setCursor(0, row);
dataParse(1);
lcd.print("Time: ");
lcd.print(returnStr.charAt(0));
lcd.print(returnStr.charAt(1));
lcd.print(":");
lcd.print(returnStr.charAt(2));
lcd.print(returnStr.charAt(3));
lcd.print(":");
lcd.print(returnStr.charAt(4));
lcd.print(returnStr.charAt(5));
}
void resetData() {
dataStr = '\0';
Serial.flush();
}
void resetReturn() {
returnStr = '\0';
}




