This blog entry was originally posted on Ara's own blog and is reposted here with his permission. --ESL
Curiosity, JPL/NASA’s new rover, has successfully landed on Mars and has now been roving the surface for nearly a year. An Earth year, that is.
Here's the thing with Mars though...time is kept differently there. This is because Mars itself rotates a little slower than Earth. Rather than a solar day taking 24 hours like it does here on Earth, Mars has a solar day of 24 Earth hours 39 Earth minutes and 35 Earth seconds. This proves to be a pain when it comes to timekeeping. If you set your normal Earth watch to the exact Mars time at that moment, you will lose a Mars second every 36 seconds on your watch. This is because Earth seconds and Mars seconds are different. If you want to have a 24-hour day (sol), you must scale the 24 Earth hours, 39 Earth minutes and 35 Earth seconds into 24 Mars hours. This redefines a second: 1 Mars second = 1.0274912510416665 Earth seconds (side note: a Mars day is called a "sol").
Now who really needs this? The answer is the Mars rover team. In order to have an efficient day driving on Mars, the rover driving team lived on Mars time, at least at the start of the mission. From what I can tell, it seems painful. However, I wouldn't mind doing it if it was for the opportunity to drive a rover on Mars. Although I don't live on Mars time and am not involved in the driving process, I still have this odd fascination with keeping track of Mars time. I remember back in 2004 a local jeweler had figured out how to make analog Mars watches. This was too cool! I realized I couldn't dish out $300 (a lot of money for a kid back then) to get a watch I wouldn't need. Most of the people who bought them were a part of the Mars team anyway.
Fast forward 8 years and now we have a new rover on the surface of Mars, and although I had a very, very small role in the mission and I'm still nowhere near having to live on Mars time, who says I can't have a Mars watch anyway?
With the knowledge of keeping time on Mars and a good background in embedded systems I figured it shouldn't be too hard to modify a digital watch. I searched around and found the perfect watch for this project: the TI Chronos eZ430 915Mhz (available to buy here: TI-Store, Digi-Key, Mouser, Newark).
The watch comes loaded with features: RF communication, timers, alarms, accelerometer, barometer, and a temperature sensor.
The watch also comes with an RF to USB module, USB programmer/debugger, and a screwdriver. For $50, it's a steal. I looked over the example code before purchasing it and discovered that I could modify the timer that controls watch's master timer. So I put in the order, rewrote the timer code (which I go into detail about below) and modified the date files to keep track of sols rather than days.
So let's dive right in.
First off, if you want to develop, you will need to download Code Composer Studio, which will come with the default watch firmware (also available here). If you just want to flash the watch with the Mars watch firmware, scroll down to the "Firmware" link and follow instructions below.
So anyway, the processor on the watch is based on the TI MSP430 and has several timers. The default program (ez430_chronos) that keeps track of the time is located in clock.c, clock.h, timer.c, and timer.h. The first thing we need know is that the clock source is a 32.768khz internal crystal. This internal clock is connected to Timer 0. The code in the function void Timer0_Init(void) found in timer.c configures the timer to count continuously up to 32768 (TA0CCR0 register), which takes exactly 1 second to reach. Once the timer reaches 32768 it triggers an interrupt which calls the function void clock_tick(void) in clock.c that takes care of the clock logic (when to increment hours, minutes, and seconds). Since the sol is 24 Mars hours, the logic will remain the same and we will mess with the timer that triggers the Mars second. What we want is the timer to go off every 1.0274912510416665 earth seconds so that it would be the equivalent to 1 Mars second. So you essentially want to scale up and count that extra 0.0274912510416665 Earth seconds. Which means you need to increase the TA0CCR0 register value. This requires some really simple math:
Here we do some basic scaling and discover the new TA0CCR0 register value to be 33668.83...but we have a problem now: the register isn't a decimal value, it's a 16-bit value. So that means we can either choose 33668 or 33669 to count to. So I decided to calculate the error for each value, expecting less error if I went with 33669. The error for 33668 is losing 1 Mars second every 0.4 sols and the error for 33669 is gaining 1 Mars second every 1.3 sols. Makes sense since 33669 is closer to 33668.83 than to 33668. So I began to wonder how bad does this drift really become? To drift 1 Mars minute it would take about 78 sols and to drift 8.57 Mars minutes would take about 1 Martian year (approximately 668.6 sols).
As for calculating sol, I modified date.c and date.h so that when 24 hours is reached it increments 1 sol rather than day and month. The sol is displayed below the time. The sol tracking works just fine but the backend code is a little messy so I will clean that up ASAP.
After some testing and comparing against the Mars24 and Mars clock programs I concluded that the clock drift isn’t too bad and could easily be changed by going into the time set menu by holding the "*" button. You can also set the sol by holding the "#" button. Worst case, 2 years from now you may get 5 minutes late to something if you relied on the watch.
This all took me about 5 hours to figure out, write, and test, plus another hour to write this blog. The code is not very complete, but is a work in progress. I would say that it has the essentials for a Mars watch, and that the bells and whistles will come later. I might try to see if I can build in some compensation for the drift or modify the timer somehow to get a more accurate reading. I will also clean up the sol code and make it so that you can track both Earth and Mars time in one watch. I figured it'd be nice to get the code out there so others who want to modify their watches into Mars watches can do so.
UPDATE: Jon Hollander made a comment on Hack a Day with a very elegant solution to losing that 0.833 in 33668.883. Rather than just picking 33669 and dealing with the loss of 0.166, he recommended switching between 33669 and 33668 until you average 33668.883. Turns out if you replace the TA0CCR0 += 33669; in Timer.c with the following code below you can greatly increase the accuracy. The code below will count 33669 5 times then 33668 1 time, thus averaging out the counting to 33668.833. Hooray for minimizing error!
To upload the firmware you can select the firmware txt file and upload it using the Chronos Control Center software that comes with the watch, or download the software here. The connection is established through the USB wireless access point (included with the watch).