# How to control speed of 28BYJ-48 stepper motor without using library?

Iam using 28byj-48 stepper motor and I want to know how to control its speed without using any library. I got to know that we need to add delays in between steps but I don't know how much delay I need to add and how delay effects the rpm. It is very much helpful if anyone suggest me how to do this.

• start by examining the blinkWithoutDelay example sketch that is included with the Arduino IDE ... it will teach you how to execute events at intervals without blocking the rest of the code Jan 18, 2021 at 3:15

A stepper motor always needs a driver. As the ULN2003 (or similar) driver is normally shipped together with the 28byj-48 motor, I will assume, that you have this driver.

The ULN2003 has 6 pins:

• Vcc and ground need to be connected to your power source. Note, that it is risky to connect Vcc to the 5V pin of the Arduino. While that might work, when there is no load on the motor, a loaded stepper motor can draw rather high currents. Letting these current run through the Arduino might fry the voltage regulator or the power switching diode. High currents should always flow past the Arduino, not through it.

• The other 4 pins (which are marked as IN1 to IN4 on my ULN2003 driver board) are for controlling the phases. You need to connect these 4 pins to 4 individual digital outputs on your Arduino. As these are the phases of the stepper motor, you need to activate them in the correct order. You have this pattern

``````  1000
0100
0010
0001
``````

for full steps, and this pattern

``````  1000
1100
0100
0110
0010
0011
0001
1001
``````

for half steps. Each digit of each number represents the status of the corresponding phase; 1 means activated/HIGH, 0 means deactivated/LOW. To move the stepper motor forward, you move in the list of phases down. To move backwards, you move up in the list.

When using a stepper motor, the speed is determined by the number of steps per time interval. Let's assume, we want to use `delay()`, which is really easy, though not recommended (see explanation below), we can do steps and `delay()` inbetween:

``````void loop(){
step();
delay(10);
}
``````

This code would do a step and then delay for 10ms. Thus we have about 1 step every 10ms. With `64*64=4096` steps per revolution (the motor itself seems to have 64 steps; additionally there is a gear with ratio 64 mounted on it; this might be different for you) we get a full revolution every 4.096s. When you use half the `delay()`, the speed will be double: with 5ms delay we get a full rotation every 2.048s. So you can use the `delay()` to set the speed of the motor.

Now we need the `step()` function, that I used above. There are multiple ways of writing this in code. I would propose to put the pins and phases into arrays and iterate through them with a static variable, which holds the current position in our phase pattern. Something like this:

``````//in global scope defining the pins for the phases
int stepper_pins[4] = {2, 3, 4, 5};

void step(bool forward){
const uint8_t phase_pattern[][4] = {
{1,0,0,0},
{0,1,0,0},
...
};
static uint8_t current_step = 0;
if(forward){
current_step = (current_step + 1) % 4;
} else {
current_step = (current_step - 1) % 4;
}
for(uint8_t i=0;i<4;i++){
digitalWrite(stepper_pins[i], phase_pattern[current_step][i]);
}
}
``````

We hold the phase pattern in a 2-dimensional array. The variable `current_step` is declared `static`, so it will keeps its value between the executions of the function. Then - depending on the parameter `forward` - we increment or decrement the current step and take that value modulo 4 (the number of phase patterns). That ensures, that `current_step` stays in the index range of our phase pattern array and will wrap around from the end of the pattern to the start and vice versa. After that, we loop through the 4 stepper pins and set them according to the current element in the `phase_pattern` array. You can easily adept that code for half steps.

Note, that this code is totally untested. Also this can be reached with way less code (at least for full steps), but I think this code is better understandable.

Now: Why not using `delay()`? This function will block the execution of other code. In that time the Arduino is just fiddling thumbs. In general that is considered bad practice. It is good, when you only need that one functionality and no responsiveness. But lets assume, you want to add a button, so that the motor reacts to your button presses. Long `delay()` calls will impact the responsiveness of your code. So instead you could use a non-blocking coding style. In the Arduino world this is easily done with the `millis()` function, which returns the number of milliseconds since startup and thus acts like a clock. Refer to the `BlinkWithoutDelay` example, that comes with the Arduino IDE, and to the many tutorials on the web, that you can find with search terms like "Arduino millis tutorial" or something like that.

EDIT:

how your code controlling the motor speed?

The `delay()` call is determining the motor speed. If you want to change the speed, you need to change the value of the delay. You didn't mention any input device, so I just leave the speed constant. But of course you can define a variable for the delay and change that delay based on some input device. How exactly that is done depends on your requirements, mainly what type of input you want to use.

if we didn't specify any delays in between steps, will it spin at its max rpm?

When you don't use any delay, then most likely your code will run too fast for the motor. The driver will set the motor phases very very fast. So fast, that the motor cannot follow that (because it has a specific inertia). (Much like the wheels of your car can loose the grip on the street and spin without moving the car, the stator of the motor can loose the magnetic grip on the rotor, which leads to further rotating phases, but a rotor, that is standing still) So you reach the maximum speed before that and it depends on the motor, the driver, how much load is on the motors and how much current your power source can give you (I once tried to provide 3 of these motors with a 1A power supply, but they moved very weak, until I upgraded to a bigger power supply, that can provide about 5A, I think). You need to test yourself, how fast you can drive your motors. So try to lower the delays step by step, until the motor cannot move in your setup anymore. Then you have the minimum delay, and the maximum speed.

Note: The `delay()` function won't be accurate for very low delays in the single digit milliseconds. In that case you might wanna use `delayMicroseconds()`, which is more accurate in that range and also can get in you in the microsecond range.

• Your explanation is wonderful,but how your code controlling the motor speed Jan 19, 2021 at 6:02
• And one more question,if we didn't specify any delays in between steps, will it spin at its max rpm? Jan 19, 2021 at 6:06
• @Akashbabutammali I added explanations for both questions in my answer. Jan 19, 2021 at 7:31