Block Diagram

DS3231 moduleSimple clock    Real-Time Clock: The DS3231 real-time clock/calendar IC is based on a temperature compensated 32 KHz crystal oscillator, with a claimed accuracy of 2 parts per million at ordinary temperatures ( 2 minutes per year). This little clock IC supports all the features that a worthy clock should have, and it includes an IC interface! The module pictured on the left was purchased from Amazon Prime for $5.99, battery included! To get started with it, I downloaded an RTC library from Adafruit, and ran their simple and instructive demo from this page. Using a 16 x 2 LCD that was on hand, I put together a simple clock display (photo right), which amounted to little more than substituting LCD for Serial as the output channel in the Adafruit example. In the back of my mind, or maybe somewhere in the middle, was the thought of interfacing the WWVB receiver. This was not a particularly compelling idea. Similar interfaces have been done countless times, and in better ways. On the other hand, I had only a murky idea how the clock and receiver/decoder could be made to work together within a single control program. It seemed, for example, that the WWVB signal decoding part, which involves timing of level durations, might complicate updating the clock display. The appeal of the undertaking was the near certainty of learning something.

    In the vein of keeping my options open, I ordered a 4-line LCD. 
There could be no harm in throwing something together on a breadboard, and fiddling with a few possibilities. Meanwhile, I thought that a timed interrupt might work for updating the real-time clock display without interfering with WWVB decoding. Googling this idea led to another fine instructional example: http://www.instructables.com/id/Arduino-Timer-Interrupts/. —Interrupt service routines should be sparse. My thought was that the ISR would not actually update the display, but rather signal when to update it.

Interrupt Service Routine

    Most physical clocks have a convenient way to adjust the time, such as pushing buttons or turning a knob. Perhaps I should have taken time to do this. Things did not go smoothly at first. Once the WWVB simulator was connected, the clock would get synched to an old (simulated) date/time. Not only that, but due to coding errors, the wrong year was being set, and Daylight Savings Time was in effect in January! Those were my errors—nothing wrong with signal decoding, or with the clock. 


    When the 4-line LCD came, I added WWVB data to the bottom line of the display. This brought up an interesting sub-problem, namely how to save WWVB data when power was removed from the microcontroller. The clock has a battery and continues to run and keep time whether it is connected externally or not. However, the Nano does not have a battery. That is when I learned about Arduino’s EEPROM: https://www.arduino.cc/en/Tutorial/EEPROMWrite.

Save and restore sync data

    The complete Arduino (Nano) sketch is here: wwvb-RTC.ino. When dealing with more than one time source it would be easy to lose track of which source is responsible for a variable named ‘hour’ or ‘minute’. To help make their meaning clearer, I substituted names like ‘rtcNow’ and ‘wwvbSecond’, where normally simpler names would suffice.

    While the display update is interrupt driven, the internal clock update is not. Whenever a valid decode of WWVB data occurs, the clock gets updated at that moment. Essentially all decodes of simulated data are valid. However, as previously discussed, only a fraction of real WWVB decodes are valid. In the first overnight period of testing with the real receiver, 37 decodes were valid, the last at 07:26 UTC (2:26 AM Eastern Time). The antenna was the loopstick-in-the-window setup, same as pictured in the WWVB paragraphs.

Annotated example of WWVB sync

    By the time the above LCD screen photo was taken, I had transferred the circuit from breadboard to a generic circuit board. This phase of the project did not proceed smoothly either. I had intended to socket each of the IC-form components, but decided for expediency to solder the level converter directly to the board. This was a mistake. At first it appeared that the receiver had stopped working, but on investigating I found the trouble was not with the receiver but the level converter. To correct the problem I socketed a second converter on a small accessory board and fastened the pieces together, leaving the original level changer soldered in place, but not connected.

Circuit Boards and LCD

    The two IC devices are wired side-by-side at one corner of the circuit board. The real-time clock plugs in battery side up and the 4-wire cable next to it runs to the LCD. A couple of jumper-header combinations serve as switches. For example to turn off the LCD backlight, the jumper from D2 is moved to ground. To run the simulator, the yellow jumper from D3 is moved from the level converter to the output of an off-board TTL inverter, as indicated in the block diagram.

   
During testing, no WWVB decodes were classified as valid that were not actually valid. Therefore it is unlikely that an invalid decode might misadjust the clock. [This problem was observed subsequently, however.] Nevertheless, the validity checker could be made stronger. For example, the decoded year should agree with the clock year 1.

   
The moment when seconds tick on the display is not generally the same instant that the real-time clock increments seconds internally. Moreover, the WWVB seconds counter can only be trusted when there has been a valid decode. A shorter update interrupt interval, say half a second, might improve display accuracy, but that hardly matters. I even considered using two Arduinos, one dedicated to the clock and the other to WWVB.

    Two issues remain unresolved at this writing. The LCD occasionally blinks dark-light for a fractional second—I don’t know why. Of more practical consequence, the clock stops or freezes from time to time, maybe when processing an invalid sync. Pressing the Arduino reset button resumes processing, with correct time display and without loss of WWVB data. If I figure out what causes the interrupts or processing to stop I will post an addendum or revised sketch. While this narrative does not cover all of the project’s travails, the diagram together with the sketch basically tell the story, at least to the present point. [To be continued ...]



Projects Home







Project descriptions on this page are intended for entertainment only. The author makes no claim as to the accuracy or completeness of the information presented. In no event will the author be liable for any damages, lost effort, inability to carry out a similar project, or to reproduce a claimed result, or anything else relating to a decision to use the information on this page.