■ FIGURE 1. Calibration panel.
■ FIGURE 2. Valid calibration value.
More Accurate RTC With Built-in Thermometer
Our DS1307 costs about $4 in singles from Mouser.
They have another RTC — the DS3234 — with a built-in
thermometer for about $8.35 in singles. It has an
accuracy of ± 2 minutes per year. Although I personally
think it is worth the price, it only comes in surface-mount,
so we'll stick with the through-hole DS1307 and provide a
calibration technique that might make it nearly as
accurate as the expensive one.
Calibrating Your Arduino Alarm Clock
I ran my AAC for a couple of weeks and checked it
more or less daily to determine that it is gaining 1.23
seconds per day. We calculate that a day has 86,400
seconds and since 1.23 seconds per day is the same as
0.813 days per second, we can multiply the days per
second times the seconds per day and get 70,244
seconds (70244.9 rounded up).
This is the number of seconds it takes for our AAC to
gain one second. So, if we set an alarm to go off every
70,244 seconds and subtract one second from our 'real'
time, we correct for the gain. I'm not sure how accurate
this will be over the long term, but I'd speculate that it
would be at least as accurate as the more expensive part.
Now, what we need to do is add a command in the
PC AAC application to send the Arduino the calibration
seconds, and whether to add or subtract a second at
each interval. Then, in the Arduino, we need to build an
alarm in the AAC that goes off every 'calibration' second,
and either adds or subtracts a second depending on what
it was told. [Yes, we could further automate this process
so that we wouldn't have to manually calculate the
calibration seconds, but I figure we'll only need to do this
once so for me, it isn't worth the extra effort.]
Let's review how we set and check alarms so that we
can see how to add the calibration alarm. In the
Commander module, we parse the input bytes from the
PC in the commandArray and see that the first byte is
58 April 2013
the character 'A.' Then, we call the
ACase() function where we further
parse the input bytes, noting that
the second byte in the
commandArray is the number
of the alarm (1 to 5).
We then call the setAlarm()
with the parameter being the
pointer to the DateTime class
instance for that alarm. The
setAlarm() function then reads the
rest of the commandArray bytes to
get the date and time to set the
alarm, and loads that into the
specific alarm instance.
Once the data is loaded, then
we can retrieve the unixtime for
that alarm (which you may
remember is the number of seconds since January 1,
1970). Now that the alarm is set, our timer interrupt sets
the check_alarm flag once per second, and the loop()
function looks to see if that flag is true.
If it is, then it checks each alarm to see if it is set. If it
is, then it calls the function specific to that alarm. That
specific alarm function then does whatever it is
programmed to do and finishes off by setting the
check_alarm flag to false.
We will create a new command 'C' to handle the
calibration alarm process, but we will try to use as much
of the regular alarm process as makes sense. We will look
at the Arduino side of this next month. For now, let’s see
how the PC application is modified to send the data.
Modify the PC Application
We need to send a calibration number and whether
to add or subtract a second to the AAC. So, let's use a
text box for the number and two radio buttons for the
add or subtract. We'll also need a send button when
we've input the data so that data is sent to the AAC.
The calibration number will need to be 32 bits to
accommodate the value, so to simplify things we'll break
the number into four bytes and send them separately.
We'll also send a fifth byte with either 0 for subtract or 1
for add. The Arduino will then parse this input packet and
set the calibration alarm.
Note in Figure 1 that we've added a Calibration
Seconds panel to the PC application that lets the user
enter the number of seconds to use as an alarm to either
add or subtract a second, depending on which radio
button is pressed.
When you press the Send button, you get the
message shown in Figure 2 that shows the AAC returns
that it was in CCase (if you are in the debug mode). It
returns the number you sent along with the add/subtract
state so you can verify that what it thinks it got is what you
think you sent.