Stepper Motor Control

This can be a pretty trivial process, simply switching four pins in a sequence and driving four buffers.

Typical steppers have 200 steps per revolution (1.8 degrees per step). Not sure why this was chosen instead of say 180 or 360 steps. Perhaps it is more convenient for decimal positioning. For example, if driving a threaded shaft with a 1 mm pitch, then 100 steps would give 10 micron increments, and 200 steps would give 5 micron increments. To do the same with a 180 step motor, the thread pitch would have to be 0.9 mm. In practice, ISO threads for fastening bolts have slightly irregular pitches:

Dia./mmPitch/mm
M30.5
M41.0
M10-121.5
M14-162.0
M18-222.5

Threaded screws for precision positioning tables are manufactured for particular pitches.

Stepper Motor Types

Unifilar

These are the simplest to drive: four transistors (one L293D chip) will do it.
Truth table (1=on, 0 = off):

V H  
T B L R Phase
1 0 1 0 TL
1 0 0 1 TR
0 1 0 1 BR
0 1 1 0 BL

Note that B = inverse of T, and R = inverse of L.

The L293D chip is convenient for hobbyists as it is available in DIP package. About £3 from Maplin.

Bifilar

These need an H-bridge to drive: eight transistors (two L293D chips) will do it.
Truth table is as above, except now 1 = drive high and 0 = drive low.

Okay, that's the simple part over with.

Half stepping

This involves using intermediate steps to double the resolution.

Microstepping

This involves coil currents to be more detailed than just on and off. We could do this using DACs to drive by high-current buffers, but it is much easier and efficient to drive in switch-mode. Typically 10-bit 20 kHz PWM.
The currents are driven sinusoidally.

Binary fractions

The easiest way is to use PWM between 0 and 255. In practice, this can be inconvenient. A 200 step motor becomes a 51200 microstep motor, and a 1 mm pitch thread provides a 19.53125 nm increment.

Decimal fractions

The nearest compromise is 250 microsteps per step. A 200 step motor becomes a 50000 microstep motor, and a 1 mm pitch thread provides a 20 nm increment.

Practical steppers

Ideal motors would have a perfect relationship between microstep and angle, but in practice they deviate. That is, the midway point requires more than 50% drive in each of two coils. The relationship is more like that of a sine and cosine wave, but even then not perfectly. This is going to vary between motors, so may not be worth the effort of calibration, especially if the microstepping is far smaller than the mechanical errors.

Practical mechanics

Mechanical components are unlikely to work with 20 nm resolution for many reasons. They're unlikely to be machined to that accuracy, thermal expansion changes the size of parts, and screw threads have 'backlash'.

Countermeasures

Lateral thinking

Microstepping pulses can run at very high rates (MHz), while switch-mode PWM runs at a few kHz. Therefore the pulse generators are whizzing through positions the PWM is does not update that often. It seems smarter to have a device that simply recalculates the PWM values at kHz rates.

Video line rates are 15.625 kHz, which is around the right value for PWM. The Atari has 228 memory cycles per line, which is not quite enough for 250 microsteps/step.
250 memory cycles = 3.57954 MHz / 250 = 14.318 kHz.
200 memory cycles = 3.57954 MHz / 200 = 17.89772 kHz.
200 microsteps is a practical decimal value giving nearly 20 kHz PWM.

Sine wave table

A bit tricky, but could approximate the more linear section. Fortunately, if there are 200 microsteps, then only 0 to 49 need a table. Of those, the first 14 can go directly to the output if full-scale output is 63. (200/pi = ~64).

Implementation so far

So far the implementation is just a simple full-step fixed-speed interface to a single motor. This is enough to get something turning and demonstrate the high-current buffer is working.