Controlling Motor Speed with PWM

Here is an illustration of how to drive a DC motor using PWM(Pulse Width Modulation). Pulse Width Modulation is a technique of driving DC motor to save power and control speed of DC motors. Instead of applying constant power to the motor, PWM applies power to the DC motor at intervals. The PWM signal is a sequence of rectangular wave of different duty cycle. The duty cycle of PWM signal controls both the speed and power applied to the DC motor.

Here Arduino is used to send PWM signal to the DC motors. The PWM signal is generated using the TimerOne library. The TimerOne library uses the Timer 1 of the Arduino/ATmega328p microcontroller. It is very easy to use and it has many useful methods. It has methods like start, pause, stop, restart, disablePwm and has methods which allows one to change the frequency and duty cycle of the PWM signal. 

arduino dc pwm speed control

Circuit Diagram

The following shows the circuit diagram of Controlling Motor Speed with PWM.

controlling motor speed with pwm

The DC motor is connected to the Arduino pin 10 via the transistor switch. Here 2N2222 NPN transistor is used as switch the controls that current flow from external 9V battery into the DC motor then to the collector and into the emitter which is grounded. When there is 0V applied to the base of the transistor,then the transistor is cutoff and there is no current flow from its collector the emitter and therefore the DC motor current path is open and the DC motor stops. The PWM signal is applied to the base of the transistor. In the circuit diagram above, a protection diode 1N4004 is connected across the DC motor. Also a 0.1uF capacitor is connected across the DC  motor. The protection diodes prevents any back emf generated by the DC motor coil due to sudden switching action into the Arduino pin 10. Thus it prevents potential damage to the Arduino pin. Such circuit is often used in handling high-current inductive Loads such as DC motor used here. Similarly the capacitor also acts as protector to the DC motor interfacing to Arduino pin since the capacitor blocks any DC signal across it. Thus wiring the motor in this way we can prevent any damage to the microcontroller.

The 10Kohm potentiometer connected to the A2 analog pin of Arduino is used for controlling the motor speed with different PWM values. By rotating the knob, we generate different voltage in the range from 0V to 5V which are converted into the range 0 to 1023 levels by the internal ADC(Analog to Digital Converter) of the Arduino. This ADC value between 0 to 1023 is used in the pwm signal generating function to generate different duty cycle and hence PWM signal.

 The push button is used to turn on or off the PWM signal on pin 10 of Arduino. 

Program Code

Below is the program code to control DC motor speed using TimerOne library PWM.

#include <TimerOne.h>

const int potPin = A2;
const int btnPin = 2;
int btnStatus = HIGH;
boolean on = false;

void setup(){
pinMode(10, OUTPUT);
pinMode(btnPin, INPUT_PULLUP);

Timer1.initialize(1000);  //1000us is 1KHz

void loop(){
  if(on == true){
      int p = analogRead(potPin);
      Timer1.pwm(10, p);

void checkPushButton(){
  //read push button state
  int btnState = digitalRead(btnPin);
  //check for button press
  if((btnState == LOW) && (btnState != btnStatus)){
  //swap on/off states
  on = !on;
  //update buttonStatus;
  btnStatus = btnState;
  //delay to cancel any debouncing faulty read

  //check for button release
  if((btnState == HIGH) && (btnState != btnStatus)){
  //updtate the pushbutton status to off
  btnStatus = btnState;
  //delay to cancel any debouncing faulty read

In the above code, we have used the TimerOne library. There are several alias names such as potPin and btnPin for the Arduino pins which are used later used in the program. The btnStatus and on are variables used for monitoring the state of the button. In the setup() function we configure the pwm pin 10 as an output. Note that only pin 9 and pin 10 can be used for TimerOne library PWM on Arduino Uno. The btnPin which is pin 2 on Arduino is configured as an input with internal pullup. The serial port setup at 9600 baud rate and this is used for debug purpose, to see whether we are receiving analog input. The TimerOne library uses an object called Timer1 and there are many methods that the object can use. Here the first method is the initialize(). Using this initialize() method we configure the period in microseconds of the PWM signal which is 1000us here. Then the stop() method is used to stop the PWM signal generation at the start of the program. In the loop() function we check the state of the push button. If the push button is pressed then the PWM signal generation is started using the start() method.If the push button is then pressed the PWM signal generation is stopped using first the stop() and then disablePwm() methods.

In this DC motor speed control with Arduino we have used TimerOne library functions but we can also use simple PWM control functions known as analogWrite() as illustrated in the tutorial DC motor control with Arduino, Transistor, Diode.

Watch the following video demonstration of controlling motor speed with PWM.

 The animation video is below.

 Other tutorials on DC motor:

- Speed and direction control of DC motor using Arduino Fast PWM

- Arduino L298N DC Motor Speed control with PWM 

- How to use L298N motor driver with Arduino

Post a Comment

Previous Post Next Post