Skip to main content

RTC without RTC ? How good is my crystal ?

Clock - I think that it's the most popular idea for a project with the MCU. It's not that hard from both software and hardware side to realize but not that trivial as well, not mentioning the fact that once realized it sits somewhere in the house, constantly reminding about itself and brings a kind of satisfaction :). There are a lot of options really to implement, a buzzer alarm, perhaps a thermometer, display and buttons servicing, perhaps maybe even serial port usage for NTP synchronization. But ...

The most challenging thing - like in every clock is the time reference source. There are a couple of options:

  • well calibrated frequency source acting as an interrupt source
  • Real Time Clock module with external crystal ( < 20 ppm )
  • internal clock


These days RTC chips are so cheap and widely available that they are really the only reasonable choice, but if we're only planning to play around a bit with the software without paying much attention to accuracy and just for the sake of curiosity let's check how good the crystal to generate the system clock on the Arduino board is.

System Clock


System clock is generated using an external 16 MHz crystal. This crystal is not ideal, although it's quite stable - it may be surprising that it doesn't resonate exactly with the referenced frequency. In fact this frequency is a little bit different. 

Stability


A crystal accuracy is measured with ppms (parts per million). A typical crystal used to generate a system clock is something around +/- 50 - 100 ppm. Let's assume 80 ppm. The day has:

day = 24 * 60 * 60 = 86400 s

the hour

hour = 60 * 60 = 3600 s

If we would want to use this crystal as a reference for the clock application our clock would loose/gain:

per day:

86400 * 80 ppm = 86400 * 0,0008 = 6,91 s

per hour:

3600 * 80 ppm = 3600 * 0,0008 = 0,288 s

On the worst case it would be around 9 s per day. That's not that bad for a toy project.

Resonance frequency


Although the stability is quite satisfying, information about the exact resonance frequency is needed. How different is the resonance frequency of a typical 16 MHz crystal from the referenced 16 MHz ?

Using some code I can roughly measure it without using any laboratory equipment like frequency meters or oscilloscope. In fact I don't have access to this hardware and for most of the simple projects which I present here, although it would be helpful it's not a must.

The simplest way to estimate the crystal frequency is to use the code already created in libpca. Let's generate a tone of let's say 1 kHz frequency with a libpca beeper API. Now, Instead of connecting the buzzer I'll connect the pin to my laptop's microphone input directly and try to record it. The code is trivial:

Recorded signal:

1 kHz square signal recorded from OC0A pin.

This rough measurement shows that the full period took 45 samples at 44,1 kHz sampling rate, this gives the period of ~1,02 ms. The crystal clock period is 16000 shorter. After dividing the measured period of 1 kHz beep by 16000 and converting it to frequency, the answer is:

f =~ 15,68 MHz.

This means that our clock application will loose seconds. Every second measured will in fact be a 1,02 seconds in reality. This gives 1.2 seconds behind after every minute ! Of course the measurements done cannot be taken very seriously since they are done very inaccurately and without a proper tools, but keeping them in mind, let's write a simple application and see how much our "clock application" will be wrong from real time.



The above code is self explaining more or less, the "epoch" variable is incremented in the interrupt service routine every second (since interrupt happens every 1/256 s and epoch is incremented only when the cnt variable wraps). The time is send via Serial Port as a string.

After flashing it and running. I did some comparison between the measured time and the "real" time with a stopwatch. After an hour, Arduino has been a second behind. The crystal instability (80 ppm) results in 0,3 seconds behind. Assuming 0,7 second lost per hour I can roughly estimate that my crystal is less than 16 MHz by something around 3 kHz. So, it's more like 15,9968 MHz.

Conclusion


When building a real clock application RTC chip is a must, the system clock won't provide enough accuracy to be considered as a frequency reference good enough. Not mentioning the obvious advantage of having the RTC - the time is counted even if the main CPU is not powered, since most of them have a backup lithium battery circuitry.

The methods used to estimate the Crystal's resonance frequency cannot be treated serously with any level of confidence and used for a real production purpose, since they present no practical level of accuracy and the results are only a general hint.

Comments

  1. This comment has been removed by a blog administrator.

    ReplyDelete

Post a Comment

Popular posts from this blog

Arduino R-2R ladder Audio DAC

There is a lot of projects out there which use  R-2R ladder and an Arduino to recreate sounds from either SD card or short audio clips programmed directly to MCU's flash memory. Although using SD card is fairly reasonable and provides a lot of flexibility it's not very challenging (from the software point of view) and it requires some additional hardware. Believe it or not we already have all the needed hardware in the Arduino itself. Assumptions In this project I'll play mp3 or any other multimedia files from the PC using Arduino. Bellow are the details: Play PCM 8kHz 8bit Audio with Arduino Audio samples will be transfered via USART from the PC in binary format using SLIP Audio files will be decoded on the PC side and only the RAW data will be send to Arduino Timing Arduino is a powerful machine, powerful enough that it's possible to play audio with even higher sampling rates and bit-resolutions than assumed above, the bottleneck in this...

Simple Serial Port Command Line Interface (CLI)

It's often very useful to have some sort of interface through which a basic management can be done of our application. Whether you're designing a giant Marquee with a LED display or a plotter or you simply need to get some diagnostics from your device occasionally, a simple CLI system can come very handy.  Of course, designing something similar to "bash" or any other unix shell is completely out of scope since those applications are huge and are simply an overkill for our needs. It's pretty simple though to create some basic, yet flexible & easilly extensible CLI system. First thing needed is a command type definition. This will bind a keyword with an actual underlying routine executed for that keyword typed in the CLI . typedef struct _t_cmd { const char *cmd; void (*fh)(void*); } t_cmd; The command type is pretty simple. There's the CLI command/keyword pointer, it holds a pointer to the execution function and that's it. OK, so...