Critical to getting our CNC-based pick-and-place machine working is driving the stepper motors.
We've already managed to get some 4-phase, six-wire motors spinning using a ULN2803A darlington array. But the problem was the current was too great and they started to smell really quickly. Not much longer after that, the magic smoke get let out.
We stripped a Lexmark Z73 printer scanner and salvaged some motors, and even stripped the steppers from old floppy disk drives. So we've no end of stepper motors to play with, but not much luck in getting them turning. The main problem has been that the motors we took from the old hardware and donated stuff off Freecycle are all 4-wire 2-phase/bipolar motors.
We upgraded the original stepper circuit, replacing the ULN2803A with 4 x IRF640 mosfets. The IRF640 chips have built-in fly-back diodes (they're designed for driving inductive loads) so we don't have to worry about any extra external components. The "gate" is isolated and can use logic-level (5V) voltages to switch them on.
This allows beefier stepper motors to be controlled (up to about 16A) but they are set up to drive 6-wire/4 phase/unipolar steppers. We still didn't have a way of driving 4-wire/2 phase bipolar motors correctly.
Until today.
Thanks to Jason at BuildBrighton, we've got a few L293D half-H-bridge chips to play with. And they work perfectly for driving scavenged stepper motors. Here's how we connected each IC to the coils on a bipolar stepper motor.
So now we've got a way of driving both 4-wire, 5-wire and 6-wire stepper motors.
We've got a nice beefy PC power supply to provide the power without having to worry about running more than two motors together (the earlier 500mA phone-charger just wasn't up to the job!) and the stepper driver chips can handle up to 1A per channel (4-wire/biopolar) and a massive 16A or more for six-wire (unipolar) motors.
The trick is to make our driver board(s) compatible with any combination of steppers so that anyone else who wants to make one of these machines can source parts for it cheaply and easily.
At the minute we're trying out a number of different ideas and don't have enough time to devote to developing each idea, AND write it up on the blog with photos/diagrams/full descriptions. So over the next few days, we're going to play about with a few ideas then write up the most successful ones here......
Showing posts with label unipolar. Show all posts
Showing posts with label unipolar. Show all posts
Saturday, 10 September 2011
Tuesday, 23 August 2011
Stepper motor forwards and reverse
A quick video showing the stepper motor going in both forwards and reverse directions.
Schematic shows PORTD connected to two ULN2803A darlington array ICs. For simplicity we've used one IC per motor, but each IC can in theory support two motors at a time - the 16-pin ULN2003A has only 7 available darlingtons, these 18-pin ULN2803A chips have eight). Pin selection is a bit messy - we'll probably move these around for the final version when it comes to putting everything down on a PCB, for easier routing.
The jog buttons (RB7 + RB6) allow the user to manually move the stepper motor in either direction. Alternatively, you can send a move "request" to the microcontroller, which consists of number of steps to move (a two-byte value) and direction (forwards/reverse)
The noise in the video is not rowing neighbours, as suggested by some viewers, but a Radio4 play and my partner on a sewing machine in the other room!
In the video we're using a 1.8 degree stepper motor.
That means 360/1.8 = 200 steps for one complete rotation. We're driving the motor in "half-step" mode (for increased precision when connected to a belt-drive) so 400 steps are required for a full rotation. The video shows a value of 1 (high byte) and 144 (low byte) being entered - this is the same as (1*256)+144 = 400
The motor responds by completing one full complete rotation.
Monday, 22 August 2011
Driving a stepper motor directly from a PIC
Much has been written about driving stepper motors. Some sites say it's easy. Some people say it's hard. Some people say you have to get the timing and the sequence right, some people say it's more hassle than it's worth and you should just buy a stepper driver board!
We've spent just a few hours today playing about with our (quite beefy) stepper motor (borrowed from Matt at 18robots.com until we can buy/salvage some 1.8 degree steppers) and found it's quite straight forward - provided you follow each step slowly and carefully.
The first thing to do is understand how the stepper motor works.
We're just going to stick to the common 4-phase stepper motor. It has four coils and we need to energise each coil in a particular sequence, in order to get the shaft to turn.
For the sake of simplicity, we'll only use one form of stepping (you can use whole-step, half-step and micro-stepping for different levels of precision). For whole stepping, you energise one coil at a time. With micro-stepping, you vary the amount of current going into one or two coils at a time. We're going to make all our movements using half-stepping, which means activating one or two coils at any one time.
To get the above stepper to move anti-clockwise, we need to energise:
As you can see, it takes 8 pulse combinations then we're back at the start. This sort of makes sense, since we have four coils, and we're using half-stepping (twice as many steps needed as for whole-stepping).
Now we know how a stepper motor works, we need to identify each wire in our bunch of six coloured wires. Sadly, there's no common colour chart to refer to - different manufacturers use different coloured wires so don't just blindly follow this set-up: find out how your own stepper is wired using this technique
Create a chart listing all six colours of your stepper motor in rows and columns.
With a multi-meter, measure the resistance between each coloured wire and the five other wires. Write down these values - each coloured wire should be connected to two other wires. It doesn't matter what these values are, what we're looking for is which values are twice the others.
Where you have the double-resistance values (in our case, black + green and red + blue) this is where you've just measured across two coils. These are the outer-most coil wires (in our example, black=A, green=C, red=D, blue=F)
Where you have single resistance values (in our case black + yellow, green + yellow and red + white, blue + white) you've just measured across a single coil so one of these pairs of wires must be the "one in the middle" - or common wire.
In our example, yellow is between black and green, so yellow=B and white=E
With this information, we're ready to wire everything up and make our motors move!
We've created a USB interface which allows us to send movement commands to the PIC 18F4550 microcontroller as well as a "jog" button. We can send a command to the PIC to say "move the motor through X number of steps", or we can "jog" the motor - i.e. make it rotate for as long as the button is pressed.
Here's a snippet of the Oshonsoft Basic code for controlling the single stepper motor:
loop:
UsbService
'every time we take an input pin high, pulse the stepper
If PORTB.7 = 0 Then
'jog the x axis motor
jog_x = 1
steps_to_move_x = 0
Gosub stepmotor
Gosub delay_after_pulse
Else
'update the X axis motor
If steps_to_move_x > 0 Then
Gosub stepmotor
steps_to_move_x = steps_to_move_x - 1
Gosub delay_after_pulse
Endif
Endif
Goto loop
End
stepmotor:
If stepdir = 0 Then
step_pos = step_pos + 1
If step_pos > 7 Then step_pos = 0
Else
If step_pos = 0 Then
step_pos = 7
Else
step_pos = step_pos - 1
Endif
Endif
Gosub energizecoil
Return
energizecoil:
'our test stepper is wired with
'red-white-blue and green-yellow-black connected
'(white is common, yellow is common) so we need to drive them
'in the pattern red, black, blue, green
'to turn in one direction and red, green, blue, black to
'turn in the opposite direction
Select Case step_pos
Case 0
Low x_coil4pin
High x_coil1pin
Case 1
High x_coil1pin
High x_coil2pin
Case 2
Low x_coil1pin
High x_coil2pin
Case 3
High x_coil2pin
High x_coil3pin
Case 4
Low x_coil2pin
High x_coil3pin
Case 5
High x_coil3pin
High x_coil4pin
Case 6
Low x_coil3pin
High x_coil4pin
Case 7
High x_coil4pin
High x_coil1pin
EndSelect
Return
delay_after_pulse:
If stepper_delay_us > 0 Then
WaitUs stepper_delay_us
Else
WaitMs stepper_delay_ms
Endif
Return
We've split the current position of the motor into 8 segments (numbered 0-7) so we always know which is the next combination of coils to energise to continue rotation. So wherever the motor stops, it can start again from exactly the same position - we don't have to return to a "known rest-state" as we should always know the next step in the sequence.
To move the motor, we can either hold down the jog button, or set a value in the two-byte variable called steps_to_move_x (this motor will form the basis of our x-axis). If this variable contains a value, we energise the necessary coils, move onto the next coil "state" and reduce the value in steps_to_move_x by one.
When this value reaches zero, we can send a message back to the PC to say we've arrived at our destination. This way, the PC can use a "fire-and-forget" messaging system: it tells the device how far it wants each motor on each axis to move, then gets on with other work. It doesn't have to keep asking for an update report, the device will inform the PC when the task has been performed (the PC fires off the request, then can forget about it!)
Here's a quick video demonstrating single-axis rotation using a 4-phase stepper motor. You can press (and hold) a button to "jog" the motor along, or send a value to the microcontroller, to tell it to move through a specific number of steps.
Sorry about the bad light! This was taken in the early hours of the morning (when most of the coolest development gets done) and it seems the camera doesn't like our artificial light)
We've spent just a few hours today playing about with our (quite beefy) stepper motor (borrowed from Matt at 18robots.com until we can buy/salvage some 1.8 degree steppers) and found it's quite straight forward - provided you follow each step slowly and carefully.
The first thing to do is understand how the stepper motor works.
We're just going to stick to the common 4-phase stepper motor. It has four coils and we need to energise each coil in a particular sequence, in order to get the shaft to turn.
For the sake of simplicity, we'll only use one form of stepping (you can use whole-step, half-step and micro-stepping for different levels of precision). For whole stepping, you energise one coil at a time. With micro-stepping, you vary the amount of current going into one or two coils at a time. We're going to make all our movements using half-stepping, which means activating one or two coils at any one time.
To get the above stepper to move anti-clockwise, we need to energise:
- coil 1 only
- coils 1+2
- coil 2 only
- coils 2+3
- coil 3 only
- coils 3+4
- coil 4 only
- coils 4+1
As you can see, it takes 8 pulse combinations then we're back at the start. This sort of makes sense, since we have four coils, and we're using half-stepping (twice as many steps needed as for whole-stepping).
Now we know how a stepper motor works, we need to identify each wire in our bunch of six coloured wires. Sadly, there's no common colour chart to refer to - different manufacturers use different coloured wires so don't just blindly follow this set-up: find out how your own stepper is wired using this technique
Create a chart listing all six colours of your stepper motor in rows and columns.
With a multi-meter, measure the resistance between each coloured wire and the five other wires. Write down these values - each coloured wire should be connected to two other wires. It doesn't matter what these values are, what we're looking for is which values are twice the others.
Where you have the double-resistance values (in our case, black + green and red + blue) this is where you've just measured across two coils. These are the outer-most coil wires (in our example, black=A, green=C, red=D, blue=F)
Where you have single resistance values (in our case black + yellow, green + yellow and red + white, blue + white) you've just measured across a single coil so one of these pairs of wires must be the "one in the middle" - or common wire.
In our example, yellow is between black and green, so yellow=B and white=E
With this information, we're ready to wire everything up and make our motors move!
We've created a USB interface which allows us to send movement commands to the PIC 18F4550 microcontroller as well as a "jog" button. We can send a command to the PIC to say "move the motor through X number of steps", or we can "jog" the motor - i.e. make it rotate for as long as the button is pressed.
Here's a snippet of the Oshonsoft Basic code for controlling the single stepper motor:
loop:
UsbService
'every time we take an input pin high, pulse the stepper
If PORTB.7 = 0 Then
'jog the x axis motor
jog_x = 1
steps_to_move_x = 0
Gosub stepmotor
Gosub delay_after_pulse
Else
'update the X axis motor
If steps_to_move_x > 0 Then
Gosub stepmotor
steps_to_move_x = steps_to_move_x - 1
Gosub delay_after_pulse
Endif
Endif
Goto loop
End
stepmotor:
If stepdir = 0 Then
step_pos = step_pos + 1
If step_pos > 7 Then step_pos = 0
Else
If step_pos = 0 Then
step_pos = 7
Else
step_pos = step_pos - 1
Endif
Endif
Gosub energizecoil
Return
energizecoil:
'our test stepper is wired with
'red-white-blue and green-yellow-black connected
'(white is common, yellow is common) so we need to drive them
'in the pattern red, black, blue, green
'to turn in one direction and red, green, blue, black to
'turn in the opposite direction
Select Case step_pos
Case 0
Low x_coil4pin
High x_coil1pin
Case 1
High x_coil1pin
High x_coil2pin
Case 2
Low x_coil1pin
High x_coil2pin
Case 3
High x_coil2pin
High x_coil3pin
Case 4
Low x_coil2pin
High x_coil3pin
Case 5
High x_coil3pin
High x_coil4pin
Case 6
Low x_coil3pin
High x_coil4pin
Case 7
High x_coil4pin
High x_coil1pin
EndSelect
Return
delay_after_pulse:
If stepper_delay_us > 0 Then
WaitUs stepper_delay_us
Else
WaitMs stepper_delay_ms
Endif
Return
We've split the current position of the motor into 8 segments (numbered 0-7) so we always know which is the next combination of coils to energise to continue rotation. So wherever the motor stops, it can start again from exactly the same position - we don't have to return to a "known rest-state" as we should always know the next step in the sequence.
To move the motor, we can either hold down the jog button, or set a value in the two-byte variable called steps_to_move_x (this motor will form the basis of our x-axis). If this variable contains a value, we energise the necessary coils, move onto the next coil "state" and reduce the value in steps_to_move_x by one.
When this value reaches zero, we can send a message back to the PC to say we've arrived at our destination. This way, the PC can use a "fire-and-forget" messaging system: it tells the device how far it wants each motor on each axis to move, then gets on with other work. It doesn't have to keep asking for an update report, the device will inform the PC when the task has been performed (the PC fires off the request, then can forget about it!)
Here's a quick video demonstrating single-axis rotation using a 4-phase stepper motor. You can press (and hold) a button to "jog" the motor along, or send a value to the microcontroller, to tell it to move through a specific number of steps.
Sorry about the bad light! This was taken in the early hours of the morning (when most of the coolest development gets done) and it seems the camera doesn't like our artificial light)
Subscribe to:
Posts (Atom)


