DC Motor Control with Raspberry Pi

Published  May 13, 2016   7
Dilip Raja
DC Motor Control with Raspberry Pi

Raspberry Pi is an ARM architecture processor based board designed for electronic engineers and hobbyists. The PI is one of most trusted project development platforms out there now. With higher processor speed and 1 GB RAM, the PI can be used for many high profile projects like Image processing and Internet of Things.

For doing any of high profile projects, one need to understand the basic functions of PI. We will be covering all the basic functionalities of Raspberry Pi in these tutorials. In each tutorial we will discuss one of functions of PI. By the end of tutorial series you will be able to do high profile projects by yourself. Check these for Getting Started with Raspberry Pi and Raspberry Pi Configuration.


We have discussed LED Blinky, Button Interfacing and PWM generation in previous tutorials. In this tutorial we will Control the Speed of a DC motor using Raspberry Pi and PWM technique. PWM (Pulse Width Modulation) is a method used for getting variable voltage out of constant power source. We have discussed about PWM in the previous tutorial.


There are 40 GPIO output pins in Raspberry Pi 2. But out of 40, only 26 GPIO pins (GPIO2 to GPIO27) can be programmed. Some of these pins perform some special functions. With special GPIO put aside, we have 17 GPIO remaining. To know more about GPIO pins, go through: LED Blinking with Raspberry Pi

Raspberry Pi 2 Model B GPIO Layout

Each of these 17 GPIO pin can deliver a maximum of 15mA. And the sum of currents from all GPIO Pins cannot exceed 50mA. So we can draw a maximum of 3mA in average from each of these GPIO pins. So one should not tamper with these things unless you know what you are doing.


There are +5V (Pin 2 & 4) and +3.3V (Pin 1 & 17) power output pins on the board for connecting other modules and sensors. This power rail is connected in parallel to processor power. So drawing High current from this power rail affects the Processor. There is a fuse on the PI board which will trip once you apply high load. You can draw 100mA safely from the +3.3V rail. We are talking about this here because; we are connecting the DC motor to +3.3V. With the power limit in mind, we can only connect low power motor here, if you want to drive high power motor, consider powering it from a separate power source.


Components Required:

Here we are using Raspberry Pi 2 Model B with Raspbian Jessie OS. All the basic Hardware and Software requirements are previously discussed, you can look it up in the Raspberry Pi Introduction, other than that we need:

  • Connecting pins
  • 220Ω or 1KΩresistor (3)
  • Small DC Motor
  • Buttons (2)
  • 2N2222 Transistor
  • 1N4007 Diode
  • Capacitor- 1000uF
  • Bread Board


Circuit Explanation:

DC motor control with raspberry pi fritzing diagram

As said earlier, we cannot draw more than 15mA from any GPIO pins and DC motor draws more than 15mA, so the PWM generated by Raspberry Pi cannot be fed to the DC motor directly. So if we connect the motor directly to PI for speed control, the board might get damaged permanently.

So we are going to use an NPN transistor (2N2222) as a switching device. This transistor here drives the high power DC motor by taking PWM signal from PI. Here one should pay attention that wrongly connecting the transistor might load the board heavily.


The motor is an induction and so while switching the motor, we experience inductive spiking. This spiking will heat up the transistor heavily, so we will be using Diode (1N4007) to provide protection to transistor against Inductive Spiking.

In order to reduce the voltage fluctuations, we will be connecting a 1000uF capacitor across the power supply as shown in the Circuit Diagram.


Working Explanation:

Once everything is connected as per the circuit diagram, we can turn ON the PI to write the program in PYHTON.

We will talk about few commands which we are going to use in PYHTON program.

We are going to import GPIO file from library, below function enables us to program GPIO pins of PI. We are also renaming “GPIO” to “IO”, so in the program whenever we want to refer to GPIO pins we will use the word ‘IO’.

import RPi.GPIO as IO


Sometimes, when the GPIO pins, which we are trying to use, might be doing some other functions. In that case, we will receive warnings while executing the program. Below command tells the PI to ignore the warnings and proceed with the program.



We can refer the GPIO pins of PI, either by pin number on board or by their function number. Like ‘PIN 35’ on the board is ‘GPIO19’. So we tell here either we are going to represent the pin here by ‘35’ or ‘19’.

IO.setmode (IO.BCM)


We are setting GPIO19 (or PIN35) as output pin. We will get PWM output from this pin.



After setting the pin as output we need to setup the pin as PWM output pin,

p = IO.PWM(output channel , frequency of PWM signal)

The above command is for setting up the channel and also for setting up the frequency of the PWM signal. ‘p’ here is a variable it can be anything. We are using GPIO19 as the PWM output channel. ‘frequency of PWM signal’ has been chosen 100, as we don’t want to see LED blinking.


Below command is used to start PWM signal generation, ‘DUTYCYCLE’ is for setting the Turn On ratio, 0 means LED will be ON for 0% of time, 30 means LED will be ON for 30% of the time and 100 means completely ON.



In case the Condition in the braces is true, the statements inside the loop will be executed once. So if the GPIO pin 26 goes low, then the statements inside the IF loop will be executed once. If the GPIO pin 26 does not goes low, then the statements inside the IF loop will not be executed.

if(IO.input(26) == False):


While 1: is used for infinity loop. With this command the statements inside this loop will be executed continuously.

We have all the commands needed to achieve the speed control with this.


After writing the program and executing it, all there is left is operating the control. We have two buttons connected to PI; one for incrementing the Duty Cycle of PWM signal and other for decrementing the Duty Cycle of PWM signal. By pressing one button the, speed of DC motor increases and by pressing the other button, the speed of DC motor decreases. With this we have achieved the DC Motor Speed Control by Raspberry Pi.

Also check:


import RPi.GPIO as IO          # calling header file which helps us use GPIO’s of PI

import time                             # calling time to provide delays in program

IO.setwarnings(False)            #do not show any warnings

x=0                                         #integer for storing the duty cycle value

IO.setmode (IO.BCM)           #we are programming the GPIO by BCM pin numbers. (PIN35 as‘GPIO19’)

IO.setup(13,IO.OUT)         # initialize GPIO13 as an output.
IO.setup(19,IO.IN)             # initialize GPIO19 as an input.
IO.setup(26,IO.IN)             # initialize GPIO26 as an input.

p = IO.PWM(13,100)        #GPIO13 as PWM output, with 100Hz frequency
p.start(0)                            #generate PWM signal with 0% duty cycle

while 1:                             #execute loop forever

   p.ChangeDutyCycle(x)                 #change duty cycle for changing the brightness of LED.
      if(IO.input(26) == False):           #if button1 is pressed
             x=x+1                                 #increment x by one if x<50
             time.sleep(0.2)                   #sleep for 200ms

      if(IO.input(19) == False):         #if button2 is pressed
              x=x-1                                #decrement x by one if x>0
              time.sleep(0.2)                 #sleep for 200ms


Have any question realated to this Article?

Ask Our Community Members


Submitted by Daniel on Sat, 03/18/2017 - 09:03


Hi, can someone help me? I'm having trouble loading the code in the part of the while

Submitted by andre on Tue, 10/31/2017 - 18:47


when am compiling the code i face many errrors in it

Submitted by Zackery Painter on Sat, 12/16/2017 - 01:11


Hello, I have tested the circuit with two motors and a water pump, but the pump and motors will not run. I have changed the pin from BOARD 35 to BOARD 32 because of my current limitations. Is there a reason I might be doing this incorrectly?

Submitted by brian hurren on Tue, 09/04/2018 - 18:33


will this work on a raspberry pi 1 or 1 b+? if so what are the equivalent pins used in a 26 pin head?..thanks in advance.