I'm building a telescope mount controller that requires the stepper motor controlling the right ascension axis to be stepped at a regular and precise interval. I've written a few simple Arduino sketches and read the Arduino language reference but it seems like I'm going to need to go to a lower level to properly write the program for this. To give you an idea of the challenge, the maximum permissible error is no more than +/- 10 uS per step event with step events occuring roughly every 1/10 s based on the gear ratios of the various components in my mount.
Since the application calls for use outdoors in extremes of temperature and humidity I don't think that I can trust the built-in timers without some sort of external time reference. I'm envisioning using a GPS module to provide a precision pulse-per-second signal to an external interrupt on Arduino and measuring the length of a second in timer ticks. Then, I want Arduino to step the motor every time the number of ticks corresponding to the step interval have passed.
The Arduino language reference discusses how to generate interrupts based on external signals which will be useful for getting the PPS signal but I've found nothing in there concerning acces to the hardware timers. I've seen some sample code floating around these forums for microsecond timers but they use calls that aren't in the Arduino language reference and I'm hesitant to use any code that I don't understand. Can anyone point me towards some literature that describes how to access the hardware timers and generate software interrupts? Also, comments and suggestions for the project are welcome.
Interesting application and I can appreciate the timing tolerance one requires for telescope work. I can't really help you with timer questions but the 16mhz crystal controlled clock used by the Arduino should be pretty good. One thing your program might include is fast and slow trimming switches so that you could tweak the speed of the RA in real time to compensate for any variables. This would just add or subtract from some timer preload value.
Any reason in particular you want to use a stepper?
I'm not an astronomer, but my friends in the hobby advise me that a servo connected through a good quality gear chain or belts is a better solution. Since tracking is continuous the smooth nature of the servo matches the task better and is less likely to introduce vibration or encounter backlash related problems.
GPS is a good source for a timing base, but it seems possible that if you are trying to receive and process GPS data via the serial port you may have difficulty maintaining your 10uS timing precision.
You might instead want to consider an oven controlled crystal oscillator. They are substantially more expensive than regular crystals, but very stable and a fraction the price of a GPS receiver.
Thanks for the suggestions, I'll definitely look into the DS1307 and improving the Arduino frequency source accuracy.
DaveK: The stepper I'm using is an OEM part for the mount and the gear train quality is excellent. You bring up a good point about receiving and processing GPS data though. I hadn't planned on trying to parse the NMEA strings since the module I'm planning to use has a dedicated pin that generates a TTL-level PPS signal. I don't really need to know position or local time for anything but I figured I would go with GPS since I have a module in my parts box.
I suspect the crystal on the arduino will be just fine unless you are in a desert in the daytime or on one of the poles. A typical quartz crystal has a tolerance of 50ppm or less. If I did the math right, that's +/- 800Hz for a 50ppm 16MHz crystal.
A TCXO (temperature controlled/compensated crystal oscillator) will give you around 0.5 to 1 ppm.
A GPS PPS (pulse per second, i.e. a 1Hz clock) signal isn't really going to help unless you use it to discipline a PLL that will generate your clock. Likewise the DS1307 RTC (which uses a 32.768kHz xtal).
Errors, rounding, and overflows from the counter(s) you use are a more likely source of problems. Sounds like you should dig in to the ATmega datasheet and read up on timers.
By my math it seems like the frequency spread you cite for the quartz crystal is outside the error tolerance: 800Hz spread -> 1.25 ms error. The assumption I made is that the quartz crystal source might not be exactly 16MHz but that whatever it is in actuality will remain constant for constant temperature and humidity. If that is the case, then I could find the number of timer ticks between two PPS pulses and then determine the interval between step events in timer ticks.
I'm reading the timer documentation and it seems like I can set it up to interrupt and reset when the timer matches some value. If I'm doing my math in integer microseconds and integer ticks then even with round-off errors I shouldn't lose more than a couple of us. As long as the interrupt and step event latencies remain constant then the step events should occur with the correct interval.
One thing that I'm not clear on from reading the datasheet is how to implement access to the timers. I can see that Atmel defines many register addresses of interest with names but I don't understand how I would write to those registers from the Arduino IDE. Is there any documentation for this?
When trying to come up with a specific timer interval I've found that, as kg4wsv mentioned, the biggest source of error is usually in what the timer interval ends up being, not the crystal accuracy.
So, you might investigate the details of setting up timers, then pick a combination of crystal frequency and timer setup that gives a result that is as close as possible to the target.