Drive a Stepper Motor with an AVR Microprocessor

Got some scavenged stepper motors from printers/disk drives/etc lying around?

Some probing with an ohmeter, followed by some simple driver code on your microprocessor and you'll be stepping in style.

Remove these ads by Signing Up

Step 1: Get to Know Steppers

Basically, you're going to need to figure out where all the little wires go.

First step is to figure out if it's a unipolar or bipolar motor. Have a look at Jones on Steppers for some deeper background, then at Ian Harries' Site for a simple method to figure out an unknown motor.

Read up a bit, then join me in a walkthrough of this motor I got for cheap. (They're on sale for \$0.99 right now. They're small, relatively light, but don't have much torque. Don't know what it'll be good for yet.)

Step 2: Find Common Ground

So you've got five (or four, or six) wires. Your motor's going to have two halves, and you can probably even tell just by looking which side each wire belongs to.

If you're only looking at four wires, you're in luck -- it's a bipolar motor. All you have to do is figure out which two pairs of wires go together.

If you've got a unipolar motor, or more than 4 wires, you're going to have to break out your ohmeter. What you're looking for is the common (ground) wire for each half. You can tell which is ground in a bipolar motor because it has half the resistance to either of the poles than the poles do across themselves.

Pictured is my notes from hooking up wires to wires and noting the resistance (or if they're connected at all). You can see that White is the ground for the bottom trio b/c it has half the resistance to Red or Blue that they have to each other.

(This motor's strange and doesn't have a center tap on the top magnet coil. It's like it's half-bipolar, half-unipolar. Maybe you could use this to sense rotation in the Red-White-Blue coil when the Black-Yellow coil is being driven.)

Step 3: Figure out the Stepping Order

I was going to drive this motor as a bipolar one, so I'm ignoring the White ground wire. I've only got four wires to worry about.

You might want to run your unipolar motor as bipolar anyway, because it uses the whole coil in both phases instead of alternating between the two halves of each coil. More coil = more torque.

Run current through a pair (noting the polarity you chose) and then run current through the other pair at the same time. When you hook up the second pair, watch which way the motor turns. Write this down.

Now reverse the polarity on the first pair you chose. Then hook up the second pair again with their polarity also reversed. Note the direction.

From this you should be able to figure out the sequence for rotating the motor in either direction. In my example, both ended up turning counterclockwise, so stepping through the sequence in the same way I chose will step the motor CCW.

Step 4: Taking the Motor for a Test Drive

If you're not already tooled up for microprocessor programming, you could do worse than the Ghetto Development Kit or any of the various PIC programmers.

Hook up the wires directly up to your microproc and burn it up with the following code:

```/* Playing with getting the small stepper motors driven. */

/* Include delay function */
#define F_CPU 1000000UL
#include

/* Pin defs for ATTiny2313 */
/* Clockwise order */
#define BLUE     _BV(PB0)
#define BLACK    _BV(PB1)
#define RED      _BV(PB2)
#define YELLOW   _BV(PB3)

#define DELAY  200 /* milliseconds between steps */

int main(void){
DDRB = 0xff;    /* Enable output on all of the B pins */
PORTB = 0x00;            /* Set them all to 0v */
while(1){                     /* main loop here */
PORTB = BLUE;
_delay_ms(DELAY);
PORTB = BLACK;
_delay_ms(DELAY);
PORTB = RED;
_delay_ms(DELAY);
PORTB = YELLOW;
_delay_ms(DELAY);
}
}```

How simple is that code? Really simple.

All it does is make some nice definitions so I could refer to the wires by color rather than their pin-names, and then it toggles them on in sequence with an adjustable delay in between. For starters, I selected a half-second delay between steps.

See the short video for the results. If you're really on your game, count the number of steps per cycle to figure out the motor's single-stepping angular resolution.

(Oh yeah. PS. Drives with no load at 3.6v easily. See battery in video.)

Step 5: Swing it Back and Forth

So you've got it running clockwise. Anything more interesting?

A little code-cleanup, and we can run it back and forth.

I put the clockwise sequence into an array so that you can step through the phases with a simple for loop. Now you can run the loop up or down to go clockwise or counterclockwise.

`int main(void){  const uint8_t delay = 50;  const uint8_t clockwise[] = {BLUE, BLACK, RED, YELLOW};  uint8_t i;  DDRB = 0xff;                  /* Enable output on all of the B pins */  PORTB = 0x00;                 /* Set them all to 0v */  while(1){                     /* main loop here */    for ( i=0; i<=3; i++ ){     /* step through the colors clockwise */      PORTB = clockwise[i];      _delay_ms(delay);    }    for ( i=3; i>=0; i-- ){     /* step through the colors ccw */      PORTB = clockwise[i];      _delay_ms(delay);    }  }}`

See the racy video for the back-and-forthing.

Step 6: I never half-step, because I'm not a half-stepper...

Quest lyric aside, half-stepping your motor is where it's at. You get more peak current, more instantaneous torque, and twice the angular resolution.

Half-stepping in a nutshell: Instead of Blue, Black, Red, Yellow, you drive the motor with Blue, Blue+Black, Black, Black+Red, Red, Red+Yellow, Yellow, Yellow+Blue. The upshot is that for half the time you're engaging both magnets at once.

And during the times that both sets are engaged, the motor points halfway between the two, shrinking the angle between "steps" and making the motor turn more smoothly. Can you tell from the video? I'm not sure...

Now the part of the code that does the half-stepping looks like this:
`void halfStepping(uint16_t delay, uint8_t direction[]){  uint8_t i;  for ( i=0; i<=3; i++ ){	    PORTB = direction[i];	/* single-coil part */    _delay_ms(delay);        PORTB |= direction[i+1];	/* add in half-step */    _delay_ms(delay);  }}`

The first PORTB command sets a single pole to positive and all the rest to negative. Then it waits. Then the second PORTB command sets a second pole (on the other winding) to positive, engaging both windings for 1.4x the torque (and 2x the current).

A full program listing is attached below. Two arrays are now defined (clockwise, counterclockwise) and both have 5 elements each to allow for the i+1 entry in the halfStepping function.

Step 7: Add a Motor Driver

So far so good.

Only problem is that the motor doesn't seem to have all that much torque, which could be due to the fact that the microprocessor will only put out ~50mA per pin. The obvious next step would be to hook it up to a motor driver to supply it with more juice.

But then a little thinkin': I'm only driving it with 5v, and the coil-winding resistance is ~125 ohms. Which means that the motor's only drawing 40mA per pin, and it should be driven just fine by the (beefy!) AVR chip.

So to get more voltage driving the motor, I hooked it up to a SN754410 H-bridge chip. The circuit is pretty simple. Each pin from the AVR goes to an input, and the corresponding output pins go to the motor. The chip needs 5v for the logic section, and can take a lot more voltage in the motor section.

Running it on 11.25v (three 3.6v batteries) helped a bit. Noticeably more torque to my finger, but it's still not a powerhouse. Not bad for a motor which is smaller than a nickel, though. And now the circuit's become a general-purpose bipolar stepper motor driver.

Added Nov 29: Ran the motor last night at 12v for a while and it started to get hot. I'm not sure if it was a resonant frequency problem or if it was simply too much current for the windings. Either way, be a bit careful if you're driving this little motor with bigger voltages.

Step 8: The End

So what did I learn? Driving a stepper motor with an AVR (and an H-bridge chip) is pretty easy, even in the "fancy" half-stepping mode.

Not sure what I'll do with the little stepper motors just yet, though. Any suggestions?
 1-40 of 44 Next »
jatinbatra12 months ago
Hey I want to drive the motors according to the steps inputted by the user itself , and I do believe I require serial communication for that , I know it's a piece of cake for an arduino to do , but I want to get it with low level.
It would be great if yo could help me with that , I'm only a novice:)
holychachi1 year ago
I'm trying to come up with a way to control twelve steppers... Any ideas besides multiple driver boards?
The Real Elliot (author)  holychachi1 year ago
Nope! Multiple stepper drivers is the way to go. (Not sure you need multiple "boards", but at least multiple driver ICs.)

When you start doing anything times four or times twelve, it can easily bog your microprocessor down, especially if you're doing "fancy" motion control stuff like acceleration and deceleration. The best way around that is to offload as much as you can to purpose-built silicon.

And if you decide to get even fancier, you can dedicate one micro per motor or section-that-requires-coordination. Then you can use a master controller to run all the sub-controllers.

This gets rapidly out of the realm of quick-and-dirty hacks though, and into engineering. Are you sure you want to drive stepper motors? Can you do something with a DC motor and position sensors?

1 year ago
No I'm not sure I want to use steppers. Would it be more readable to go with dc motors and encoders? Feasible as far asfinancialy and less electronics overall? I would need the motors to move fairly slowly like 1 inch a sec. Possible?
The Real Elliot (author)  holychachi1 year ago
To run DC motors, you just need to apply power. If you need speed control, you can use PWM. Nerdkits has a good tutorial on running DC motors, for instance. (I'm writing a book on AVR programming at the moment with two chapters on motor control, but it won't be out until summer...)

Also see sites like Robot Room and Dallas Personal Robotics Group -- you'll need slightlly more complex circuitry if you'd like the motor to go both forwards and backwards. (There, again, a few dollars spent in motor driver chips is easily worth the hassle, IMO, but it's also fun to DIY.)

Slowing a DC motor down as much as you'd like to requires a gear train, which can be a pain to assemble. On the other hand, if you're slowing a DC motor down from a few thousand RPM to just a few, you'll get a tremendous gain in usable torque, so I'd say it's worth the tradeoff. And if you put your encoders upstream of the geartrain, you get an equivalent gain in measurement resolution, which can help if you need the motors to stay in synch.

awais mughal2 years ago
bro can i use hard disk motor ...?
1 year ago
No you can't, these are mostly 3 wire BLDC motors. I broke two l293 chips on one of these :) .
hi there, I made a attiny13 + uln2003 to controll a small stepper motor, which can only running at ~40 rpm, if I increase the output, the motor just not run, what's happened help please.
Callum Snowden3 years ago
An idea for the stepper motor, use two of them in a small robot as the drive motors to do fancy precision moves :)
specospec3 years ago
what about using l293d
The Real Elliot (author)  specospec3 years ago
Would be good.

If you're serious, you usually start off with an idea of how much torque and speed you need for your application, then find a motor that'll deliver, and then pick a motor driver depending on the motor's current requirements.

But for low-current applications, I've had good luck with the SN754410, for slightly larger currents the 293D is good, and above that, especially if you're driving with a microcontroller or need microstepping, Allegro has some great offerings.

And there's always build-it-yourself from 8 MOSFETs. Google for "H-bridge" to get an idea.

Enjoy!
vhk4 years ago
Hi I have a unipolar stepper motor 0.4A,15v,1.8 degree my chip is attiny3213, can i drive it with ULN2803?
4 years ago
Should be fine. According to manufacturers site: "currents up to 1 A at voltages from 4.5 V to 36 V"
wijting4 years ago
I m working with this stepper and a Picaxe 28x project board.
I want to make a 90 degree swing,  that would be about 5 steps, based on the 20 steps for 360 degree
anyone an idea how to do this in the Picaxe Basic language?
I can make it step but not exactly 90 degree forward and backwards
Any suggestion is welcome, thanks

Ebay5 years ago
where did u get that thing on the end of your motor to indicate it is turning?
geeklord5 years ago
Can someone please find me a good reference/explanation of the different functions/commands/whatever that are used for AVR's? I've been dinging around for a while now with an Arduino and would really like to start using just the uC and not a developement board and simple language with it. I pretty sure I can get past getting the HEX file on the chip, I just need help with the language. Thx for any help.
The Real Elliot (author)  geeklord5 years ago
Absolutely!

The language is C, and there's tons of good resources for that. For beginning I like the Kernighan & Ritchey book. Or search around for C tutorials on the web until you find one that looks good for you.

For AVR-specific C, everything you need is at the avr libc project page: http://www.nongnu.org/avr-libc/user-manual/index.html. While you're there, see their example projects link.

For AVR hardware-related stuff, there's the datasheet for the chip you're using (which can be a little daunting, but is very very good once you get used to it) and a bunch of projects online to learn from.

If I were just starting out, I'd pick up a project like a blinking-light kinda thing and learn just enough C to get that working. Then continue on project by project, expanding your hardware and software knowledge in tandem, but always with a concrete project in mind. At least that helps me...

I made a page of many helpful AVR resources for a class I taught: http://wiki.hacdc.org/index.php?title=Useful_AVR_Links

5 years ago
Wow, thanks a lot. Nice to get help from people who know what they're doing. The Instructables community is awesome!
TobiasPl5 years ago
I really like this tutorial! Very easy to follow, but I have a questions left: Lets say the sequence is BLUE BLACK RED YELLOW and RED is set to 5V, all others to 0V. Now I turn off the current and later on, I turn it on again but the IC now again starts with BLUE at 5V instead of RED. What will happen?
The Real Elliot (author)  TobiasPl5 years ago
It doesn't really matter where in the cycle you start, although the motor might turn backwards one step before it gets going in the right direction. So in your example, you stopped the motor with RED energized. If you then went back to BLACK, it would take one step backwards so that it was lined up with BLACK. At that point, you'd continue the cycle either to BLUE or RED, and that would determine the direction that the motor rotated. As for BLUE... It would be 50/50 whether it goes clockwise or counter-clockwise. Try it and see? Repeat it like 10 times or so. Regardless, it won't hurt the motor.
TurboTronix6 years ago
I want to use this setup to open and close a valve (for water current)...
The Real Elliot (author)  TurboTronix6 years ago
Are you in the US? If so, you probably want a "sprinkler valve" instead. They're like \$10-15 at Home Depot or many hardware stores.

Or a dishwasher repair place may have a similar solenoid-driven water valve for use in dishwashers.

Unless your application is very strange, buying a purpose-built solenoid valve is probably a lot easier, cheaper, and more reliable.

If your application is very strange, you may need more torque to open/close the valve than a direct-driven stepper motor can provide. You may need a gearbox.
6 years ago
I went to the hardware today (Sydney, Australia) to get a solenoid garden watering valve to use on my yacht. All seemed to be either mains power or 24 volt DC - no 12 volt available. Anypne know where I can get a 12 volt DC one please?
6 years ago
It is for a school project. I changed it a little though. Now all I need is to use your setup but with some sort of a switch that will allow me to choose the spinning direction. I tried adding a simple ON/OFF switch to one of the ATTINY2313 chip without success. I ordered the H-bridge and should be getting it shortly. Do you know by any chance how should your code look with an input?
The Real Elliot (author)  TurboTronix6 years ago
Setting up a button-press input with the AVR (or any microcontroller) is a classic problem. Basically, you can configure a pin as an input pin, and then you use the button to send either a high or low voltage to that pin.

There's some extra tricks because usually switches "bounce" back and forth between on and off as you press them down. You're gonna want to debounce the switch.

This PDF on debouncing is pretty good. And google around to find more examples.

TurboTronix6 years ago
ya i guess you are right... A selenoid would be a better idea. I saw an electrical one so basically it would be a simple ON/OFF switch rather then spin.
TurboTronix6 years ago
Yes it works but not clean. I need to get the H-bridge going... Also can you by any chance give me an example code where I'll use this setup with an input pin (i.e. a photocell which will base the rotation side of the motor based on its input)? I tried but could not get it going well.
TurboTronix6 years ago
All worked until I used the code in your stepperMotor.c Nothing happens, the motor does not run anymore...
The Real Elliot (author)  TurboTronix6 years ago
First thing to check is the signal coming out of your AVR going to the H-bridge chip or the motor. Is it giving the right pulses at the right time? If you have some LEDs around, you can hook them up to the AVR pins instead to verify that the code is doing the right thing. If it is, and you're not using an H-bridge, you may not have enough current to step the motor. (Depends on the motor brand and what load you've got attached. Try without load to get it working first.) The solution is to get an H-bridge.
xenomorph6 years ago
manuka um I beleive that he/she's using the attiny 2313 wich is \$3 at spark fun
manuka7 years ago
(removed by author or community request)
6 years ago
AVRs only cost ~\$1.50
The Real Elliot (author)  manuka7 years ago
These steppers don't end up turning out much torque -- they're limited by small coil size and etc. But they're really fun for small and light applications.

Another stepper to look at are the Japan Servo low-voltage models. For example. They're a little heavier/bigger, but offer a much smaller step size and some more torque. They also cost \$5 each, instead of \$1.

As for AVR vs Pic, it's like Coke vs Pepsi. (With the AVR playing the part of Coke, as far as I'm concerned.)
Thomas Countz7 years ago
So in building this, should I put a diode between each motor winding and the SN754410, or should I put a diode between the power supply and the 8(Vcc2) pin of the SN754410.
coolguy7 years ago
If you want a cheap solution to greatly increasing the torque and resolution, add gearing. You could probably build one of those homebuilt CNC machines with really cheap unsophisticated parts if you incorporated gearing. BTW nice tutorial. I now have a reason to play with steppers and microprocessors.
AP8 years ago
With a motor this small it may not matter, but it's generally a good idea to stick a diode betwen the motor and the rest of the electronics to block back current or give it a shunt to ground.
The Real Elliot (author)  AP8 years ago
Agreed. You get those "for free" if you go the motor-driver IC route. (Along with the extra voltage.)

That said, I would bet that back EMF is not as important for steppers as for regular DC motors because of the way they're driven. I'll do some 'scoping and get back to you on that.

And anyway, the AVRs also have limiting diodes on the pins that keep the voltage in the 0-12v range. They're not as beefy as the ones in the motor-driver chip, and can overheat if you really overdrive the pins, but for this project, they suit just fine.

For a small (50mA) motor like this, I'd not hesitate to drive it directly from AVR pins. Everything's within spec all around as far as I can see. But I'll test out the peak back-EMF under heavy load before I bet the farm on it.
The Real Elliot (author)  The Real Elliot8 years ago
Oops. I was looking again at the specs for the SN754410 chip, and I now think that the diodes in the block diagram may be smallish CMOS-protection-type diodes (like the ones in the AVR) and not proper large-current shunting diodes. The example circuit TI provides has additional, external shunt diodes in it. So AP is right -- if you care about not smoking your motor driver IC, you might want to add some more diodes to the system.
Captain Pedantic8 years ago
I have this exact motor. Figured for .99 it's a great way to learn about steppers. I haven't gotten around to playing with it yet. I did assemble the parts for their driver, though. This looks much more comprehensible. Great instructable.
lotmi1278 years ago
Ideas for stepper motor projects?
check this guy out!
http://www.taomc.com/gallery/sand.htm
 1-40 of 44 Next »