[time-nuts] GPS seconds conversion on an Arduino

Nick Sayer nsayer at kfu.com
Sun May 14 12:15:06 EDT 2017


I wouldn’t expect floating point to enter into it.

Add the leap second correction in, then take seconds modulo 86400 and you get the second-within-the-day. Divide seconds by 86400 and you get the day number.

With the day number, it’s quite straightforward to figure out gregorian date given a 0 date in modern times (GPS’ epoch is in 1980). You do have to figure out externally what 1024 week GPS cycle you’re in. You can start with a firmware default and increment an EEPROM value every zero-crossing. As long as the user gets a fix at least once every 1024 weeks, you’ll be good.

You figure out the year by subtracting 365 or 366 and incrementing the year number until the day is less than either 366 or 365. Picking which of those is tricky, but it’s not particularly onerous. You figure out the month by comparing the remaining days to a list of day-of-year-for-month values (again, being careful to increment by 1 during leap years if the month is > 2). Subtract that out, add 1, and the remainder is the day-of-month.

Turning a second-within-the-day value into H:M:S is child’s play. The only nuance left is 23:59:60 when a leap second occurs.

All of that is enough to go from GPS second number to the NMEA UTC output.

Going from NMEA UTC output to DST corrected local time is actually an exercise I’ve done for my GPS clock. You can take a look at my C code for that on GitHub: https://github.com/nsayer/GPS_clock

Now, going to Sidereal time, *that’s* a floating-point bitch.


> On May 13, 2017, at 6:58 PM, Mark Sims <holrum at hotmail.com> wrote:
> 
> Converting GPS seconds to Gregorian date/time on the Arduino will be an arduous task.  You take GPS seconds and add it to the GPS starring epoch to get a Julian date.  Then add in the number of leap seconds as a fraction of a day to get UTC and possibly add in a time zone offset for local time.  Don't forget to do daylight savings time conversion...  Then convert the result to Gregorian date/time for display.  
> 
> The problem is the Arduino floating point library is single precision only and does not have the resolution needed to handle the numbers involved.  Doing it with integer arithmetic (long longs) opens up a whole new can of worms.
> _______________________________________________
> time-nuts mailing list -- time-nuts at febo.com
> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
> and follow the instructions there.



More information about the time-nuts mailing list