Proton BASIC Compiler - Using a GPS module as an accurate clock

  • PicŪ Basic

  • Using a GPS module as a very accurate clock

    GPS modules working in NMEA mode are easy to use as clocks and they're very accurate.
    If you want a clock that is accurate and will reflect the correct timezone and summer/winter time I suggest you use a GPS.

    There is one particular NMEA string that should be used: $GPRMC.
    This string contains the time (in UTC), the date and a 'valid' indicator.
    This is an example:
    $GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13, 309.62,120598, ,*10
    The time is the second parameter, hhmmss.mss (here 16:12:29:487).
    The date is the 8th parameter, ddmmyy (here 12-05-98).
    The valid indicator is the 3rd parameter. It can have two values 'A' and 'V'. And, surprisingly enough, 'A' indicates a valid time (where a simple soul like me would have expected that would be 'V'). The RMC data from the example show that this time is NOT valid.
    During the time no valid RMC has been received either the time should not be shown or it should be shown with an indication that it may be wrong.
    But that's only my opinion.

    After a cold start it may take some time before a 'valid' RMC is received. I once had to wait for some 40 minutes, but then the module was more or less not in view of the satellites.
    After a valid RMC has been received the module may be switched off. In my experience, switching it on every hour leads to very short intervals for a valid RMC to be received (some minutes at the most).

    The timezone used is UTC and it doesn't 'do' daylight savingtime.
    This means that the information has to be adjusted for the timezone where your appllication will be used and optionally for daylight saving time.
    What I do is set up a table in either EEPROM or Program memory that will hold the start days ('days', like '29' not 'dates' like '29-03-2012') of both summertime and wintertime for each year.
    Since the date in the GPRMC string only has the year, and no centuries, I use a table that starts at the current year and ends at '99' (2099). Should be enough for now.

    Adjusting UTC time and date to 'your' time and date.
    I live in the Netherlands where wintertime starts the last sunday of october at 3 o'clock, setting the clock back 1 hour and summertime starts the last sunday of march at 3 o'clock, moving the clock forwards by 1 hour.
    Next to that I'm living in a different timezone than UTC.
    So the device has to adjust the time and time all the time.
    In wintertime it's UTC + 1.
    In summertime it's UTC + 2.

    Implementation details
    All my clocks using a GPS module check the GPS every hour, between :05 and :10. This is mainly because a GPS module may use up to 200 mA and it's simply a waste of energy to check it constantly. The frequency could easily be lowered, but I do think it should at least be once a day.
    So all my clocks also have a 32768 Hz crystal on board that's used for keeping track of the seconds passing (Timer1 routine).
    An RTC will also do I suppose, but most of them use the same type of crystal and are, for that reason, just as (un)reliable as your average uC. The advantage is, of course, that it will do correct updating of month and year. If you don't use an RTC you'll have to do that in the code.

    Tip for decreasing the wait time.
    You don't have to wait for a valid RMC, you could use a little trick.
    Store the current month and date in EEPROM.
    Wait for the RMC year >= stored year.
    You're pretty sure that you have a date 'that will do for now' since most GPS modules initially will have a date that's way in the past.
    Store the date and month read.
    Now wait for a valid RMC and, again, store the date and month read.
    Do this every time the month/year part of the RMC date changes.

    The display
    The actual display can be anything. Some examples are shown below, but I've also built clocks using a GLCD and a 2x16 LCD with 60 leds to show the seconds.

    Clock showing time as words.

    Round clock using 168 leds. It's in turbo mode, overriding the actual clock.

    Clock using 6 bicolour dot matrix displays. Showing off with the various colour modes.

    Scrolling marquee, 4 x 8*8 dot matrix.

    If you think you can't produce this code by yourself, send me a PM and I will see what I can do for you.