Sidereal time

The stars rise about 4 minutes earlier every day, making them seem to march ever-westward across the sky.

I received the gift of a real-time clock (RTC) circuit last week, and it got me to thinking about how to convert a RTC tuned to solar time into one tuned to sidereal time.

A solar day (the kind measured by the RTC) is 86400 seconds long. A sidereal day is ~86164 seconds long. They differ by a factor of 1.0027379.

The RTC uses a 32768Hz crystal to keep time. In order to keep sidereal time, that crystal would have to vibrate at 32857.7155072Hz instead.

Searching the ‘net for such a crystal was fruitless. Apparently, astronomers don’t have enough pull to get manufacturers to make watch crystals for sidereal clocks.

An important side note: why 32,768 ticks per second? Any computer geek will glance at that number and know it’s a power of 2. It turns out to be 2^15, in fact, which seems like a strange value for an ultra-accurate crystal that is so ubiquitous that it’s actually referred to as a “watch crystal”. Remember, back in the days when people still though digital clocks were pretty nifty, most digital clocks showed HH:MM, and the colon blinked on and off to show the seconds? Well, it turns out that if you have a 16-bit value (65536 possible values), the 16th bit is “off” for values 0-32767, and “on” for values 32768-65535. So if you have a crystal that can drive 32768 times a second, then that 16th bit will be off for exactly 1s, then on for exactly 1s, then (as the counter rolls over to all 0s again) off for exactly 1s again, and so on. Sound familiar?

OK, so what all that means is that, since you probably don’t want the thing to roll over every 2 seconds, you take your 16-bit value, and set the highest bit “on” to begin with, so that it only takes 1 second to fill the rest of the bits. You pre-fill the counter with 0x8000 hex. Essentially all RTC implementations do this. OK, back to the show.

So a sidereal day is slightly shorter than a solar day. Which means that sidereal seconds go by slightly faster than solar seconds do. In fact, a sidereal second goes by in 89.7155072 fewer ticks (of a watch crystal) than a solar second does.

Hm.

So, if I pre-populate the counter with 0x8059 hex (that’s 89 more than 0x8000), the clock will run a little slow (0.715… ticks per second slow). If I pre-populate the counter with 0x805A (90 fewer ticks), the clock will run a little fast (by 0.284… Hz). A mix between the two could reduce that error significantly.

After much spreadsheet-twiddling, I came up with an algorithm that I am sure is to make me famous, at least in my own mind:

Algorithm to calculate extra ticks required to change 32768Hz into 32857.7155072Hz
Required: extra 89.715…Hz of ticks
1) pre-populate 16-bit counter with 0x8059 (it will fill 90 ticks early every sec), except

2) To account for the delta .715… seconds (first-level correction), out of every 7 seconds (one “stanza”), only populate for 89 extra ticks (0x805A) on seconds 1 and 5 (-1,0,0,0,-1,0,0,-1,0,0,0,-1,0,0…)

At this point, clock will run slow, losing 1 tick every 45min or so, 1 second per 17 days

3) To correct this (second level correction), after every 18 stanzae, add one “leap second” of 90 ticks (does not count in a stanza)
At this point, clock will run fast, and will gain 1 tick in 1.16 days (1 second gain in 103 years). This is probably accurate enough for anything not involving a space probe.

However, another “leap tick” can be subtracted every 784 stanzae, which will boost the accuracy to 1 second gain in 518,000 years.

The RTC that I’m using is a DS1307, which has a battery backup and can maintain its time even with the rest of the circuit unplugged. It also can put out a 32768Hz pulse, which I will read on a second chip to become a sidereal clock.

For the sidereal clock, I thought about using an Arduino. It would be easy to code up, I have them available, and it would not take much in the way of resources on the circuit.

However, I wanted something more compact, and I have a bunch of PIC 12f683s lying around, and I already have code to drive the 16-bit Timer1, so I decided to go that way. The ‘683 is an 8-pin chip, and honestly is overkill for this; the 12f675 would work just as well. It’s just that I have 4 ‘683s lying around unused, and only 1 ‘675, so there you go. I have yet to figure out how to maintain the sidereal time with a backup battery, so I may have to set it at startup every time. That works for me.

I have decided to implement I2C in software to allow the PIC to run on the same bus as the Arduino and RTC.

This entry was posted in Electronics, Knowledge, Science, Technology and tagged , . Bookmark the permalink.

One Response to Sidereal time

  1. Pingback: Sidereal Time, cont. | Things on My Mind

Leave a Reply

Your email address will not be published. Required fields are marked *