# Controlling speed of DC Motors using Arduino

This is part 4 of my “Building Robots using Arduino” tutorial series, explaining how you can create robots using Arduino.

In this article we will see how we can control the speed of the DC motor using Arduino.

## Recap

Last week, I explained how we can control the direction of DC motors using the H-Bridge L293D IC.

This week we will see how we can control the speed of the motor as well using the IC. Also I will talk about how we can encapsulate the entire logic into an Arduino Library.

## Analog Write

Before we go ahead, we need to know about `analogWrite` function in Arduino.

In Arduino, the `analogWrite` function allows you to generate a PWM wave in a pin. If you have tried out the LED fade example in Arduino, then you already know how to use it. If not, then checkout the PWM tutorial from Arduino reference.

This function takes a value between 0 and 255 and doesn’t work on all pins in Arduino. In Arduino Uno, it works on pins 3, 5, 6, 9, 10 and 11.

## Controlling Speed of DC Motors

To control the speed of the motor, all we need to do is to replace `digitalWrite` function on L293D enable pins to `analogWrite`. The speed of the motor depends on value that was passed to the `analogWrite` function. Remember the value can be between 0 and 255. If you pass 0, then the motor will stop and if you pass 255 then it will run at full speed. If you pass a value between 1 and 254, then the speed of the motor will vary accordingly.

### Circuit

You can just reuse the same circuit from last week.

Remember, I asked you to connect the enable pins of H-bridge to pins 10 and 11 of Arduino. This is because pins 10 and 11 are PWM pins.

### Code

You just have to replace the function `digitalWrite` with `analogWrite` in last weeks code. The value you pass to `analogWrite` function will decide the speed of the motor.

Here is the modified sketch that you can use to change the direction as well as the speed of the DC motors.

## Library

I have encapsulated the logic of changing directions of DC motors in an Arduino library called DCMotorBot. The library is available in github from where you can download it.

Instead of setting the pins individually, you can call the following directions to change the direction of the motors. Check out the examples sketches inside the `/examples` folder of the library.

• Start
• Stop
• MoveUp
• MoveDown
• TurnLeft
• TurnRight

Note: I am still working on adding support for changing the speed(pwm) as well.

## What’s next

Next week we will see how we can put together all we have learned so far and build a complete bot. It’s going to be existing, so don’t miss it 😉

Till then, happy roboting 😉

## 59 thoughts on “Controlling speed of DC Motors using Arduino”

1. rosamunda

Hi there!
I´m following your instructions to the letter (instead of a battery I´m using a wall adapter), but the motors run very, very slowly (as if they didn´t have enough power). Why could that be?
Thanks!

1. Sudar Post author

Are you using analogWrite() or digitalWrite() to the enable the enable pin?

Also what is the output voltage of the power supply you are using?

1. rosamundaRosamunda

This is my adapter that I connect to my Arduino Mega board: http://postimg.org/image/ug87tg2w1/
bout analogWrite vs. digitalWrite, I´ve tried with your code:
analogWrite(E1, 153);
digitalWrite(E2, 255);
And then, as it wasn´t working for me, I´ve tried both cases analogWrite, but still.

I´ve also tried attaching 3 AA batteries to the board, and a 9v battery aswell, as your example does, and in this case the wheels moved, but barely.

Rosamunda

1. Sudar Post author

Okay let’s debug it one at a time. Try the following combination.

– Use digitalWrite(pin, HIGH);
– Use a 9V battery as input to motor

Also what happens when you connect the motor directly to the batter? How fast is it rotating?

2. Davew

As with the last tutorial, the has a SERIOUS wiring error, which may be the cause of Rosamnda’s problem.

The positive and negative of the battery are both connected to the same row of the Breadboard, shorting it out!!

I highly recommend using only the top row for Positive and bottom row for Negative, keeping the power ‘rails’ distinctly separate.

Dave

3. Andrew

Hi, great tutorial! Although I’m slightly confused why you sometimes use analogWrite() for E1/E2 and other times you use digitalWrite()?

Also, can I update the E1/E2 values during operation like this to alternate fast and slow?

analogWrite(E1, 153);
delay(1000);
analogWrite(E1, 255);
delay(1000);
analogWrite(E1, 153);

Thank you!

1. chrsman63

Hi
if the Arduini is away from my pc, I would like to add two buttons (one to increase and the other to decrease) the values and so i can set the set point.
Probably i have to connect the one pin of the button to the ground and the other to the V+ throw a resistor 10K. So when i press the button the input is pulled down to ground

Any help to the code?

4. Leelesh

Can a single arduino Atmega 328 board be used to control 3 different dc motors with different speeds at a time. If possible, how ? Please reply soon.
If possible, which chips are required and how to connect it with breadboard…?

1. vrushabh Ganvir

Sir, I m doing project of controlling speed of dc motor using arduino by recognizing sound signal. So please tell me which sensor are used to convert sound signal to arduino recognizable language…..and also tell that how power circuit is to be design…….

2. satyam

yes, it is possible, because arduino uno contain 3 pwm, you can control speed by varying the potentiometer at analog channel.

5. john

I am.desperate for help. i built a robot with ardunio my dc motors will not move. im.going crazy. if you can help email.me and ill explain

6. fyp

is it possible to halt the motors by adding command digitalWrite(I1,LOW)
and digitalWrite(I2,LOW) instead of (E1,LOW)) & (E2,LOW)?

7. joel

Love the tutorial but I’m having a problem controlling the speed. I have the wiring all the same and changed the code so i only have one motor. When i analog write between 0-255 I’m hardly hearing a change in speed and it’s not stopping when set to 0? Any thoughts?

Here is my code
#define MotorSpeed 10 // Enable Pin for motor 1
#define I1 8 // Control pin 1 for motor 1
#define I2 9 // Control pin 2 for motor 1

void setup() {

pinMode(MotorSpeed, OUTPUT);
pinMode(I1, OUTPUT);
pinMode(I2, OUTPUT);
}

void loop() {

analogWrite(MotorSpeed, 250);
digitalWrite(I1, HIGH);
digitalWrite(I2, LOW);

delay(2000);

// change speed

analogWrite(MotorSpeed, 150);

delay(2000);

analogWrite(MotorSpeed, 20);

delay(2000);

analogWrite(MotorSpeed, 0);

delay(2000);
}

8. Gero

Thanks for the taking the time to make tutorials like this. Great Job.The previous one worked like a charm. With the code in this one I’m confused. You have only 1 analogWrite after void loop for half speed.
After that it’s digitalWrite(E2, 255). Same after delay(200). I haven’t tried but I guess for the speeds there should be 4 analogWrite in the code.
Looking forward to your other tutorials.

Kind regards,
Gero

1. Sudar Post author

Yes, you are correct. The code is wrong. It should use analogWrite instead of digitalWrite.

I have corrected it now.

9. zeevy

Hi, i am trying to control the speed of the toy car motor.
one like this

but there is no change in speed of the motor always runs at constant speed.
also motor starts only if the analog value is more than or equal to 130,
analogWrite(E1, 130) starts the motor and runs at full speed ( no change in speed even for 255)
any value below 130 motor is not rotating,

10. Ishani

The tutorial was very helpful. Thank you.
Do you have library which includes even speed controlling(PWM) command?!

Regards.
Ish

11. Amit

Hi Sudar,
my project is to generate random noise and apply this generated noise to dc motor such that the duty cycle of the motor is varied in order to vary the speed of the motor with this random noise. could I get any help for this issue ? I am very desperate to achieve this.
Thanks

12. Haren

Hello sir, I am using a motor driver module of L293D, the thing is when I connect motors to bridge and turn it on, the wheels rotate very slow even on digitalWrite(high) the speed is very very slow. How can I increase the speed?

13. Pingback: Lab 1 | Introduction to Robotics

14. Cassandra

Hello!
For my science fair project I’m creating a robot to cut crust off a sandwich with a turning table and a blade controlled by the Arduino UNO R3, two 12VDC motors w/encoders, a breadboard, male to male jumper wires, a 12V adapter, and an Arduino R3 Motor Shield.
I’d appreciate some people I could bounce ideas off of since this is my very first robotics project.
Please help soon as I only have till January 14th to have a complete robot that functions properly, plus research and a way to prove to the judges that I created it on my own.
I have absolutely no idea on how to program or set up an Arduino, so if you wish to help, please don’t be frustrated by my “not knowing anything”.
Thank you!

15. PRAKHAR

IF I WANT TO CONTROL THE SPPED AND DIRECTION OF ARDUINO MANUALLY i.e WHENEVER I WANT I CAN INCREASE THE SPEED AND CHANGE THE DIRECTION. SPEED AND DIRECTION SHOULD NOT BE CHANGED AT REGULAR INTERVALS , LIKE IN THIS YOU HAVE DONE.WHAT SHOULD BE THE CODE FOR THIS WHAT EXTRA DO WE NEED? CAN WE USE POTENTIOMETER FOR THIS CAUSE?

16. M Arslan

Hellow, nice tutorial
I am making a robot for my FYP ………. and i want to control the speed of 3 motors at 3 legs of a pipe inspection robot 120 degree a part ……… i have heard that all motors do not run at same speed because of their some inner problem ……… so i will have to design a PID ……….. so i want to ask if this code is enough
or need some changing?

17. Samer Najia

I noticed this post as part of a plan to run a simple robot with a rotating platform on its back. Basically, you have 2 motors controlling direction (fwd, back, right and left) using skid steering, like a tank, and a simple pan tilt camera mechanism on its back (2 more motors). Based on what I am seeing, I would need a second L293D and make use of pins 2 through 7 wired up the same way (making use of the remaining 3 PWM pins) and coded the same way and coded much the same way as you have here. Is that correct?

1. Sudar Post author

Sorry Samer. I am not able to understand the circuit that you are explaining. Can you post the schematics of the circuit?

1. Samer Najia

I am proposing adding 2 more motors and using a second bridge chip. You still have 3 PWM pins on the Arduino, so conceivably I can do this by replicating your connections to the one bridge IC and adding a second L293D.

1. Samer Najia

Not yet. I also would have to allocate certain letters to the app button or use another app to send commands to the other 2 motors. But, I will.

18. Hallur

Hi, thanks for your very good tutorial.
I have gotten my motors to rotate as it says in the program, but both motors aren’t getting the same input voltage all the time, which makes the AGV NOT drive in a straight line. Any thoughts or solutions what I can do :)?

19. Jaya Surya

i want completely stop the dc motor after my conduction is complete. So what can i do??

20. Wyatt

Hi Sudar,
I am working on an Arduino RC Car at my school, and have been this circuit. It worked with the DC motors, but we want to use higher voltage motors. We tried the code and circuit that you have. We are using a motor driver, but it recently died on me, and we ordered another. Also, we can run one of our motors at a time on a nine volt, but we don’t want to burn out the Arduino by using too high of a voltage battery. Is there any way to up the voltage of a battery used in the Arduino without destroying it? Any suggestions help.

21. Mohanraja

Hi Sudar,
I have computer science background, I don’t know much about electronics, so my questions might be naive.

In your diagram, you only show Arudino, The board, IC, Motor, battery, but in your youtube video, I see some extra components, (looks like capacitor & resistor), I am not sure why you used that, could you explain?

1. Sudar Post author

Hello Mohanraja,

To get the basic circuit to work you don’t need the capacitor or resistors. Just use the components that I have shown in diagram.

22. Sarah

Hi Sudar,
Thanks for posting this, I’ve got it all working well. I’d like to introduce a switch so that when the motor shaft turns 360 degrees exactly, the switch is activated and the code starts again from the beginning. I want the motor to do exactly the same movement i.e. slow for 180 and fast for 180 in the exact same position over and over. I’ve added a switch and guessed at some code (below) but, as expected, it isn’t working! I wonder if you could pass an eye over it for me. I’m not sure how to tell the control pins 1 and 2 (I’m only using one motor) to stop altogether, or how to have switch reset the code. 🙁

I’ll buy you many beers if you ever find yourself in Edinburgh. 🙂

const int enablePin = 10;
const int controlPin1 = 8; // Control pin 1 for motor 1
const int controlPin2 = 9; // Control pin 2 for motor 1
const int switchPin = 2;
int switchState = 0;

void setup() {

pinMode(enablePin, OUTPUT);
pinMode(controlPin1, OUTPUT);
pinMode(controlPin2, OUTPUT);
pinMode(switchPin, INPUT);
}

void loop() {

analogWrite(enablePin, 50); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(30);

analogWrite(enablePin, 100); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(30);

analogWrite(enablePin, 150); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(30);

analogWrite(enablePin, 200); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(30);

analogWrite(enablePin, 255); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(566);

analogWrite(enablePin, 200); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(30);

analogWrite(enablePin, 150); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(30);

analogWrite(enablePin, 100); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(30);

analogWrite(enablePin, 50); // Run in half speed

digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, LOW);

delay(566);

if (switchState == HIGH) {
digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, HIGH);
}
else {
digitalWrite(controlPin1, LOW);
digitalWrite(controlPin2, LOW);
}
}

1. Sudar Post author

This type of things becomes difficult to do in a DC motor. I would recommend that you use a stepper motor for this.

23. Pathfinder

I have successfully made L293D driver and RC-CAR Controlled through Android but i want to ask one thing.What will happens if i connect L293D pin 1,16,9 direct to Arduino 5v pin.I found this in internet but cant figure out. I think it will not be PWM and cannot controll the speed of motor.

How about using 2 L293D IC and drive 4 DC motors. Is it possible? Will it overheats?
Plz suggest.