I have recently had some questions about my knowledge and background in motion control and so I though I’d summarize here to help get my thoughts in order.
I have largely worked with stepper motors to date. For precision positioning (at least by the standard of things I’ve worked on) they are cheap and effective. They have also bee relatively small motors (NEMA 14 to NEMA 17 types) and driving a single axis using a lead screw. I have been looking at putting together a RepRap 3D printer recently, but haven’t yet ordered the stepper for the project.
Most of my detailed motion control experience came when I was working for Howtek. We were designing, manufacturing and selling high end imaging systems for graphics arts and medical film scanning. Our first few designs used a dedicated 80188 microprocessor board for motor control. Precision timing was managed with assembler language coding (this was probably one of the last CPUs where noop sequences would provide good timing as pipelines and caches came into general use shortly). The entire board was dedicated to controlling one stepper motor, the drum drive and reading the quadrature encoder that checked carriage motion.
I became directly involved when we needed to significantly cost-reduce our medical film scanner design. We were moving to a single 386ex processor for all control functions (from a system where I/O, motor control and overall system control ran on independent CPUs). In order to make this transition we needed to dramatically change the stepper control implementation.
The step to step timing is critical if a stepper motor is to run smoothly and reliably. We could not depend on the processor to directly provide this in the new system. For the new design we chose to use a CPU timer/counter segment to provide the time base for commutating the motor. A two stage pipeline for windings state was implemented using two latches with the first latch writable by CPU and its outputs driving the inputs of the second latch. The second latch was clocked by the timer/counter output and fed the drivers that ran the windings (I can’t remember whether this was a unipolar motor or an H-bridge driving a bipolar motor). Each time the time triggered, and IRQ would be delivered to the CPU at a rather high priority as well, allowing the processor to update the winding drive pattern for the next time interval.
This was a single axis system that positioned a heavy aluminum sled holding a rotating acrylic drum with a positional accuracy of approximately 1/4000 of an inch. The stepper motor was coupled to a lead screw that was connected to the sled using an anti-backlash nut. There was a quadrature encoder on the far end of the lead screw that was used to verify that the mechanism was responding to stepper impulses. Flags mounted on the ends of the carriage slotted into optical interrupters at either end of the carriage run to indicate that the end had been reached. The sled was mounted on one side to a circular cross section linear rail using a PTFE contact bearing (this was a cost reduction from previous systems that used linear bearing with a ball bearing race inside). The other side of the sled had a follower (spring loaded with brass rollers for tracking I believe) running along a rectangular cross section bearing. This arrangement allowed larger out of parallel tolerances between the two rails in comparison to previous systems (with two captive bearings the sled would bind if the rails were even slightly out of true).
On system start up (I believe this was carried out on the first commanded motion which would occur immediately if the door was closed and secured) the software would comb the winding pattern forward for one or two steps. This was performed to ensure that the rotor and stator relationship was known before making larger motions. Once the motor had been synchronized in the manner, if the parking side end stop sensor was occluded, a slow move out until the sensor was cleared would be performed, followed by a home to sensor move to establish the parking position of the sled. If the sensor was not occluded, the system would perform a slow home operation until the sensor was occluded (slow moves were not ramped and were run at the maximum unramped step rate for the system).
Normal move to position transits were ramped moves where the timing between steps decreased from the initial value (thus accelerating the movement) until the maximum speed was achieved and then ramped back down in a similar manner to ensure a clean stop. Given that we retained a memory of the current position of the sled and that we had feedback from the quadrature encoder if something caused the sled to fail to respond to a step request we could substantially improve performance by doing this. Moves that were run against the normal imaging step direction would be set up to overshoot the destination position slightly and then move back a short distance to take up any slack (backlash) in the drive system.
Once the sled was positioned at the start of operation position, the imaging system would be primed for data acquisition and scan stepping (not ramped, fixed number of steps per scan line) would be initiated. In this mode, each burst of steps (to position the sled for the next scan line) would be slaved to the needs of the imaging system to ensure clean image data (no motion during imaging) and repeatability (the hosts would sometimes fail to keep up and the scanner would need to stop for a time as internal buffers were saturated).