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 😉
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!
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?
Thanks for your reply!
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.
Again, thanks for your advice and insight!
Rosamunda
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?
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
Damn! Didn’t realize the error and thanks for pointing it out. Will change the wiring diagram.
Sir can u please send me the re-corrections of the breadboard diagram?
Just updated the circuit in both the blog posts. Once again thanks for pointing them out.
sir, where is the updated circuit?can you please post it to me.
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!
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?
I never u an anduino before the question is .is pwm in anduino enable by defult?
Yes, it is enabled by default. But you have to use analogWrite() instead of digitalWrite().
More details at http://arduino.cc/en/Tutorial/PWM
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…?
Yes, but you would need an additional IC like H-Bridge.
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…….
yes, it is possible, because arduino uno contain 3 pwm, you can control speed by varying the potentiometer at analog channel.
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
jmaderer1@gmail
Can you post your code in a github gist and then post the link here?
is it possible to halt the motors by adding command digitalWrite(I1,LOW)
and digitalWrite(I2,LOW) instead of (E1,LOW)) & (E2,LOW)?
I am not sure if I understand your question. Can you explain it a bit more?
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?
Thanks in advance.
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);
}
Thanks anyway! fixed my problem. 🙂
Glad to know that you got it fixed yourself 🙂
how u fixed that??/can u please give me the updated final code and the apps??
Same, I can’t get the PWM to affect the speed. 0 does not stop the motor.
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
Yes, you are correct. The code is wrong. It should use analogWrite instead of digitalWrite.
I have corrected it now.
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,
http://www.electrorobotech.electrogroups.org/wp-content/uploads/2014/06/toy-dc-motor.jpg
The tutorial was very helpful. Thank you.
Do you have library which includes even speed controlling(PWM) command?!
Regards.
Ish
Nice to know that you found the tutorial helpful.
At this point, I don’t have a library.
Nice tutorial, thanks bro
nice article, visit this website to know more about this.
visit this website for a simple code and circuit
I need help in coding the arduino using fuzzy logic for speed control of DC motor. please do write back.
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
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?
Try to use a separate power supply. Arduino may not be able to provide the necessary current for the motor.
Pingback: Lab 1 | Introduction to Robotics
Pingback: #9 Controlling the tractor’s motor using L293D H-bridge | Arduino Dad
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!
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?
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?
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?
Sorry Samer. I am not able to understand the circuit that you are explaining. Can you post the schematics of the circuit?
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.
I think it should work. Have you tried it?
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.
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 :)?
thanks in advance 🙂
i want completely stop the dc motor after my conduction is complete. So what can i do??
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.
Not sure if I fully understand your question. Arduino doesn’t have a battery inside it.
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?
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.
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);
switchState = digitalRead(switchPin);
if (switchState == HIGH) {
digitalWrite(controlPin1, HIGH);
digitalWrite(controlPin2, HIGH);
}
else {
digitalWrite(controlPin1, LOW);
digitalWrite(controlPin2, LOW);
}
}
This type of things becomes difficult to do in a DC motor. I would recommend that you use a stepper motor for this.
the app?
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.
I don’t think Arduino will be able to provide enough current that is required by the motors.
sir..will this cose work..its urgent..its an automatic braking system using sensors..braking in the sense..the speed will be reduced to zero
#define trigPin 13
#define echoPin 14
#define e1 10 // Enable Pin for motor 1
#define t1 8 // Control pin 1 for motor 1
#define t2 9 // Control pin 2 for motor 1
#define led 3
#define led2 5
#define buzzer 4
float duration,distance;
#include
void setup() {
Serial.begin(9600);
pinMode(trigPin,OUTPUT);
pinMode(echoPin,INPUT);
pinMode(e1, OUTPUT);
pinMode(t1, OUTPUT);
pinMode(t2, OUTPUT);
}
void loop() {
digitalWrite(e1, HIGH);
digitalWrite(t1, HIGH);
digitalWrite(t2, LOW);
digitalWrite(trigPin,LOW);
delayMicroseconds(2);
digitalWrite(trigPin,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin,LOW);
duration=pulseIn(echoPin,HIGH);
distance=(duration/2)*0.0343;
Serial.print(“Distance= “);
if(distance>=400||distance<=2)
{
Serial.println("out of range");
}
else if(distance<=100&&distance<=50)
{
digitalWrite(led,HIGH);
delay(1000);
analogWrite(e1,157);
digitalWrite(t1,HIGH);
digitalWrite(t2,LOW);
delay(500);
}
else if(distance=25)
{
digitalWrite(buzzer,HIGH);
delay(100);
analogWrite(e1,56);
digitalWrite(t1,HIGH);
digitalWrite(t2,LOW);
}
else if(distance=10)
{
digitalWrite(led2,HIGH);
delay(100);
analogWrite(e1,0);
}
else if(distance=100)
{ digitalWrite(e1, HIGH);
digitalWrite(t1, HIGH);
digitalWrite(t2, LOW);
}
delay(500);
}
How can I drive 4 dc motor at same speed ?please provide me solution.arduino drive it?
I made a circuit with L293D, motor and arduino but the speed of one motor is little bit faster than the other
why it come like this?
I’m brand new to this world of micro controllers and sketches, but with enough digging, I’ve been able to find answers to most of my questions. One question I haven’t found info for, is my confusion over the PWM control wiring and code for certain motor control breakout boards. Some seem to require 3 input lines from the microcontroller for each DC motor, one line for enable/disable and the other two lines for set the direction (Clockwise/Anti-clockwise) of the motors. I have a DROK® Smart Car DC Dual Motor Driver PWM Module Circuit Board H-bridge MOSFET Driver, from Amazon I would like to use. It only has has 2 input lines per motor. They are PWM1 + DIR1 and PWM2 + DIR2 .
Then they provide the following info.Control Signal:
The motor is transferred: DIR = 1 PWM = PWM
Motor Reverse: DIR = 0 PWM = PWM
Parking brake: DIR = X PWM = 0
Motor and power connections
Then the power of positive POWER, GND for negative one. Two motors were connected MOTOR1, MOTOR2
Thats all I can find. Can someone help me understand why some need 3, while others only require 2, and what if any changes are needed in a sketch between the two types.
I need to start, brake, and or Stop, vary the speed, and pattern of two 24V DC motors soon, and I’m taking too long to figure it out!
Sample code would be fantastic.
Thanks
Please, i have a problem with my “L293D” and “DC / Optical Encoder motor”.
this IC generates a voltage about 3.9 v even without external supply and even in non turning state (enable grounded).
i think, i don’t need any other component like diodes, because this circuit has his own integrated diodes.
can u help me ?
I’m using LM298N and a 10 rpm dc motor for my egg tray turner working fine, but it requires 60 min interval between clock wise and anti clock wise turns,please help.
void setup()
{
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9, OUTPUT);
}
void loop()
{
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(9,10);
delay (4000);
digitalWrite(8, LOW);
digitalWrite(7, HIGH);
delay(4000);
}
Improving my understanding… the solution is…. added delay in between digitalWrite High and low!
digitalWrite(8, HIGH);
delay (17000);
digitalWrite(7, LOW);
digitalWrite(9,10);
delay (4000);
digitalWrite(8, LOW);
delay (27000);
digitalWrite(7, HIGH);
delay(4000);
thank you all..
thank u Suresh
hello ppl, I really need some help regarding speed control of a motor using arduino uno. I’m currently doing a project on gesture control robot which uses an accelerometer, 2 arduino unos, rf pair and motor driver module. So far I’ve achieved what I desired. But my next challenge is to control the speed of the robocar using hand gestures via accelerometor. Is there anyone who can help me with this???
if i understood your question: i used an optical encoder integrated with the motor to see its velocity, from that we can compare it with the desired velocity, and apply the correspondent regulation (PID), but actually i used MBED not ARDUINO.
hello. thanx fr the tutorial. can u kindly teach me how to realise this code in MATLAB please?????????
No sirven sus códigos alv ppcdsalvc
Thank you so much for this tutorial. I have just learned how to make the Robot go full speed.
I was wondering if you can program it to go a specific distance -say 5 feet, then turn left etc.
Could I possibly use a switch button to make it go and stop? If so how? Thanks again.
Hey have you found a way to add the button?
thank you!! Is there any way to add a servo or a button?
Hey
I have 2 12V DC Gearmotors. I’m trying to let them spin all the way until I hit a stop switch. I have two relays to reverse the movement.
anyway you recommend any similar written program please, I’m very new to Arduino.
Thank you
Thank you for Controlling DC motor Tutorial, helped me a lot. Still, I am facing some trouble’s using the code and the setup as per yours(ditto). I was able to achieve pwm from 65+ to 255(analogWrite(60)-analogWrite(255)) but unable to achieve pwm of DC motor less than value 65(analogWrite(60) or analogWrite(30). Even, analogWrite(0) doesn’t work, to achieve it i used “analogWrite(300)”. Thanks once again for your effort.
NVM, solved using a softPwm library. https://www.arduinolibraries.info/libraries/soft-pwm
The bend winding machines are winds the circles in like way applications like transformer, inductors, motor and spreads. The structure of winding machine is articulating by multifaceted nature of circles, square of the material determined nature, versatilities of machine, intervention of head or robotization, creation level and other budgetary concerns.Choke winding
sir,i need an urgent update regarding this question..its my final year project..will this code work?i have applied the above mentioned principle for automatic braking using sensors
code-:
#define trigPin 13
#define echoPin 14
#define e1 10 // Enable Pin for motor 1
#define t1 8 // Control pin 1 for motor 1
#define t2 9 // Control pin 2 for motor 1
#define led 3
#define led2 5
#define buzzer 4
float duration,distance;
#include
void setup() {
Serial.begin(9600);
pinMode(trigPin,OUTPUT);
pinMode(echoPin,INPUT);
pinMode(e1, OUTPUT);
pinMode(t1, OUTPUT);
pinMode(t2, OUTPUT);
}
void loop() {
digitalWrite(e1, HIGH);
digitalWrite(t1, HIGH);
digitalWrite(t2, LOW);
digitalWrite(trigPin,LOW);
delayMicroseconds(2);
digitalWrite(trigPin,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin,LOW);
duration=pulseIn(echoPin,HIGH);
distance=(duration/2)*0.0343;
Serial.print(“Distance= “);
if(distance>=400||distance<=2)
{
Serial.println("out of range");
}
else if(distance<=100&&distance<=50)
{
digitalWrite(led,HIGH);
delay(1000);
analogWrite(e1,157);
digitalWrite(t1,HIGH);
digitalWrite(t2,LOW);
delay(500);
}
else if(distance=25)
{
digitalWrite(buzzer,HIGH);
delay(100);
analogWrite(e1,56);
digitalWrite(t1,HIGH);
digitalWrite(t2,LOW);
}
else if(distance=10)
{
digitalWrite(led2,HIGH);
delay(100);
analogWrite(e1,0);
}
else if(distance=100)
{ digitalWrite(e1, HIGH);
digitalWrite(t1, HIGH);
digitalWrite(t2, LOW);
}
delay(500);
}