Controlling a stepper motor with Raspberry Pi Zero W

Last Updated on

In my projects with Raspberry PI I always has been fashinated by the infinite fields of application for this fantastic board. One of my preferred is robotics, and this requires the control of arms, wheels and gears by using motors.

Stepper motors are the most common motor type in commerce for these projects, because of their precision.


In this article I’ll show you you to control a simple stepper motor with a Raspberry Pi Zero W.

What we need

This time things are a little more complex than other previous articles, because we need to perform some cabling tasks that require attention.

For this tutorial I use the following:

  • Raspberry Pi Zero W kit – including SD card, power supply and (the most important) a GPIO header
  • Stepper motor – I use Elegoo 28BYJ-48
  • Motor driver – I use Elegoo ULN2003
  • dupont wiring (in my configuration, I will use 4x female-female + 2x female-male)

Before starting (additional HW)…

Before starting, let me expose some considerations on hardware.

Raspberry Pi Zero W kit comes with a GPIO header not connected to the board (why? I really don’t know…). So you have 2 options:

  1. You can use the one coming with the kit, but you will need to solder it. There are many tutorials over internet (you can just google “raspberry pi zero w gpio soldering”) and it is quite simple if you have a little of soldering manuality.
  2. You can buy an alternative solderless holder, which is easier to attach (you can google “raspberry pi zero w solderless gpio hammer header”). In this case you will need to add it in your shopping list

About the choice of Elegoo parts, I choose them because they are cheap and enoght for my very first experiment. I must state that these motors are a little slow for robotics projects, but they appears to be precise. They come in a kit including also some female-male dupont cables, but if you don’t have a breadboard you will need to buy one or to buy other female-female dupont cables.

Regarding the power supply, it is possible to power the motor directly from RPI GPIOs (there are some pins cabled to ground and some other cabled to 5V). The second option is to use an external power supply which can erogate 5V. The second option is mine one. Built this with an old electrical screwdriver, detaching the battery box and identifying positive and negative connectors. I used also 4x rechargable AA battery providing 1,2V each one and connected it with 2 male-female dupont cables (from male side):

RPI motor battery pack
RPI motor battery wiring

Wiring schema

The following picture shows how connections have been cabled in my lab:

RPI stepper motor schema

The stepper motor comes with a pre-installed connector that you can directly connect to ULN2003 controller. All other connection are made with dupont cables.

To identify GPIO in Raspberry Pi Zero, refer to the following picture:

RPI Zero W GPIO pinout

This numbers both GPIO IDs and phisical positions. Using RPI.GPIO python libary requires the use of GPIO ID instead of phisical position. The picture above shows also pins usable to supply power (5V and 3V3) and ground.

We use:

  • GPIO 17 (connected to ULN2003 IN1)
  • GPIO 27 (connected to ULN2003 IN2)
  • GPIO 22 (connected to ULN2003 IN3)
  • GPIO 23 (connected to ULN2003 IN4)

so having the following:

RPI motor GPIO wiring

If you want to power the motor with RPI power PINs, you will connect one of Ground pins to ULN2003 negative pin and one of 5V pins to ULN2003 positive pin.

In the following picture, the ULN2003 wiring:

RPI motor driver wiring

…and the overall picture:

RPI motor lab overview

Preparing the test

We’ll start from a clean raspbian stretch lite installation (see here for steps).

Once connected via ssh to your RPI, update first of all:

sudo apt-get update

Install RPi.GPIO:

sudo apt-get install rpi.gpio

Now we need a Python script to control the stepper motor with our Raspberry Pi. For this purpose, I prepared a simple python script. You can just download it and align the script to yuor wiring configuration:

Logic Behing Python Script

This script is based on producer step sequence schema:

SEQ1SEQ2SEQ3SEQ4SEQ5SEQ6SEQ7SEQ8
IN411000001
IN301110000
IN200011100
IN100000111

Each sequence step (from 1 to 8) is a GPIOs status to set from RPI to ULN2003.

You can image this table as a composition of 8 arrays (each one with 4 digits). This can be also seen as an ordered composition of 2 kind of arrays (0,0,0,1 and 0,0,1,1) alternated and rotating by one digit. In python, array rotation can be implemented with the simple line:

rotated_array = array[n:]+arr[:n]

where “n” is the number of rotation steps. To rotate by 1 step, this string becomes :

rotated_array = array[1:]+arr[:1]

Because arrays are composed by 4 digit, opposite rotation can be achieved with a 3 step rotation:

rotated_array = array[3:]+arr[:3]

So, first download the script in your RPI:

wget https://peppe8o.com/wp-content/uploads/2020/02/stepper.py

now edit:

nano stepper.py

If your cabling is different from mine, identify the row where chan_list is defined. The original one appears as the following (including comments):

chan_list = [17,27,22,23] # GPIO ports to use

You can also edit delay var from current “.001” value to higher one. The higher the value the lower the rotation.

delay=.01 # delay between each sequence step

Now you can easily test your lab by launching a simple command:

python stepper.py

and you should see the motor rotating.

For opposite rotation, as previously described edit:

arrOUT = arr1[1:]+arr1[:1]

to:

 arrOUT = arr1[3:]+arr1[:3] 

Finally, you can find step motor on common e-commerce sites or with the following link for best prices I’ve found around the web:

AliExpress.com Product – 5pcs New Brand ULN2003 28BYJ-48 5V Reduction Step Motor Gear Stepper Motor 4 Phase Step Motor for arduino 5pcs Motor +5pcs Board

Amazon – ELEGOO 5 Sets 28BYJ-48 ULN2003 5V Stepper Motor + ULN2003 Driver Board for Arduino

Enjoy!