#include //====================================================================== // 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 . // //====================================================================== 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 //-------------------------- // 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(); }