I have a project that i shelved for a couple of years, but am thinking of starting it up again.
The project is basically to drive a stepper motor connected to a gear box such that the end shaft will rotate once every sidereal day (23h 56m 4.091s) with accuracy.
I had got to the point of using a GPS module to set an accurate tempo eg 1hz with a high degree of accuracy.
However, i hadn't resolved how i would programme the number of (micro)steps so the motor would be driven accurately over the day.
Looking for coneptual ideas for me to research and understand how i could bring all these large decimial points together to a uniform and accurate rotation.
So first - what precision do you need in rotation? That will determine the stepper motor and gear ratio.
the sidereal day is 86164091 msec - for 360 degrees - so you need an angular division of less than 0.015 seconds of arc.
I dont know how realistic that is. You will need a very precise worm drive gearbox with no backlash.
Perhaps you could revise your specification to use the arduino internal clock - or a RTC module - that synchronises to NIST at frequent intervals, and correct the rotation at that time?
Or perhaps the system could incorporate some sensors (magnet, limit switch, small hole with a led and sensor,…) at precise points so that the system could sync from time to time the physical angular position of the shaft to known position and avoid drifting too much.
The way I'd set up the drive would be to have it always stepping, and always under load - hoping to avoid backlash issues.
I wont be running the unit for 24 hours (at least not at this stage) - more like maximum 1-2 hours.
Some of my original thoughts were to run the motor at a reasonably rounded number of steps and then pause momentairily and start again. The idea being that the movement would oscillate around the true sidereal rate with only very small errors.
I was going to use two planetary gearboxes (1:51 each) and microsteps to get the precision.
I had also planned to fine tune the precision, or at least verify it using a test rig to measure the time interval for 1 rotation once i had it set up.
I was hoping to use a small arduino unit, but i see some libraries that deal with sidereal time use double precision and recommend the Due for its better accuracy in calculations.
Not sure if other third party units might be smaller and also support double precision like the Due.
What are you trying to achieve? Do you want a clock that displays sidereal h/m/s; of just a shaft the turns once per s.d., or are you trying to track a star with a telescope? All of those have different requirements. The last is probably the most demanding.
A worm drive isn't necessarily the best as you can only get integer divisions (1/N). Spur gear combinations can give rational ratios (N/M). These have been extensively studied for clocks and a short paper (dating from 1934!) is attached. Using the simplest of these, 366/365, can get you within 18 parts in 10 million.
As for driving the stepper and calculating microsteps, I suggest you look up Bressenham's algorithm, which was developed for use in computer graphics but is very useful in rotary dividing systems. Basically you compute the nearest whole number of steps to give you a desired increment which would need a non-integer number and as you apply that number of steps keep a running tally of error, and when that gets larger than a certain threshold you add or subtract a step next increment.
If precision is really essential don't rely on microstepping to get it. Most common stepper drives are quite inaccurate at interpolating between whole steps.
Make it tick like a clock with a second hand. Tick - compute target and tell servo to go. Wait a minute (or a second) and recompute angle again and repoint. No step counting and skipping. No reduction. Just point to desired angle for each "hand". Look at the analog clock project and just change the angle routines.
Thank you I'll do some reading. Bressenham's algorithm sounds like the kind of concept i was thinking of except adding the additional step instead of my thought of pausing for a set duration. I think this will help.
I'm only trying to achieve shaft rotation of 1/s.d.
If you're going to be making gearboxes it might be simpler to use a synchronous A/C motor and avoid any arduino-related complexity. A synchronous motor will move at the same speed, locked to the frequency of the AC voltage so you just plug it into the wall outlet and it runs at a fixed speed.
Alternately, if you're using OTS gearboxes (I wasn't quite clear from your post) another way would be a DC gear motor with an encoder and use the arduino to perform speed control. This might be smoother than the stepper.
I was going to mention that Slo-Syn made a stepper motor that was also designed to run as a synchronous A/C motor with the addition of a capacitor. Then I googled it and realized that they cost around $800 now. Guess I'll hold on to the last one I have
I don't know what the mathematical relationship is to another name for doing essentially the same thing
phase accumulation
which you can do with floating point but more common in microprocessors is to use fixed point calculations - all done with integers, and a "binary point" wherever you need it within the integer.
86164.091 seconds per revolution. Divide that by your steps per revolution to get seconds per step. Let's say you have a basic 200 SPR stepper: 430.820455 seconds per step.
You can fit that in microseconds in an unsigned long.
const unsigned long MicrosecondsPerStep = 430820455;
const unsigned long GPSInterruptMicroseconds = 1000000;
unsigned long ElapsedMicroseconds = 0;
// Every pulse from the GPS
void GPSInterrupt()
{
ElapsedMicroseconds += GPSInterruptMicroseconds;
if (ElapsedMicroseconds >= MicrosecondsPerStep)
{
DoAStep = true;
ElapsedMicroseconds -= MicrosecondsPerStep;
}
}
void loop()
{
boolean stepNow;
noInterrupts();
stepNow = DoAStep;
DoAStep = false;
interrupts();
if (stepNow)
SiderealStepper.step(1);
}
I think this is a simple and smart way to manage it.
I sat down and did some checks in excel to understand theoretical accuracy that doesn't account for any real-world issues. My calculations include consideration of micro stepping and adding gearbox ratios:
Sidereal Day
86164.090530833
Seconds
Motor steps per rev
800
Steps
Gearbox
51
ratio
Seconds per step
2.1118649640
Seconds
microseconds per step
2111864.963991
Microseconds
Working backwards to check accuracy on paper using integers of a whole day:
microseconds per step
2111865
microseconds
Seconds per step
2.111865
seconds
Gearbox
51
ratio
Motor steps per rev
800
steps
Actual rotation for full circle
86164.092
Seconds
Accuracy in seconds
-0.001469167
seconds
Accuracy %
-0.000001705080369%
Angular accuracy
-0.022097842
arcseconds
I'm very happy with the potential accuracy of the system using integers, on any number of combinations of micro steps and gear ratios. Ideally, having two gearboxes in series (2x 1:51 giving me 1:2601 would be better on paper because the time between movements will be much less and therefore better resolve immediate accuracy through better raster resolution. The overall daily accuracy would remain similar. Two gearboxes have additional issues of mechanical accuracy.
Further, considering how I trigger the movement, I feel like I might be best served by establishing the most accurate timebase/clock for the arduino and then triggering the drive using interrupts and the integer time I establish for the particular microstepping/gear ratio setup.
What do you think? I'll ask about thoughts on establishing accurate timebase/clock when we get to that.
Look at the time on the mark. Compute where to look. drive servo there. No error. Interrupts can be missed or powered off and upon powerup, time and position will still compute properly and point servo.
If you're really clever, add a 3D motion sensor and have it stay locked when moved.
How are you going to target and designate the object to track? If you're running a motor continuously you need to be able to slew rapidly to establish initial target lock. This thing needs to be bolted into concrete to work long term.