Raspberry Pi Stepper Motor Control with L293D / ULN2003A

25. January 2017

Stepper motors are ideal for applications where it is necessary to know the angle of rotation, for example in robotics. Unlike a normal motor, stepper motors can control the steps individually and can therefore detect the exact position.
For easy controlling such a motor, a driver IC like the L293D or the ULN2003 are needed. The use of both drivers is shown in this tutorial.


The more common of those two is the ULN2003, this is also often included on driver boards with the 28BYJ48th There is a voltage of 5V and 12V possible.

The L293D however opens the possibility to connect an external power source, whereby for example a higher amperage (which in some motors is necessary) can be connected.



  • Stepper motor, e.g. the 28BYJ-48 with ULN2003 driver board (US / UK)
  • L293D Driver IC (US / UK)
  • alternatively, if no L293D is wanted: ULN2003 Darlington Array IC (US / UK)
  • Jumper wire (US / UK)
  • maybe an external power source, for example batteries

Of course, you can use any other stepper motor, but it is important to identify the possibly different wire colors when you connect them (see data sheet).

Those colors reflect in my case to the 28BYJ-48 (data sheet):

If you so choose a different motor, consider the case that the colors may be different. Important are the positions and steps.


Wiring L293D

If you have a motor with ULN2003 driver board or the ULN2003 driver IC, you can skip this step.

The data sheet shows that an external power source is possible. The structure is thus as follows:

It is important to say that if you use an external power source, the + 5V from Raspberry Pi must also be connected to the bottom left pin of the IC (pin 8), in addition to Pin 16.

If the motor amperage required more than the Raspberry can deliver, you must have an external power source (a fixed current source is better than batteries). The pre-resistor is also specified in the data sheet. Pay attention that you have enough voltage and amperage, because that is the most common cause, why the engine later is not working as it should. With the 28BYJ-48 however, this is not the case.


Wiring ULN2003

Unlike the L293D, here are only 5V or 12V input voltage allowed (data sheet). Since the Raspberry Pi only has 5V supplies, we can also only use stepper motors that require a maximum of 5V.




When using the 28BYJ48, the sequence is as follows. If you are using a different motor, you have to adjust the sequence corresponding to your data sheet.
So we create a script:

sudo nano stepper.py

and add the following script:

Then just save with CTRL+O and CTRL+X and quit. You can start it with:

sudo python stepper.py

With setStep(0,0,0,0) you can set the stepper to idle, because otherwise power is consumed all the time (by the electromagnets in the motor).

Regard that if you choose a high delay value (per step), the motor is moving very slowly (e.g. with a 100ms delay one full turn would already take 51.2 seconds, because the engine has a total of 512 steps. Too small delay values may, however, have the opposite effect, so that the signals are transmitted too quickly and causing the motor to just “stuttering”. If you want a faster engine, choose a model with a larger step angle).

11 Responses

  1. filename = motor2003.py
    Every time the same error
    Is there an solution for this problem


    File “motor2003.py”, line 55
    backwards(int(delay) / 1000.0, int(steps))import RPi.GPIO as GPIO
    SyntaxError: invalid syntax

  2. Hey,
    Thanks for the tutorial!
    I bought the 28BYJ-48 and set it up. However when I execute the script the motor is only humming and getting warm but it’s not working 🙁
    Btw what is it with this undefined “enable_pin” variable in the script? I commented it out.

    • Hi Gerald,
      the enable pin is only for some other motos (as you can use the tutorial for any stepper motor by changing the step sequence). But if you use the 28BYJ-48 you can ignore this pin.
      Did you check your wiring? If the wires are not connected in the right order the motor cannot rotate and only hums.

  3. Hi, thanks for sharing. I also have a problem. Terminal texts as “NameError: name ‘enable_pin’ is not defined”. Any solutions please ?

  4. Hi,
    I got your setup to work. Your diagram was esp. helpful. So then I tried to program a simple stopwatch hand. The problem is that from your .py (and my stepper) a complete rotation seems to be about 130 steps (but not exactly). How do you change the step angle so I can accurately do 360 degrees?

    • Hi,
      it depends on your motor: Mine had 512*8 steps, so a complete rotation has to rotate 4096 times. If you are using another motor then first see how many steps the motor has (datasheet).
      Regards, Felix

  5. Re Felix: As far as I can see the 28BYJ–48 motor comes in only 1 flavor. The datasheet states that the “stride angle” is 5.625 degrees / 64 — a nasty fraction of a degree. The comment in the code above: “# adjust if needed” is interesting but not useful.

    • @Haight : 360 degrees / 5.625 degrees = 64. Since it also takes 64 steps to go 5.625 degrees, that means 1 rotation is 64 * 64 = 4096 steps. It may be a seemingly strange angle, but it is a nice power of two (2^12) in steps.


Leave a Comment

Your email address will not be published.

Subscribe to Raspberry Pi Tutorials and don't miss any new Tutorial!