forked from SlashDevin/NeoGPS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNMEAtimezone.ino
188 lines (154 loc) · 5.64 KB
/
NMEAtimezone.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <NMEAGPS.h>
//======================================================================
// Program: NMEAtimezone.ino
//
// Description: This program shows how to offset the GPS dateTime member
// into your specific timezone. GPS devices do not know which
// timezone they are in, so they always report a UTC time. This
// is the same as GMT.
//
// Prerequisites:
// 1) NMEA.ino works with your device
// 2) GPS_FIX_TIME is enabled in GPSfix_cfg.h
// 3) NMEAGPS_PARSE_RMC is enabled in NMEAGPS_cfg.h. You could use
// any sentence that contains a time field. Be sure to change the
// "if" statement in GPSloop from RMC to your selected sentence.
//
// 'Serial' is for debug output to the Serial Monitor window.
//
// License:
// Copyright (C) 2014-2017, SlashDevin
//
// This file is part of NeoGPS
//
// NeoGPS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// NeoGPS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with NeoGPS. If not, see <http://www.gnu.org/licenses/>.
//
//======================================================================
static NMEAGPS gps; // This parses received characters
static gps_fix fix; // This contains all the parsed pieces
//--------------------------
// CHECK CONFIGURATION
#if !defined(GPS_FIX_TIME) | !defined(GPS_FIX_DATE)
#error You must define GPS_FIX_TIME and DATE in GPSfix_cfg.h!
#endif
#if !defined(NMEAGPS_PARSE_RMC) & !defined(NMEAGPS_PARSE_ZDA)
#error You must define NMEAGPS_PARSE_RMC or ZDA in NMEAGPS_cfg.h!
#endif
#include <GPSport.h>
//--------------------------
// Set these values to the offset of your timezone from GMT
static const int32_t zone_hours = -5L; // EST
static const int32_t zone_minutes = 0L; // usually zero
static const NeoGPS::clock_t zone_offset =
zone_hours * NeoGPS::SECONDS_PER_HOUR +
zone_minutes * NeoGPS::SECONDS_PER_MINUTE;
// Uncomment one DST changeover rule, or define your own:
#define USA_DST
//#define EU_DST
#if defined(USA_DST)
static const uint8_t springMonth = 3;
static const uint8_t springDate = 14; // latest 2nd Sunday
static const uint8_t springHour = 2;
static const uint8_t fallMonth = 11;
static const uint8_t fallDate = 7; // latest 1st Sunday
static const uint8_t fallHour = 2;
#define CALCULATE_DST
#elif defined(EU_DST)
static const uint8_t springMonth = 3;
static const uint8_t springDate = 31; // latest last Sunday
static const uint8_t springHour = 1;
static const uint8_t fallMonth = 10;
static const uint8_t fallDate = 31; // latest last Sunday
static const uint8_t fallHour = 1;
#define CALCULATE_DST
#endif
//--------------------------
void adjustTime( NeoGPS::time_t & dt )
{
NeoGPS::clock_t seconds = dt; // convert date/time structure to seconds
#ifdef CALCULATE_DST
// Calculate DST changeover times once per reset and year!
static NeoGPS::time_t changeover;
static NeoGPS::clock_t springForward, fallBack;
if ((springForward == 0) || (changeover.year != dt.year)) {
// Calculate the spring changeover time (seconds)
changeover.year = dt.year;
changeover.month = springMonth;
changeover.date = springDate;
changeover.hours = springHour;
changeover.minutes = 0;
changeover.seconds = 0;
changeover.set_day();
// Step back to a Sunday, if day != SUNDAY
changeover.date -= (changeover.day - NeoGPS::time_t::SUNDAY);
springForward = (NeoGPS::clock_t) changeover;
// Calculate the fall changeover time (seconds)
changeover.month = fallMonth;
changeover.date = fallDate;
changeover.hours = fallHour - 1; // to account for the "apparent" DST +1
changeover.set_day();
// Step back to a Sunday, if day != SUNDAY
changeover.date -= (changeover.day - NeoGPS::time_t::SUNDAY);
fallBack = (NeoGPS::clock_t) changeover;
}
#endif
// First, offset from UTC to the local timezone
seconds += zone_offset;
#ifdef CALCULATE_DST
// Then add an hour if DST is in effect
if ((springForward <= seconds) && (seconds < fallBack))
seconds += NeoGPS::SECONDS_PER_HOUR;
#endif
dt = seconds; // convert seconds back to a date/time structure
} // adjustTime
//--------------------------
static void GPSloop()
{
while (gps.available( gpsPort )) {
fix = gps.read();
// Display the local time
if (fix.valid.time && fix.valid.date) {
adjustTime( fix.dateTime );
DEBUG_PORT << fix.dateTime;
}
DEBUG_PORT.println();
}
} // GPSloop
//--------------------------
#ifdef NMEAGPS_INTERRUPT_PROCESSING
static void GPSisr( uint8_t c )
{
gps.handle( c );
}
#endif
//--------------------------
void setup()
{
DEBUG_PORT.begin(9600);
while (!DEBUG_PORT)
;
DEBUG_PORT.print( F("NMEAtimezone.INO: started\n") );
DEBUG_PORT.println( F("Looking for GPS device on " GPS_PORT_NAME ) );
DEBUG_PORT.println( F("Local time") );
DEBUG_PORT.flush();
gpsPort.begin( 9600 );
#ifdef NMEAGPS_INTERRUPT_PROCESSING
gpsPort.attachInterrupt( GPSisr );
#endif
}
//--------------------------
void loop()
{
GPSloop();
}