28BYJ-48 5-Volt Stepper

I couldn't fit cw and ccw() in the 10k code box limits of the forum. It is included in the previous version, as well as the original version. 400us works if you ramp up the speed first. Or just call degrpm(35rpm) it does that for you. All the relevant speeds are listed in the comments. I don't see the advantage of PORTB? DigitalWrite is only microseconds apart which is not significant compared to 400 or 1200us. Can you go faster than me? My sketch is compatible with most Arduinos having the relevant ports which you specify at the top.

PORTB's advantage is probably moot, since we are throwing in delays anyway. The only advantage is to eliminate those microseconds of delay when setting two ports simultaneously. However, the difference is not trivial - is about 95 times faster, according to John Boxall's blog: http://tronixstuff.wordpress.com/tag/portb/

However, using PORTx commands introduce a lot of risk, reduces portability and readability and should be avoided unless truly needed.

I just wanted to see if I could get it working and I will NOT be using PORTx for a stepper application.

My point being that sequential turn off of motor windings is the same as a movement command, ergo there is a probability of either a backstep or a forward step as you release control.

As you move from 1 step to the next you are only changing 1 winding at a time. So if it begins to move before the 4th winding is not changed, all the better! Then there is a delay of 1000x. When you come to an immediate stop, there is no changes to worry about. When you turn off the power in my code, the order could be important. I have not handled this case yet. You can choose which order to do this in. If 1-4 then it could in theory move backward. If 4-1 then maybe forward. It could not move forward if there is some torque against it. With the gear ratio of 64:1 nor will it move backwards. Even if it did move a step 1/11th degree, you're coming to a stop anyway. When you start up again it will be as if it didn't slip backwards. It should not effect torque or top speed. Agree?

For those of you interested in greater technical detail on controlling a stepper motor, take a look at Atmel Corp's Application Note titled "AVR446: Linear speed control of stepper motor". Lots of math there for you number crunchers. it is an PDF located at: http://www.atmel.com/dyn/resources/prod_documents/doc8017.pdf

I was able to get the Arduino stepper library to perform better for the 28BYJ-48, but, of course, the Arduino stepper library is limited and does not support acceleration/deceleration. Here is working Arduino stepper library code for the 28BYJ-48:

/*
  Derived from YourDuino.com Example Software Sketch
   Small Stepper Motor and Driver, by:
   terry@yourduino.com
*/

#include <Stepper.h>
//declare variables for the motor pins
int motorPin1 = 8;	// Blue   - 28BYJ48 pin 1
int motorPin2 = 9;	// Pink   - 28BYJ48 pin 2
int motorPin3 = 10;	// Yellow - 28BYJ48 pin 3
int motorPin4 = 11;	// Orange - 28BYJ48 pin 4
                        // Red    - 28BYJ48 pin 5 (VCC)

#define STEPS  64   //Number of steps per revolution

//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 of 28BYJ48
Stepper small_stepper(STEPS, motorPin1, motorPin3, motorPin2, motorPin4);

int  Steps2Take;

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  small_stepper.setSpeed(200);
}/*--(end setup )---*/

void loop()
{
  // sweep 1 turn each way
  small_stepper.setSpeed(200);   
  Steps2Take  =  2048;  // Rotate CW
  small_stepper.step(Steps2Take);
  delay(2000);
  
  small_stepper.setSpeed(200);  // 200 a good max speed??
  Steps2Take  =  -2048;  // Rotate CCW
  small_stepper.step(Steps2Take);
  delay(2000);

}

Most recently, I have been experimenting with the powerful accelstepper library (http://www.open.com.au/mikem/arduino/AccelStepper). It supports acceleration/deceleration and much more. I posted a short demo video of a 28BYJ-48 being driven by the accelstepper library in full-step mode. It actually is more impressive in half-step mode but I didn’t make a video of that. The video is at: http://youtu.be/1F3240hCHE4

The sketch used in the video is shown below:

// accellsteppertest.ino
// Runs one stepper forwards and backwards, accelerating and decelerating
// at the limits. Derived from example code by Mike McCauley
// Set for 28BYJ-48 stepper

#include <AccelStepper.h>

#define FULLSTEP 4
#define HALFSTEP 8

//declare variables for the motor pins
int motorPin1 = 8;	// Blue   - 28BYJ48 pin 1
int motorPin2 = 9;	// Pink   - 28BYJ48 pin 2
int motorPin3 = 10;	// Yellow - 28BYJ48 pin 3
int motorPin4 = 11;	// Orange - 28BYJ48 pin 4
                        // Red    - 28BYJ48 pin 5 (VCC)

// The sequence 1-3-2-4 required for proper sequencing of 28BYJ48
AccelStepper stepper2(FULLSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

void setup()
{    
  stepper2.setMaxSpeed(1000.0);
  stepper2.setAcceleration(50.0);
  stepper2.setSpeed(200);
  stepper2.moveTo(2048);
}

void loop()
{
  //Change direction at the limits
  if (stepper2.distanceToGo() == 0) {
    stepper2.moveTo(-stepper2.currentPosition());
  }
  stepper2.run();
}

The accelstepper library has many useful features. Check it out!

I find that library to be difficult to understand for a beginner. Maybe I'm biased because I wrote mine. I've added some of the useful features mine was missing. I can detect the torque load or change!

Hello,

I just bought the 28BYJ48 stepper motor and will try these codes.
Just so that I will not burn my Arduino Nano, how is the wiring done?
I have also ULN2003 driver.

Thanks

The wiring is listed in the sketch. I also used a nano as well as a mini-pro. The power pins on ULN2003 driver board, if yours is the same as mine, are poorly marked. Ground goes to the pin marked with a very litttle “-” and 5-volts Vcc is connected to the pin marked “+”. For the ULN2003 driver board’s LEDs to light the jumper must be in place - it is unmarked and is adjacent to the power pins.

From the sketch

int motorPin1 = 8; // Blue - 28BYJ48 pin 1
int motorPin2 = 9; // Pink - 28BYJ48 pin 2
int motorPin3 = 10; // Yellow - 28BYJ48 pin 3
int motorPin4 = 11; // Orange - 28BYJ48 pin 4
// Red - 28BYJ48 pin 5 (VCC)

#define STEPS 64 //Number of steps per revolution

//The pin connections need to be 4 pins connected
// to Motor Driver In1, In2, In3, In4 …

Thank you selem,

did you take the +5V from Nano or separate powersupply?

The nano's supply is inadequate for the stepper. I used a separate 5v supply and just tied the grounds.

@sbright33: Hi! Do you have a new version of your code? Can you explain better your idea about the angle for motors x, y?

J

My newer library is on another thread here. Many improvements. More coming. PWM to make it smoother. Non-blocking to free up the processor for other tasks. Higher voltage to increase performance without getting hot...

I'd like to move 2 motors called x,y at the same time. Pointing a laser for example. While the laser is on when you go from 0,0 to 10,10 it should move at a 45 degree angle. That's simple just move 1x,1y,1x,1y... until you get to 10. Or move them simultaneously. Not so simple when you're going to 75,80 or an arbitrary x,y. There must be an easy algorithm? I don't know it. Anyone?

sbright33: There must be an easy algorithm? I don't know it. Anyone?

http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Fairly simple for 2D stuff (there are tons of implementations out there - it is used for line drawing in 2D graphics); not sure what it would take to add a 3rd stepper (or more). You might also look into the few g-code interpreter implementations for the Arduino that are out there...

Found this; the links still work:

http://www.gamedev.net/topic/536735-bresenham-2d-3d-4d-6d/

BTW - that 6D one looks like it could be easily generalized to N-degrees...

Your first link looks really simple! I like simple. Only 10 lines of code in the loop. Thanks! 2D is enough.

did that algorithm work for pointing at x,y?

Yes, in my simple experiments. Only 10 lines of code it is easy to follow. I've been sidetracked by a few other projects hope to get back to this. The whole point of Bresenham is to make a straight line while moving to arbitrary x,y.

sbright33: My newer library is on another thread here. Many improvements. More coming. PWM to make it smoother. Non-blocking to free up the processor for other tasks. Higher voltage to increase performance without getting hot...

Hi sbright33, many thanks for your library. But I cannot find this newer version. Would you mind sharing the link?

I'm glad I found this, because with the standard library 28BYJ was getting very hot an not really behaving well!

I had trouble cobbling the code together from the various bits in this thread. Is there any particular reason to be pasting inline rather than just use a standard code-bin like pastebin or gist? If it helps anyone else, I put the latest version I could find on https://gist.github.com/4149982

The advantage of using something like Gist is that you can update the one file whenever you like and the forum link will always be up to date then.

Please don't take this as any criticism of your excellent library - it's just a newbie asking a newbie question!