# Using cheap 28BYJ-48 stepper with ULM2003 drivers and AVR/Arduino

30 Apr 2019 - tsp
Last update 06 Feb 2021

Just a word of precaution first: Do not expect these steppers to perform with a high torque (they can deliver about $34.3 \text{mNm}$) or high speed (due to their builtin gearing they can deliver a maximum speed of approxiamtely $25$ revolutions per minute (i.e. it takes about 2.5 seconds for the motor to turn by an angle of $2\pi$.

## What is the 28BYJ-48

The 28BYJ-48 is a pretty cheap and readily available (for the hobbyist; note: affilate link) unipolar geared stepper motor. The stepper embedded inside the assembly has the standard wiring used for unipolar steppers. One lead is used as common ground wheras the other 4 leads connect to the coils. As usual direction of the connections are reversed between coils 1 and 3 as well as 2 and 4 to provide torque into the same rotational direction. The output shaft of the steper is reduced (by a plastic gear) with an approximate ratio of 1:64. Note that this is really only approximated and the gearing adds a bit of backlash to the whole assembly. The stepper itself should provide a stride angle of $5.625^\circ$ (i.e. $0.1964 \text{rad}$). After reduction that would result in an angle of about $0.0879^\circ$ (i.e. $0.0015 \text{rad}$).

The operation conditions are specified at an operating point of $5\text{V}$ and an DC resistance of $50\Omega\pm 7\%$. This would be equal to a maximum current of $100 \text{mA}$. The steppers also operate at a voltage of about $12\text{V}$ without any current limiting (i.e. $240\text{mA}$) but when using higher voltages one should use current limiting as usual.

## And the ULM2003

The ULN2003 stepper driver is in fact a darlington array containing seven darlington circuits that can be controlled independently of each other (the free wheeling diodes are common for all channels). It can handle an output voltage of up to $50\text{V}$ and an continuous collector current of $500 \text{mA}$. Inputs can handle up to $30 \text{V}$ and draw an current of maximum $1.25\text{mA}$. The minimum high voltage for the ULN2003 depends on the collector current but can be roughly estimated to be at around $3\text{V}$. The on- and off delay times (important for maximum stepper frequency) are at a maximum of $1 \mu\text{s}$.

The ULM2003 can be used to drive any load starting from steppers up to LED strips as long as one does not exceed the maximum ratings. To use it as a stepper driver one has to provide the correct sequence to power the coils inside the stepper motor.

It’s often available bundeled together with the above mentioned geared steppers (note: this is an affilate link).

## A word of caution

Be warned, that the leads from this series of unipolar steppers are not colored the same way in every batch of motors. Even the assignment of leads to the connector (if preassembled) may not be the same every time. The easiest way to solve that problem in a hobby setting is - make sure that the center tap (normally the red wire in the center of the cable assembly) connects to your common ground or power supply. The others can be detected by trying all permutations (be sure to check if the motor runs smoothly in both directions! Exchanging some of the wires may work for one direction but not the other). If the common ground is assigned to the right pin all other changes can be made in software by simply changing pin assignments.

When you see too many vibrations even at moderate speeds or whenever your motor does only turn into one direction - or you see non reverseable movement when doing the same amount of steps in both directions (at lower speeds) you should re-check your pin assignments.

Another indicator for invalid pin assignments is - when you’re using one of the available breakout boards that display the current pin status via status LEDs - an status LED that’s not as bright as the others (due to the occuring short). In this case also don’t panic and re-check your pin assignments.

## Controlling the stepper with an AVR

The control algorithm that is used to control a stepper has already been described in a previous article on linear stepper motor control. To realize this on an AVR one can use two approaches. If one really just wants to control a single stepper in a predetermined fashion one can use loops and delays (this is a good method during testing) or use one of the available timers as counting source. The latter one is of course the only way when controlling multiple steppers at the same time of when doing other things in parallel.

To provide stepping or microstepping one can use one of two patterns in which the arrays are switched. The idea is to generate the rotating field using software by energizing the coils one after each other.

On can either power up each coil after each other:

Step Coil 1 Coil 2 Coil 3 Coil 4
0 +
1 +
2 +
3 +

A better way is to introduce microstepping the most basic and simple way:

Step Coil 1 Coil 2 Coil 3 Coil 4
0 +
1 + +
2 +
3 + +
4 +
5 + +
6 +
7 + +

To realize that one can simply build oneself a step table:

static int stepTable[8*4] = {
1, 0, 0, 0,
1, 1, 0, 0,
0, 1, 0, 0,
0, 1, 1, 0,
0, 0, 1, 0,
0, 0, 1, 1,
0, 0, 0, 1,
1, 0, 0, 1
};


and use that step table to execute the steps:

static int currentStep = 0;

static void doStepFwd() {
currentStep = (currentStep + 1) & 0x07;

digitalWrite(STEPPERPIN1, stepTable[currentStep << 2 + 0]);
digitalWrite(STEPPERPIN2, stepTable[currentStep << 2 + 1]);
digitalWrite(STEPPERPIN3, stepTable[currentStep << 2 + 2]);
digitalWrite(STEPPERPIN4, stepTable[currentStep << 2 + 3]);
}

static void doStepBack() {
currentStep = (currentStep - 1) & 0x07;

digitalWrite(STEPPERPIN1, stepTable[currentStep << 2 + 0]);
digitalWrite(STEPPERPIN2, stepTable[currentStep << 2 + 1]);
digitalWrite(STEPPERPIN3, stepTable[currentStep << 2 + 2]);
digitalWrite(STEPPERPIN4, stepTable[currentStep << 2 + 3]);
}


The step generation has - as previously mentioned - already been covered in a previous article on linear stepper motor control.