28BYJ-48 5-Volt Stepper

The reason that motor is a poor performer is it has high impedance windings - typically 30 or 50 ohms. That means they are lots of turns of very fine wire. This then means they have a high inductance. The more inductance the slower the current can change when the winding drive switches. Try to switch too fast and the current no longer is responding much to the drive waveform - current is what generates the force in the motor.

The only ways round this are to use a higher drive voltage (and a current-limiting driver), or lower resistance/inductance windings.

For instance high-performance bipolar stepper motors for CNC machines are typically 0.5 to 1 ohm winding resistance, take 2 or 3A and use current-limiting (chopper) drivers from 36 to 120V supply. The winding only needs a volt or two to overcome its resistance, the rest of the power supply voltage is available to overcome inductance in the windings (to get faster switching) and back-EMF from the spinning rotor (to get faster top speeds).

Unlike standard motors, steppers have to switch the current dozens to hundreds of times faster, so inductance is a real performance limiter.

I finally dug around in the stepper library and figured out why the number of speeds is limited! It's an artifact of the way the Arduino stepper library sets motor rpm. The speed value is used to calculate the integer "step_delay", which is a delay in ms inserted between pulse trains using the delay function. If you calculate the step_delay for 500, 550, and 600 rpm, you get 3.75ms, 3.409ms, and 3.125ms. However, the arduino is doing this with integer variables, so all of them come out as 3ms, so you get the same speed for each of those settings. I guess the moral of the story is don't use the Arduino stepper library if you need a specific speed! Now I'm playing with the AccelStepper library, which looks promising so far...

MarkT - thanks for the lucid explanation of why impedance matters!

I feel like I'm starting to get a handle on how steppers work, but I'm still not clear on why the 8 step(half stepping) sequence gives better performance(speed and torque) than a 4 step sequence. ajofscott said "Terminal speed is a limitation of drive voltage, winding inductance, and rotor inertia." Are these the ONLY factors? If so, then I guess I'd have to think that the extra pulses are keeping up momentum to fight inertia. andy

Sometime you need to take a stepper motor apart and look and see how it is made, it will make more sense to you on how they operate. Although technically a type of synchronous motor, steppers are a unique animal compared to a conventional sine driven synchronous motor.

All that you said makes sense to me. You can get 35RPM by using a higher voltage with these tiny motors!

I know this is a sidestep to the topic but: does anyone know if it would help to replace the uln2003 with a uln2803?

I am looking either for wheels that fit the 28BJ stepper or hints on how to make wheels for this motor.

Any ideas? Thanks Dave

I haven’t read this entire thread but…

Is there a link to the ‘final’ code that you guys have come up with?

And I’d like to offer this for anyone interested in learning how stepper motors work. I watched it the other day and it’s well made and quite informative!

Hey Guys!

I know this thread has been quiet for a while, but I am hoping for a bit of input on a project involving some 28BYJ-48 steppers with uln2003 drivers…

The project involves driving a fairly large number of steppers (10 to 30 in groups of 4-6) at ~10-20 rpm with as much torque as the little guys can muster…in ~6 hour cycles…12V/Full Step provides the requisite torque/speed but as noted frequently in this thread, the motors get really hot really fast…

I am familiar with stepper motor drivers from my CNC hobby and have a fairly strong background in electronics…In short, I know I need the higher voltage to overcome the inductance inherent in these steppers, but I need to limit the current to keep them from heating up…This is easily achieved with a PWM chopper with current feed back, but I don’t have any desire to design/build a large number for complicated drivers…

Obviously I can use the existing code posted @ github, but I really don’t want to dedicate a large number of arduinos to achieve the goals…preferably I would like to use some ATTINY2313’s I have on hand…and this is where I need a touch of help…I have been writing AVR code in assembler since the 90s, but I have never taken the time to learn C…If someone could take just a few moments to outline how the “coolstep” portion of the code works with some pertinent details about the timing involved it would save me a ton of bench time…I suspect the “coolstep” function modifies the full or half step routines by breaking each step into pulses…that is, for instance, @ the beginning of a 1mS step the driver is on for say 400uS, then “off” for 100uS then “on” for 100uS then “off” for 200uS then “on” for 50uS then off for the final 150uS…It is also possible the code could simply turn the driver on a specific period of time, then turn it off, thus allowing the current to reach its requisite level for the step and allowing the core’s momentum to carry it through once the core has reached its saturation current…

I don’t need anyone to write the code for me, I would just love a few details about how the “coolstep” function actually works w/o having to battle my ineptness with C…

Thanks in advance.

Fish

Adafruit Small steppers are 9-12V with 16 to 1 reduction or 16.032. http://www.adafruit.com/products/918

Yes, ULN2803 will work, it has 8 drivers and can run 2 steppers. Better yet, add a PCF8574 in front and run them with I2c with only 2 pins.

I am a newly graduated ELCT. I have ordered my third component kit for the arduino and am having issues finding color code conversions. I understand US colors, but I cannot find what these wires represent: blue, pink, orange, brown, and yellow. Can someone help me before I hook this step motor to my Mega and blow it up.

Hello all,

This thread has been extremely helpful in me getting my 28BYJ-48 stepper motor running properly, so thanks.
One thing I would like to be able to check is the torque, or more exactly, check for a torque spike.

I looked at the library from sbright33 (thanks!!) located here: Stepper library for 28BYJ-48 · GitHub
I copied out the relevant section (or what I think is the relevant section):

//torque load detect code to prevent destroying motor
for(int i=0;i<steps;i++){
if(nar>=1024){ //lower for slow?
k=sum5/nar; //why not 6? div 0? fixed
if((k==last)&&(!norm)&&(millis()>5
1000)) norm=k; //since program start
if((k==last)&&(k==norm+1)) norm=k; //within 40 sec when if k>norm+0 below
//if((k==last)&&(k==norm-1)) norm=k;
digitalWrite(13,LOW);
if(!norm)digitalWrite(13,HIGH); //ON until normal is found
//10,-10 for 8v level ground
// 0,-10 for 12v >30RPM only
if(((k>norm+20)&&norm)||((k<norm-20)&&norm)){ //0,-10 can change 2B less sensitive with high load
digitalWrite(13,HIGH);
//will never print past 1 min
//Serial.println();Serial.print(millis()/1000/60);Serial.print(" Min “);Serial.print(nalarm+1);Serial.println(” count");
if(millis()>long(40)*1000){ off(); while(1);} //infinite loop
if(nalarm++>10){ off(); while(1);} //can change 10
} //if load
last=k;
sum=nar=0;
} //if 1024
ccw();
//if(i%16==0)Serial.println(float(i+1)*360/64/8);
//can detect individual outliers here
nar+=8; for(int j=0;j<8;j++) sum+=ar[j];
} //for

How does this check for the torque? I am at a bit of a loss. Thanks in advance if you can enlighten me!

Yes, I wrote that code years ago. Yes, you found the correct section. Yes, I can remember exactly how to connect it, since it's so easy. Yes, it works perfect in my application to detect a change in torque. But I cannot explain the overall flow, and it takes me awhile to understand a specific line, even with my cryptic comments. They made sense at the time? Think of this code as an example to base your code on. It should work for many situations, by only changing a few constants.

Here's how to connect the hardware: Connect a wire from any of the motor coils, to an analog pin. I guess that AnalogRead is done in an earlier section. Search for sum=.

// This will show that the motor advances a little more than one revolution with 2048 (4-step sequence) steps.
// This means that the mechanical gear ratio is NOT exactly 64:1 but more like 63.68395.:1.

// Import needed libraries.
#include <Stepper.h>

// Number of steps per revolution of INTERNAL motor in 4-step mode.
#define STEPS_PER_MOTOR_REVOLUTION 4

// Steps internal motor have to take, so OUTPUT shaft turns one full revolution.
// 2048 would be the right number if the gear ratio was exactly 64:1.
// 2041 was the closest one i can come up, output shaft goes allmost full revolution.
// 2024 goes just over one revolution, a bit more over than 2041 leaves short.
// At 700 full revolutions it was ~1mm short from the start point at distance of ~10mm from the shaft.
#define STEPS_PER_OUTPUT_REVOLUTION 2041

// In1, In2, In3, In4  and then the pins entered here in the sequence is
// 1-3-2-4 for proper sequencing
Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 23, 27, 25, 29);

// Declare Variables
int  RunStepper;
int  TotalRevolutions = 0;

void setup() {
 Serial.begin(9600);
 RunStepper  =  STEPS_PER_OUTPUT_REVOLUTION;  // Rotate CW 1 turn
 small_stepper.setSpeed(6000);  // Fastest my motor would start with this sketch was somewhere 7500+ but the torgue starts to weaken after 5000+
}

void loop() {
 small_stepper.step(RunStepper);
 TotalRevolutions += 0;
 Serial.print("Total Revolutions = ");  
 Serial.println(TotalRevolutions,DEC);
 delay(200);
}

Please i need a Code to make something similar to this video https://www.youtube.com/watch?v=epSI04xXR7s

Hi sbright33,

Looking through your ‘stepper2’ sketch there seems to be an error (or omission) in your direction loop - see void movetodir(boolean bcw, int steppos) sub-routine.

void movetodir(boolean bcw, int steppos){
//absolute position you decide direction
steppos&=4095;
movecnt&=4095; //this will not happen in move() can be >4096 or <0
while(movecnt!=steppos) {
move(bcw);
movecnt&=4095;

Compiling this section returns an error - move was not declared in this scope. Perhaps a int is required here???

Hi sbright33,

I d/loaded your stepper2 sketch and extracted the code "//code decides which direction to move is shortest" .

I then added an array with 8 various degrees and ran the sketch.

It worked BUT IN REVERSE! If I asked for 120° the stepper went to 240°. If I asked for 40° the stepper went to 320°, etc., the CW and CCW seemed to be about faced. Also, I found that this sketch only found the 'long way' to the next angle.

Maybe somewhere there's a error in the sketch or I missed something?

I made a short movie on this but I don't yet know how to post it.

Cheers Old_Goat

Can I just clarify... did you get 35rpm out of the 28BYJ-48 ??

Hello, and what an informative thread!
I have the 28BYJ-48 and struggeling with heat.

With no load on the stepper it gets realy hot after only 20-30 seconds with this code:

/* YourDuino.com Example Software Sketch
   Small Stepper Motor and Driver V1.3 11/30/2013
   http://arduino-direct.com/sunshop/index.php?l=product_detail&p=126
   Shows 4-step sequence, Then 1/2 turn and back different speeds
   terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <Stepper.h>

/*-----( Declare Constants, Pin Numbers )-----*/
//---( Number of steps per revolution of INTERNAL motor in 4-step mode )---
#define STEPS_PER_MOTOR_REVOLUTION 32   

//---( Steps per OUTPUT SHAFT of gear reduction )---
#define STEPS_PER_OUTPUT_REVOLUTION 32 * 64  //2048  

/*-----( Declare objects )-----*/
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to

//The pin connections need to be 4 pins connected
// to Motor Driver In1, In2, In3, In4  and then the pins entered
// here in the sequence 1-3-2-4 for proper sequencing
Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11);


/*-----( Declare Variables )-----*/
int  Steps2Take;

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
// Nothing  (Stepper Library sets pins as outputs)
}/*--(end setup )---*/

void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
 // small_stepper.setSpeed(1);   // SLOWLY Show the 4 step sequence 
 // Steps2Take  =  400;  // Rotate CW
 // small_stepper.step(Steps2Take);
 // delay(2000);

//  Steps2Take  =  STEPS_PER_OUTPUT_REVOLUTION / 2;  // Rotate CW 1/2 turn
//  small_stepper.setSpeed(100);   
//  small_stepper.step(Steps2Take);
//  delay(1000);
  
  Steps2Take  =  - STEPS_PER_OUTPUT_REVOLUTION / 2;  // Rotate CCW 1/2 turn  
  small_stepper.setSpeed(700);  // 700 a good max speed??
  small_stepper.step(Steps2Take);
  delay(2000);

}/* --(end main loop )-- */

/* ( THE END ) */

I looked at the github page mentioned many times but the code gets to complex for me.

I am going to use my stepper to pull some curtains, but with the heat its building up at the moment i think there might be something wrong with the code i am using.

I am using the nano and the stepper driver that came with the motor with 12V powersupply.

Hi. The ones i've seen myself are 5 volt motors. Are you sure yours is a 12 volt motor, does it say so on its label ?

Oh ****!

The stepper came with a bundled driverboard that said 5-12v so i just assumed that the motor could handle it. But you are correct, thanks for the tip and i will look more closely at voltages with my next komponents :)

Lucky for me the motor seems to have survived the high voltage.