I’ve now got a schematic and program for running a bipolar stepper motor via a serial interface (just as for the unipolar case). This is important for the robot arm cause because two of the three steppers will be of the bipolar kind.
Where driving the unipolar stepper required only current ‘pushing’ (ie all in the same direction through a common ground), a bipolar motor requires current to flow in both directions. The following image shows the difference.
In theory the control of this is very easy with two half H-bridges (essentially four transistors) controlled by several Picaxe output lines). The basic concept is shown below.
(Source: http://commons.wikimedia.org/wiki/File:Bipolar_Stepper_Motor_H-bridge.png)
The L293D chip has the requisite transistors and a nice interface (with lots of extra features that my DIY skills couldn’t match). I’ve also used it in the mobile robot experiment to control the direction of 2 motors.
As with anything like this though, one needs to think through the sequence and outline a table of output values corresponding to the steps, as below.
| Direction | Coil 1 | Coil 2 |
| N | + | 0 |
| NE | + | + |
| E | 0 | + |
| SE | - | + |
| S | - | 0 |
| SW | - | - |
| W | 0 | - |
| NW | + | - |
At first I was using 6 output lines (!) – 4 for each of the transistor inputs and 2 for enabling or disabling the L293D’s 2 ‘half h-bridges’. In this configuration it could be reduced to 4 by using an external NOT gate (because 2 of the controls are always the opposite of another 2). Such a scheme would look like this:
| Direction | EN1-2 | 1A | 2A | EN3-4 | 3A | 4A |
| N | 1 | 1 | 0 | 0 | 0 | 0 |
| NE | 1 | 1 | 0 | 1 | 1 | 0 |
| E | 0 | 0 | 0 | 1 | 1 | 0 |
| SE | 1 | 0 | 1 | 1 | 1 | 0 |
| S | 1 | 0 | 1 | 0 | 0 | 0 |
| SW | 1 | 0 | 1 | 1 | 0 | 1 |
| W | 0 | 0 | 0 | 1 | 0 | 1 |
| NW | 1 | 1 | 0 | 1 | 0 | 1 |
But while trouble shooting this (I had swapped LSBs with MSBs so it probably did work after all!) I came across a site tying the enable lines Hi and using 4 control lines. At the poles one of the loops must have zero current flowing through it. In the above scheme this is done by setting the enable line Low and ignoring the A values. In the 4 line scheme this can be achieved by sending the same control output to both ends of the loop (ie the potential difference across the coil is 0). Then the table looks like this (including half stepping):
| Direction | 1A | 2A | 3A | 4A |
| N | 1 | 0 | 0 | 0 |
| NE | 1 | 0 | 1 | 0 |
| E | 0 | 0 | 1 | 0 |
| SE | 0 | 1 | 1 | 0 |
| S | 0 | 1 | 0 | 0 |
| SW | 0 | 1 | 0 | 1 |
| W | 0 | 0 | 0 | 1 |
| NW | 1 | 0 | 0 | 1 |
That makes the schematic as follows:
…and the program as follows. Note that this program is designed to wait until it detects a serial input on input 0 (pin 17) in the form of three bytes: The first is a qualifier – 85 uniquely identifies this stepper motor – the second is the number of steps – 0-255, and the third is the speed – 0-127 is backwards, 128-255 is forwards.
'Serial driven stepper motor by DMT195 symbol posrotor=b0 symbol numturns=b2 symbol speeddir=b7 symbol direc=b8 symbol pulsegap=b3 symbol counter=b4 symbol modrotor=b1 symbol outbyte=b5 posrotor = 1 'set starting position start: 'main sequence - wait for command then move the motor numturns=0 'sets a default number of turns high 7 'reset ready flag serin 0,T2400,(85),numturns,speeddir 'get serial data gosub getspeed 'get the direction and speed gosub move 'perform number of steps goto start getspeed: if speeddir>128 then 'find direction and store in direc (1 is +ve, 0 is -ve) direc=1 else direc=0 endif speeddir=speeddir//128 'gets the speed 0-127 negative, 128-255 positive (higher =faster) pulsegap=264-2*speeddir return move: for counter=1 to numturns pause pulsegap 'wait before moving again (set by speed) if direc=1 then posrotor=posrotor+1 'increase/decrease the step by one else posrotor=posrotor-1 endif gosub moverotor 'set the rotor position for this step next counter return moverotor: modrotor=posrotor//8 'find out where the rotor arm should be (1 of 8 positions) lookup modrotor, (0x08,0x0A,0x02,0x06,0x04,0x05,0x01,0x09), outbuyte '(%00001000,%00001010,%00000010,%00000110,%00000100,%00000101,%00000001,%00001001) is (0x08,0x0A,0x02,0x06,0x04,0x05,0x01,0x09) in hex 'looks up the step from the sequence and applies it to the output pins pins=outbyte return
Please leave comments if you’ve found this useful or if you think I’ve made a mistake.
I have something to say about accessing all these devices through a single serial port too but that will have to wait for one or two more tests…
Update: Of course this can be done with a PICAXE 08(M) with the 4 outputs and 1 serial input to spare. The pinouts would have to change as would the respective program. If there’s enough demand for me to document this I will. Let me know in the comments. Consider using this little board from Technobots.
Update 2: I’ve reduced the code length by using a lookup table instead of the select/case structure. I’ve also use hex to reduce the size of that line (but included the binary values in a comment below for those that are interested).
Posted by dmt195
Posted by dmt195
Posted by dmt195 

