This is a basic sketch that will convert UTC (NMEA) to local time and display it on an LCD. I hope to add a menu option later that will let you change the time zone instead of changing it in the code. The conversion code part was developed by Jinseok Jeon (JeonLab.wordpress.com). I look forward to seeing any improvements or additions by others.
Enjoy!
Craig Clark
/*
By: Craig Clark N5XNQ Jan 2014
This sketch takes the UTC time from the NMEA "RMC" sentence and converts it
to your local time. You will need to change the TimeZone number to match the
time zone you are in.
I hope later to add a menu that will allow you to change the time zone without
having to chage it in the program. This sketch is a good basic start for those
that wish to learn about time converting.
UTC to local time conversion by: Jinseok Jeon (JeonLab.wordpress.com)
Date: September 2013
*/
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
SoftwareSerial gps = SoftwareSerial(8, 9); // GPS TX ---> Arduino Pin 8
//*******CHANGE TIME ZONE HERE************
const int TimeZone = -6;
int DSTbegin[] = { //DST 2013 - 2025 in Canada and US
310, 309, 308, 313, 312, 311, 310, 308, 314, 313, 312, 310, 309};
int DSTend[] = { //DST 2013 - 2025 in Canada and US
1103, 1102, 1101, 1106, 1105, 1104, 1103, 1101, 1107, 1106, 1105, 1103, 1102};
int DaysAMonth[] = { //number of days a month
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int gpsYear;
int gpsMonth;
int gpsDay = 0;
int gpsHour;
int gpsMin;
byte gpsSec;
void setup() {
gps.begin(4800); // GPS baud rate
// Print a message to the LCD.
lcd.begin(20, 4); // Using a 20 X 4 VFD
lcd.clear(); // Clear the VFD
lcd.setCursor(1, 0);
lcd.print("N5XNQ local Time");
lcd.setCursor(4, 1);
lcd.print("Version 2.00");
delay(2000); // Hold for 2 seconds
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("Current Time");
}
void loop()
{
PrintGps();
while (gps.available() > 0)
{
if (char(gps.read()) == 'R' && char(gps.read()) == 'M' && char(gps.read()) == 'C')
{
gpsTime(gps.parseInt());
gpsDate(gps.parseInt());
if (gpsYear%4 == 0) DaysAMonth[1] = 29; //leap year check
//Time zone adjustment
gpsHour += TimeZone;
//DST adjustment
if (gpsMonth*100+gpsDay >= DSTbegin[gpsYear-13] &&
gpsMonth*100+gpsDay < DSTend[gpsYear-13]) gpsHour += 1;
if (gpsHour < 0)
{
gpsHour += 24;
gpsDay -= 1;
if (gpsDay < 1)
{
if (gpsMonth == 1)
{
gpsMonth = 12;
gpsYear -= 1;
}
else
{
gpsMonth -= 1;
}
gpsDay = DaysAMonth[gpsMonth-1];
}
}
if (gpsHour >= 24)
{
gpsHour -= 24;
gpsDay += 1;
if (gpsDay > DaysAMonth[gpsMonth-1])
{
gpsDay = 1;
gpsMonth += 1;
if (gpsMonth > 12) gpsYear += 1;
}
}
}
}
}
void gpsTime(long UTC)
{
gpsHour = int(UTC/10000);
gpsMin = int(UTC/100%100);
gpsSec = UTC % 100;
}
void gpsDate(long dateRead)
{
gpsDay = int(dateRead/10000);
gpsMonth = int(dateRead%10000/100);
gpsYear = dateRead%100; //last 2 digits, e.g. 2013-> 13
}
void PrintGps (){
lcd.setCursor(5, 2);
if (gpsHour < 10) {
lcd.print("0");
}
lcd.print(gpsHour);
lcd.setCursor(7, 2);
lcd.print(":");
lcd.setCursor(8, 2);
if (gpsMin < 10) {
lcd.print("0");
}
lcd.print(gpsMin);
lcd.setCursor(10, 2);
lcd.print(":");
lcd.setCursor(11, 2);
if (gpsSec < 10) {
lcd.print("0");
}
lcd.print(gpsSec);
}