PAReX Home

Phoenix Area Robotics eXperimenters

Home Club Info Web Log Meetings Events Rules Articles Links

November 26, 2003

Designing with Stepper Motors

Introduction

Having built 8 robots, 6 based on hacked servos for drive motors, it was time to try something different. The biggest problem with any wheeled robot is getting the darn thing to travel in a straight line. Since no two DC motors are going to spin at the same rate, some form of feedback system must be used to detect and adjust for these differences. I’ve used wheel encoders to count the pulses and range sensors to monitor the distance from a wall. Given enough time and code tweaking, you can get these methods to work for you, but again I wanted to try something different, thus I began my research into the use of stepper motors. Rather then go into a lot of detail on how stepper motors work, this article will cover the process I went through to design and build a maze runner robot using stepper motors.

Concept

Ok, so what is a stepper motor and why do I want it? A stepper motor consists of several field coils that are energized in a sequential fashion to rotate the motor’s armature in steps. Each of these steps is very precise and gives you excellent control of the motor’s movement. The motors I used have almost 1800 steps per rotation, that a lot of precision! To control the robots movement becomes a simple matter of counting the number of pulses you send to the motors to travel a desired distance.

Details

Ok first I needed to get some stepper motors. Not knowing a thing about them I ordered a pair from a surplus center and started playing with them. The specs sounded good, 400 pulses per revolution and they would run on 5 volts. I built up a driver circuit on a breadboard using an AT90S2313 micro and an h-bridge driver. It was thrilling to see the stepper spin around and be able to precisely control it’s movement, but it was whimpy. There was no way a pair of these motors would be able to move a robot around, so I did some more research. When looking for stepper motors, one of the specs you need to look at is the dynamic torque, which is how much power can be applied when moving the shaft. The motors I started with were probably NEMA 17. After reading other articles and newsgroups on robots and steppers, I determined that I needed at least 60 oz.-in. torque or a NEMA 23 motor.

None of the surplus centers I normally use had anything this big. If they did they were expensive. Even on Ebay a set of 3 CNC steppers would typically go for more then $50. Fortunately those same people that were recommending NEMA 23 motors also had a source for them. Turns out the Image Writer II, an old dot- matrix printer for Apple computers have such a stepper motor in them. In fact I was led to believe that they contained a pair of identical stepper motors in them, which would be great since I would need two motors for the robot. Back to Ebay and a quick $3 bid got me a printer! Course I had to pay about $10 in shipping. Once the printer arrived I opened it up and quickly discovered that while there are indeed two steppers in there, only one is the big NEMA 23. This one is in the bottom and moves the print head assembly back and forth. The other motor is much smaller and spins the platen and tractor feed assembly to move the paper through the printer.

Text Box: Figure 1

Before removing the motor from the printer I wanted to see what the drive pulses looked like that moved the stepper. Since this motor has 6 wires coming out of it, that tells me it’s a unipolar motor and that 2 of the wires are commons, while the other 4 wires go to 4 separate coils as shown in figure 1.










Once I had an oscilloscope attached I could see the waveform shown in figure 2. One of the first things I noticed was that the pulses overlapped each over, something I hadn’t done with my earlier experiments. This technique is called half-stepping and allows you to get even more torque out of the motor. The down side is that you use a little more battery power, since you briefly have two coils energized instead of only one.

Text Box: Figure 2


Next step was to develop my own driving circuit and see if I could control the stepper motor. Using the same 2313 and 4 MOSFET's, I built the basic circuit you see in figure 3. I wrote a test program that duplicated the 4ms pulse train the printer driver used and started experimenting. The new motor was a lot more powerful, I couldn’t stop the shaft while holding it with my fingers! Just for chuckles I changed the waveform back to driving one coil at a time and noticed the output torque was significantly reduced, to the point of not being able to move the robot. So the final design would require half-stepping and a beefier power source to handle the load. Now that I had the right type of motor I needed, and a basic idea of what to do with it, I needed another motor. Another visit to Ebay got me a 2nd printer and I verified that the second printer had the same stepper motors in it. Now I could start designing the robot.

Text Box: Figure 3



Power Supply

All of my previous servo based robots used 3-volt logic on the controller board. This allowed me to run the entire robot off of 4 AA batteries since the 6-volt supply would drop down to 4 volts before the power supply couldn’t regulate and the servos struggle to work. To use the stepper motors a different approach was required. The MOSFET drivers need more then 3 volts at the gate to turn on and I also wanted to use a digital compass on this project, so a 5-volt logic controller was needed. To supply 5 volts to the controller would require either a fancy step-up/step-down supply with a 6-volt battery, or a higher voltage battery pack. Knowing the steppers would draw more power over their servo counterparts I also wanted to use a higher current capacity cell, so a 7.2 volt sub-c based pack seemed like a good selection. These packs are commonly used in R/C cars and are readily available for under $20. The only other concern was noise. If these steppers motors were extremely noisy, then isolated supplies might be necessary, would mean using optically-isolated drivers and different supplies for the motors and controller board. I decided to design the power and driver sections with optical isolators, use a single power supply, but design it to use two supplies if needed.

Motor Driver System

The driver circuit for the unipolar stepper motor is fairly straight forward. The common side of both coils are tied to the plus side of the power supply and N-channel MOSFET’s are used to sink each coil to ground and energize them. The gates of the MOSFET’s could be driven by the TTL outputs of the microcontroller, but this is where the isolation comes into play. By using optical-isolators between the micro-controller and the MOSFET drivers, most of the noise generated by the motors won’t find it’s way back to the controller. A typical circuit would now look like figure 4.

Text Box: Figure 4

From a software standpoint it would be nice to drive all the driver circuits from the same 8-bit I/O port. This arrangement would also allow all the drivers to be updated at the same time with a single instruction. A concern I had was the total current capacity of that single I/O port. In order to keep all 8 coils turned off, the LED’s in the optical isolators must be on. This means all 8 bits of the port are sinking current, which would exceed the total current capacity of the port. So the polarity of the port pins needed to be inverted. The obvious solution would be to use inverters between the micro and the optical-isolators, but that would require at least two more IC’s where space was quickly becoming a premium. By swapping the location of the pullup resistors and the optical- isolators, the required inversion is satisfied without additional parts. The final driver circuit in shown in figure 5.

Text Box:  
Figure 5



Firmware Development

After the robot was designed and the circuit board was built, I was able to start working on the firmware to drive the stepper motors. My intent was to use one of the timer interrupts to generate the waveforms needed to drive 8 port pins and both motors, and handle it all within the interrupt service routine (ISR). In doing so it becomes a background task that I don’t need to deal with as part of the main code. A good design will minimize the amount of time spent in the ISR and a lookup table seemed to be the fastest approach to use for this task.

Text Box: Table 1

The table would mimic the actual waveform and a simple version would look something the one to the right. Each column represents the logical state of one coil in the motor. Each time we advance through the table, a different coil will get energized.





Text Box: Table 2 The real table is more complex since we need to control two motors and I was planning to use half-stepping for the additional power, so now the table looks like this. Each nibble drives one motor and since the port pins are wired the same way, a single “OUT” command will update both nibbles and both motors.







Text Box: Table 3

Two final changes are needed. One is to invert the table, since the driver circuit works in an inverted fashion. The other change is to reduce current spikes when each coil is energized, by not allowing both motors to turn on at the same time. The way I did this was to double the size of the table and only change one nibble on either side. I wanted to maintain the original timing of the waveform I observed from the printer board, so each pulse will be 4ms in duration. Since the lookup table has doubled in size, the timer interrupt will occur every 2ms. The basic operation of the ISR is to point to the lookup table and use an index to retrieve the next entry. This 8-bit entry is sent to the I/O port to update the driver circuits, and the index is incremented to the next entry in the table.












Now if all we had to do was run the motors all the time, then we’d be done. Of course we need to start, stop, and turn, so once again things get a little more complicated. To start and stop the motors I decided to use a global flag that was set when I want to motors to operate, and cleared when I want to stop. Within the ISR, the first thing it does is test this flag and exit the ISR if the flag isn’t set. Other approaches would include starting and stopping the timer itself to prevent motor updates. Turning and going backwards are little tougher to handle. To make the motors go in reverse you simply decrement the index pointer instead of incrementing it, which walks through the lookup table backwards instead of forward. To let the ISR know if you want to go backwards, another flag is set by the main code when we want to go backwards and the ISR will test the flag before incrementing or decrementing the index pointer. Turning requires one motor going forward and one going backwards. Since both motors are controlled by a single table, the use of a 2nd table is the only way to get the motors going in opposite directions. Once again a flag is used to tell the ISR whether to use the straight table or the turning table. A summary of the 3 flags is shown in table 4.

mtrRunning mtrTurning mtrBackward Operation
0 X X Robot is stopped
1 0 0 Robot is going forward
1 0 1 Robot is going backwards
1 1 0 Robot is turning left
1 1 1 Robot is turning right

Table 4

Once all these routines were in place, it was time to get the robot moving through the maze. One of the most critical operations is turning, I need to have precise 90° turns to move the robot around. With the steppers it should be a simple matter of counting the pulses that are sent to the motors and stop after a predetermined amount. To test this operation I setup a simple routine that performs 4 turns with delays between the turns to allow the robot to come to rest. When the routine is complete the robot should be sitting right where it started from. After coming up with the proper number of pulses to use for a single turn I noted that the turns still weren’t consistent. From past experience with servo motors I had a suspicion that the problem was too much momentum, the motors were simply turning too fast. By reducing the speed of the motors during a turn, this may give me the added control I needed. To reduce the speed of the motors I simply changed the timer interval from 4ms to 8ms to reduce the pulse rate by half. Now the turns were consistent enough to start running in the maze.

Final Testing

I was impressed with how straight the robot moved around my 4’x4’ test maze. Most of the time it could run the entire maze without touching the walls, and this is without any kind of guidance correction at all. The times that it did get off track were due to starts and stops that would turn the robot slightly. I suspect using some form of ramping function to accelerate and de-accelerate the robot might help, but I didn’t have time to develop anything before the next maze event. Instead I planned to use range sensors to track my relation to the nearest walls and adjust the robots direction as needed, something I would have done anyway, since we can never achieve perfect handling all the time. So the final routines I added were ones that would align the robot parallel with the nearest wall after each turn. This precision required further reduction in turning speed, so the robot wouldn’t turn faster then the range sensor could update, so I added a quarter-speed routine for the aligning routines.

Conclusions

Working with stepper motors was a very rewarding project. I now have a very stable robot that operates smoothly and drives straight as an arrow.

Posted by Kelly Small at November 26, 2003 05:27 PM

Comments

I realy appreciate the idea on your robot. i am working on my school project on maze robot. I am using stepper motor that has 3.7 degree per step. I am a littile bit confused on the program. can I SEE UR SOURCE CODE U USED TO DRIVE THE MOTOR and to solve the maze I realy appreciate if you can do it.Thanks.
Tewodros

Posted by: Tewodros at February 15, 2004 07:56 AM

sir,i m a tyro in making a robot.i want to know more about robot construction and all it's requirement that r needed.
so,could jsut mail me and help me in making my first robot
from india.

Posted by: himanshu at March 4, 2004 12:07 AM

Sir i am a B.Tech pre-final year student.Iam very much impressed by the way u outlooked ur robot designing.i m an opener to this field but i m keen to make a project on "pc controlled spider robots".could u help me regarding the circuits and interfacing in this project. i would be highly obliged if u do me this favour

Posted by: Esha Malhotra at March 11, 2004 03:20 PM