GPS+Atomic clock build

Building a GPS-disciplined clock using Rubidium oscillator with DS3231 backup using PPS signals from all sources

Similar projects worth following
The goal is to have a clock that is essentially always correct (goal of about 1 ms accuracy) regardless of GPS signal and intermittent loss of power.

Parts used will include 8 8x8 LED matrices for display; Arduino Nano clone, Symmetricon SA.22c Rubidium oscillator, uBlox GPS with PPS and external antenna, DS3231 TXCO RTC, 2U rack-mount case, 15V PSU. The main clock logic entails using the GPS serial data to obtain current date/time; using GPS PPS signal to keep sub-millisecond accuracy. Rubidium signal will be measured relative to the GPS PPS signal and used as a backup (or if the GPS is intentionallly taken offline). If the GPS PPS signal is lost (or switched off), the Rubidium PPS signal will be used as the driver to sync the internal clock. If that is also lost, the RTC PPS will be used as a fallback (as well as to sync and store the "correct" time for power failures.

Internal time is kept in UTC using a modified time.h library.

Current software supports all of the features in the description. Additions include adding the ability to set the RTC based on the Rubidium PPS signal during long GPS outages. Also want to add a basic menu system to support options like animation style of digits, brightness setting, GPS in/out, time zone, rotating display mode (e.g. date, time, other info).

Front panel will have main power switch and Rubidium power switch--this will support fanless operation without the Rubidum source being powered up. This will give it very low-power consumption in non-atomic mode (and lets be honest, will sacrifice essentially nothing in accuracy as long as GPS is switched in).

Using the Matrix library to drive the 8x8 LED panels, but had to modify to rotate pixels 90 degrees due to the way they are mounted on the PCB. Will use right-most column of display to indicate statuses and signals: GPS PPS, Rubidium PPS, RTC PPS, internal clock "tick" and Rubidium lock.

The display matrices are now soldered together and ready to mount behind the glass:

Front panel is complete:

Just need to mount stuff inside and tidy up the wiring.

Using a Kill-a-Watt, this clock consumes about 9 watts in atomic mode and under 3 watts with the Rubidium source switched off.

  • 1 × Arduino nano
  • 1 × DS3231 RTC module
  • 1 × GPS breakout board with ublox NEO-6M
  • 1 × External GPS antenna and SMA adapter
  • 1 × Symmetricom SA.22c Rubidium oscillator

View all 9 components

  • More accuracy, and measuring it

    Paul Leskinen09/02/2015 at 04:14 0 comments

    I've decided that it's not terribly useful to have an atomic clock but not really know how accurate it is. And since it can take a year or so for the Rubidium oscillator to be off by a millisecond (and much longer for a visible error), I need to take precision down to the microsecond. This requires modifying the time library (again) and measuring how far off the internal time is from the GPS pulse when the GPS is taken "offline." Also, the GPS and Rubidium pulse interrupts need to use micros() instead of millis() to "stamp" when they fire. I mean really, 1/1000th of a second is an eternity.

    Most of these code changes are already in place, but I'm now having issues when the micros() function wraps after 4.2 billion microseconds elapses (every 71 minutes). Should not be too difficult to track down and fix, but debugging is trickier when you have to wait over an hour to see if you've fixed it!

    Anyway, I should be able to see errors in the microseconds accumulating after a day or two, depending on how consistent the measurement is. More to come...

  • Nearing completion

    Paul Leskinen08/14/2015 at 18:38 0 comments

    It's alive! Everything is wired and almost all mounted in the case. I'm testing the software, and once that checks out, I will (try to) make everything look pretty inside the case. I am currently running in atomic mode--solely based on the Rubidium 1 PPS output.

    This turned out to be a bit more challenging that I initially expected. I was not particularly happy with the solderless breadboard approach--I ended up ditching that and bascially just putting pin headers on the nano and plugging everything in to that. I also have a large ground "bus" and 5V "bus" that were made from pin headers. I really would prefer a more robust solution to the ground/5V buses, but that is the way I'm doing it for now.

    Here is a shot of the (nearly) completed project.

    From left to right, the buttons are main power, Rubdium power, then on the right side are the menu button and select button. Once things are more permanent inside, I will get a picture of that (and maybe use a better camera). Video to follow too.

  • Fabrication

    Paul Leskinen06/02/2015 at 18:41 0 comments

    This project is nearing completion. Front panel for the display is cut, as well as drilled for switches and buttons. The oscillator mount points are drilled; the back panel only needs a hole for the power cord. Lucite is cut for the display window. Remaining work is re-spraying the front panel, tinting and mounting the Lucite, wiring switches and pushbuttons, and mounting everything inside the case.

    I would estimate another 2-3 hours' work until completion. I will add some photos to the gallery as well showing my progress.

  • Slow progress

    Paul Leskinen04/07/2015 at 05:03 0 comments

    New matrix boards ordered. These are from Electrodragon and are chainable using jumpers (though they will likely work better if the jumpers are replaced with wires and just soldered (or use lower-profile jumpers). The current driver boards I have are not going to fit in the box due to the overhang of the board and the right-angle header pins. I could desolder and resolder new wires and/or headers, but that doesn't sound like fun. Not only that, but they do not attach to each other and would require some kind of backplane to hold them in place. For $26 shipped, I have a solution that will work (hopefully) much better. Will still need some structure behind it, but should be a more reliable setup.

    On the software side, I've completely rewritten the matrix library to be much faster by using direct byte transfers from the font array to the buffer and by only syncing with the 7229 registers when necessary. Things were getting a little sluggish with only 4 matrices but with these optimizations it all looks very speedy now. Have also written the menu system and defined the menus and settings. Still waffling on the animation of the numbers--I'm not sure I like it enough to put the effort into the rewritten library.

    I've ordered a couple panel-mount pushbuttons to operate the menus as well as a couple other miscellaneous parts. I think I have everything I need either in hand or on order now.

    Time to stop ordering stuff and start building!

  • The Build Log

    Paul Leskinen04/02/2015 at 22:04 0 comments

    Parts have all arrived. So now it's time to fabricate the front panel and wire everything up. I have basically rewritten the matrix library to support a full 5x7 font (eliminated the sprite class and substituted some print functions). Code is in place to use the Rubidium PPS signal to accurately set the RTC clock during times of no GPS signal. Finalizing desired menu items. Need to find a couple suitable panel-mount pushbuttons to support basic menu items.

    Also considering whether to include leap-second handling and how to do it if so.

View all 5 project logs

Enjoy this project?



Steve wrote 01/12/2018 at 22:09 point

Are you going to publish the wiring diagrams and software that was used such as the Arduino sketches?

  Are you sure? yes | no

Dharmesh2499 wrote 05/18/2021 at 18:49 point

Awaiting the same

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates