Stepper Motor Basics

Hey folks. I've recently got two 28BYJ-48 5V 4 Phase stepper motors with ULN2003 driver boards. The specs on the motor i'm a little confised about are as follows:

Step angle: 5.625 x 1/64.
Reduction ratio: 1/64.

After looking around on the net I've come to the conclusion that it has 64 steps/revolution, which is geared down at a ratio of 1:64. So based on this, the motor should have 64 x 64 steps/revolution, which is 4096 steps/revolution. I wrote a very basic piece of code using the Stepper library just to get a feel for how this thing works:

#include <Stepper.h>

int motorSteps=4096;
Stepper test(motorSteps,8,9,10,11);


void setup() {
  // put your setup code here, to run once:
  
}

void loop() {
  // put your main code here, to run repeatedly: 
  test.setSpeed(180);
  test.step(4096);
  delay(3000);
}

This code didn't do anything. So, I changed the value of motorSteps from 4096 to 64 (to ignore the gear ratio), and the motor spun, but with the parameter in step set to 4096, it rotated two full revolutions. So I'm a little confused how the specs for this motor work with the Stepper library. Should I be using the ungeared motorStep value (it wouldn't work the other way anyhow...), and why would test.step(4096) spin it around twice? Any light that could be shed on this would be appreciated. Thanks.

AFAIK the steps/rev is only used to set the speed.

Are you using half steps or full steps? The datasheet I found gives instructions to drive 1 or 2 phases (half steps) so it seems they mean 5.625/64 degree in half step mode and it's quite normal you're getting 2 revolutions if you're using full steps.

It's not the first time I hear about problems when using a high value in the stepper initialization, I'll have a look at the library.

Try lower speeds, 180 rotations per minutes @4096 steps/rotations gives 12KHz pulses, that may be too fast for your stuff, on an ebay page I found, it's written to start at maximum 500Hz and don't increase past 900Hz.
That's quite low, it means you should use 1/10 rotation per second or 6 rpm, maybe 12rpm will work if the load is light.

That stepper is for low speed and light duty, it doesn't turn very fast from 5V (chopper drive from a high voltage supply
would work faster, but the mechanics aren't really designed for such use).

Also the gear ratio is not exactly 64:1, its 25792:405 or about 63.684 : 1

I've tried it using 2038 for my motorSteps value, and reducing the RPMs to 12. Still no luck. Thje driver board LEDs are lighting up and I can feel the motor vibrating, but it's just not turning. I know the boards and motors are good, cause they work when I use 64 as the motorSteps value....

You need AccelStepper to get to the full speed (steppers are both velocity and acceleration limited).

Vibration can also be a symptom of one phase being unconnected.

I prefer to see what's happening to the stepper motor as I run it, accelerate it, or just step it a step at a time:

/*Stepper Test Drive specifically for the 28BYJ-48 with gear reduction drive

  Note:  There is slop in the gear drive and it takes a dozen or more half-steps before 
  moving the output shaft when reversing directions.  For precision it is best to always
  approach settings from the same direction.
  
  This program allows for no acceleration, it jumps to maximum speed or dead stop.  If
  pause is much below 3000,(3 milliseconds), it will lose some steps on start and stop.
  This is in the neighborhood of 5 rpm maximum speed.*/

int i = 0;
int j = 0;
int oneRev = 4076;                         // Total number of half-steps per revolution
                                           //   or whatever your gear train is.
int pause = 3000;                          // Pause between steps in microseconds.
const int pin[] = {5,4,2,5,3,2,4,3};       // A progressive array of pin numbers to drive motor.
const int pinState[] = {HIGH,LOW,HIGH,LOW,HIGH,LOW,HIGH,LOW}; 
void setup()
  {
    for (j = 1; j < 5; j++)                // Set the digital pins as outputs.
      {
        pinMode(pin[j], OUTPUT);           // Set up 4 digital pins motor.
      } 
  }

void loop ()
  {
    for (i = 0; i < oneRev; i++)
      {
        motorStepForward();
        delayMicroseconds(pause);
      }
    delay (2000);                          // Pause after one revolution.
    for (i = 0; i < oneRev; i++)
      {
        motorStepReverse();
        delayMicroseconds(pause);
      }
    delay (2000);                          // Pause after one revolution.
  }
void motorStepForward()
  {
    digitalWrite(pin[j],pinState[j]);
    j++;                                   // Keeps permutating the pins in forward direction.
    if(j > 7)                              // Reset j if it has exceeded array size.
      {
        j = 0;
      }
  }
void motorStepReverse()
  {
    j--;                                   // Keeps permutating the pins in reverse direction.
    if(j < 0)                              // Reset j if it has exceeded array size.
      {
        j = 7;
      }
      digitalWrite(pin[j],pinState[j]);
  }

Luckily I'm using it in a clock so that it turns only in a "clockwise" direction and gear train slop is not an issue.

Dave

Thanks for the info guys. Dave, I've set up a little piece of code using your functions, and I'm having a separate issue. The code I wrote uses an accelerometer to drive a stepper motor (it will eventually drive 2... but for now, just 1) and looks like this:

int xIn=A4;
int yIn=A3;
int xbl;
int ybl;

int i = 0;
int j = 0;
int oneRev = 4076;                         // Total number of half-steps per revolution
                                           //   or whatever your gear train is.
int pause = 3000;                          // Pause between steps in microseconds.
const int pin[] = {5,4,2,5,3,2,4,3};       // A progressive array of pin numbers to drive motor.
const int pinState[] = {HIGH,LOW,HIGH,LOW,HIGH,LOW,HIGH,LOW}; 



void setup()
{
  for (j = 1; j < 5; j++)                // Set the digital pins as outputs.
      {
      pinMode(pin[j], OUTPUT);           // Set up 4 digital pins motor.
      } 
  for (j = 8; j < 12; j++)                // Set the digital pins as outputs. **DISREGARD THIS LOOP FOR NOW**
      {                                                                                    //**WILL BE USED FOR SECOND MOTOR**
        pinMode(pin[j], OUTPUT);           // Set up 4 digital pins motor.
      } 
  Serial.begin(9600);
  pinMode(xIn, INPUT);       
  pinMode(yIn, INPUT);
  xbl = analogRead(xIn);
  ybl = analogRead(yIn);

}

void loop()
{

  int xPos=analogRead(xIn);
  int yPos=analogRead(yIn);
  int offset=50;

Serial.print("xbl ");
  Serial.print(xbl);
  Serial.print(" X: ");  
  Serial.print(xPos);
  Serial.print("      ybl ");
  Serial.print(ybl);
  Serial.print(" Y: ");
  Serial.println(yPos);
  
  if (xPos>xbl+offset)//LEFT
  {
    Serial.print("L ");
    motorStepReverseL();
    
  }
  if (xPos<xbl-offset)//RIGHT
  {
    Serial.print("R ");
    motorStepForwardL();
  }
  if (yPos>ybl+offset)//DOWN
  {
    Serial.print("D ");
    motorStepReverseL();
  }
  if (yPos<ybl-offset)//UP
  {
    Serial.print("U ");
    motorStepForwardL();
  }

}
void motorStepForwardL()
  {
    digitalWrite(pin[j],pinState[j]);
    j++;                                   // Keeps permutating the pins in forward direction.
    if(j > 7)                              // Reset j if it has exceeded array size.
      {
        j = 0;
      }
  }
void motorStepReverseL()
  {
    j--;                                   // Keeps permutating the pins in reverse direction.
    if(j < 0)                              // Reset j if it has exceeded array size.
      {
        j = 7;
      }
      digitalWrite(pin[j],pinState[j]);
  }

Without the motor functions included, the accelerometer portion of the code works fine, and I can see my xPos, yPos xbl, ybl, and U, D L, R in the serial monitor. As soon as I add the motorStepForward or motorStepReverse, I get crazy values from the accelerometer and it no longer works. I had an issue like this in the past which was caused by having the SL pin on the accelerometer hooked up to a digital out, but the current set up has it connected to a straight 5VDC pin. Any ideas what would cause this interference?

Mine goes 30RPM using 12v
http://arduino.cc/forum/index.php/topic,89159.0.html
http://arduino.cc/forum/index.php/topic,85335.0.html

Some motors have 4096 steps. That makes the code much easier because it is an integer.

The model 28 BYJ-48 comes in both 5V and 12V models, but from everything I see there doesn't seem to be any difference between the two. Are they interchangeable? Can I hook my 5V model up to a 12V source and get more speed out of it?

The only difference is the coil resistance. You can hook a 5v motor to a 12v supply only if you use code similar to mine! If you don't change the code it will overheat in a few minutes. More speed and more torque.

sbright33 I was looking at those two links you posted, and it says that you've attached a zip file, but I can't seem to find it.... Also any thoughts on what might cause the interference when I try to use the motors in conjunction with an accellerometer (see above)?

Here's the code:

No thoughts today sorry!

So I've been digging through this code a little, and it work pretty well. Is there any way to control two motors at once using your functions?

First learn to use 1 pair of 4 non-blocking functions I included. Can you find them? Slow or fast pair?

Once you get that working, duplicate the pair, changing the global variable names and pin constants.

Let me know if you need more help...