Hello guys. In the field of robotics, we use different types of motors – DC motors (mostly geared), servo motors, stepper motors, etc. In this post we will discuss how to control DC Motors (geared or gearless) using a MCU.
Most DC motors are normally very easy to reverse. By simply changing the polarity of the DC input, the direction of the drive shaft reverses. This property makes DC motors very popular among enthusiast people involved in robotics. In most cases, DC geared motors are used.
The changeover process (reverse in direction due to reverse in polarity) can be achieved via a simple changeover switch (DPDT switch) or for a remote or electronic control, via a suitable relay. For more information on changeover process, view this page. However, when we use MCU in our circuit, we don’t need a relay. The necessary control signals will be generated by the MCU. This signal will be passed to a Motor Driver IC, which in turn drives the motors. The following block diagram shows this process.
Why use a Motor Driver?
Block Diagram Explained
In the above block diagram, we can see that there is a microcontroller (MCU). Now, this MCU may/may not take in inputs (inputs as in from sensors, other digital inputs, etc). Next, as per our programming, the MCU will generate control signals. Please note that the MCU will generate signals in form of HIGH (Vcc = 5v) or LOW (zero). But this voltage is insufficient to drive a motor. That’s why we need to use a Motor Driver.
A motor driver always has a battery input Vs (which depends upon the rating of the motor). In simple terms, what a motor driver does is that it directs the Vs voltage to the motors connected (or in fact, the output pins) to it. Thus, the motors behave as per the control signals generated using the MCU with the excitation from the external battery voltage.
The most commonly used motor driver is the L293D. I have also found some people who look for its replacement. For them, SN754410 should do. Both are pin-to-pin similar to each other, quad Half-H-Bridge Motor Drivers, capable of driving high voltage motors using TTL 5V logic levels. They can drive 4.5V up to 36V at 1A continuous output current!
L293D Connections
L293D is a 16 pin IC which comes in a DIP Package. Its pin configuration is shown below.
Now let’s have a look at its connections for bidirectional motor control.
In this way, we can have bidirectional control over two motor. Let’s have a summary of connections:
- There are two enable (EN) pins, pin 1 and pin 9. Pin 1 EN enables the motor M1 whereas pin 9 EN enables motor M2.
- Connect motor M1 across OUTPUT1 and OUTPUT2 i.e. across pins 3 and 6.
- Connect motor M2 across OUTPUT3 and OUTPUT4 i.e. across pins 11 and 14.
- The inputs for motor M1 is given across INPUT1 and INPUT2 i.e. across pins 2 and 7.
- The inputs for motor M2 is given across INPUT3 and INPUT4 i.e. across pins 10 and 15.
- Connect GROUND pins 4, 5, 12 and 13 to ground.
- Connect pin 16 to Vcc (=5V) and pin 8 to Vs (battery, 4.5V~36V).
As per the diagram, the inputs of motor M1 are M1-A and M1-B, whereas inputs of motor M2 are M2-A and M2-B.
Now consider the following cases for motor M1:
- M1-A = 1 and M1-B = 0 → M1 moves clockwise (say). Then
- M1-A = 0 and M1-B = 1 → M1 moves counter-clockwise.
- M1-A = 0 and M1-B = 0 → M1 stops.
- M1-A = 1 and M1-B = 1 → M1 stops.
Similar cases can arise for motor M2:
- M2-A = 1 and M2-B = 0 → M2 moves clockwise (say). Then
- M2-A = 0 and M2-B = 1 → M2 moves counter-clockwise.
- M2-A = 0 and M2-B = 0 → M2 stops.
- M2-A = 1 and M2-B = 1 → M2 stops.
Suppose if you need to control only one motor at a time, you need to enable that particular EN pin. Enabling both pins at the same time will drain your battery unnecessarily.
Motor Control Using AVR
Now let’s generate control signals from the AVR MCU and feed them to the inputs of L293D. Assuming ATMEGA32, let us connect L293D across PORTC pins (PC0…PC3) as shown in the diagram below.
Now open up AVR Studio 5, type the following code and build it. If you are new to AVR Studio 5, you can read this post to get started with it.
#include <avr/io.h>
#include <util/delay.h> // for _delay_ms()
int main(void)
{
DDRC = 0x0F; // initialize port C
// motors connected across PC0...Pc3
while(1)
{
// clockwise rotation
PORTC = 0b00000101; // PC0 = High = Vcc
// PC1 = Low = 0
// PC2 = High = Vcc
// PC3 = Low = 0
_delay_ms(500); // wait 0.5s
// counter-clockwise rotation
PORTC = 0b00001010; // PC0 = Low = 0
// PC1 = High = Vcc
// PC2 = Low = 0
// PC3 = High = Vcc
_delay_ms(500); // wait 0.5s
}
}
After burning the code into your MCU, you will find that the motors rotate in clockwise direction for 0.5s and counter-clockwise direction for 0.5s. This goes on continuously.
Video
This is a simple demonstration of controlling two DC motors using a single L293D IC and a microcontroller. The video is made by Lavin Khandelwal for maxEmbedded. He has used the low cost 28 pin AVR Development Board and the USBasp AVR Programmer by eXtreme Electronics. He used the eXtreme Burner for burning the code.
In this way, you can control DC motors using AVR. For any kind of queries, clarifications or suggestions, you can use the comment box below!






Pingback: AVR Timers – PWM Mode – Part I « maxEmbedded·
Pingback: RF Module Interfacing without Microcontrollers « maxEmbedded·
Hi Mayank. This post is just AWESOME!!!
I have a suggestion for you. It will be great if you also include “Speed control of DC motor” in this post. Which can be done by feeding PWM signals to “Enable” pins. I think this will “complete” the article.
I am really getting very valuable information from your blog. Thanks for your hard work. And I have also liked your Facebook page. Keep up the good work!!!
Thanks Ameeya!
I will take care of that!
Hey Mayank,
This has been another great tutorial. You really do a fantastic job of explaining and simplifying things that can be very hard to understand otherwise. I have a project that requires an H-bridge, but I am running my circuit on 3.3 volts. This is too low a voltage to control the L293. I learned how to build an H-bridge from discrete components (as well as a great deal about how BJT’s work) from this website, for anyone who is interested. http://www.mcmanis.com/chuck/robotics/tutorial/h-bridge/bjt-circuit.html .
Thanks for all of your hard work. You are doing a great service for a lot of people.
Devin
Thanks for your appreciation!
And yeah, making your own H-bridge is the solution to your problem. However, there are other solutions as well. You can make a DC-DC converter to increase the voltage level from 3.3v to 5v. Or else you can also make simple op-amp based amplifier circuits.
Pls given me infrmtion 4 interfacing motor without microcontroller , controlling by rf module
Hello Manish
If you want to use a motor without a microcontroller, then simply connect the input terminals of L293D directly to the RF module. Make sure you vary the input manually (since microcontroller is not used).
i hav tried running a dc motor with 8051.l293d powered with a 9v batery. it runs for sometime,stops then and automatically starts as if it hs lost out the control from the 8051.why is it so?is it some internal resistance of battery effect? howw can i solve it? pls..its xtremely urgent for my project.
Check the following:
1. Check whether your coding is proper.
2. Check whether you have made the proper connections.
3. Check the output of the microcontroller pins using a multimeter.
4. Similarly, check the output of the L293D pins using a multimeter.
5. If step 3 gives you proper result and step 4 doesn’t, replace your motor driver.
how can I use RF Module interfacing to controll one robot by another?
Means I will drive one robot manually and the second robot should follow it one all types of tracks like tadial turns and straight track…
Please help..
If you want, you can use a microcontroller to decode your manual signals and transmit it.. or else if you don’t wish to use microcontrollers, then you have to make a simple digital circuitry to decode the data from your remote/DPDT into the four channels, that can be transmitted with the above technique.
Hii Mayank. We we want to change the polarity of dc geared motor without using micro controller. We are working on one model which should have one direction movement for 9 sec then it should return back i.e. reverse and forward movement it can only happen when we change the polarity of geared motor. so please suggest any simple circuit since we are mechanical and not so much familiar with micro controller. thanks in advance.
Hi Amol
Since you don’t want to use a microcontroller, you must make a separate timer circuit on your own. This also requires some knowledge of electronics. You can use 555 timer IC in astable mode to generate a 9sec timer by selecting proper values of resistor and capacitor.
hi mayank, can u help me with speed control of dc motor?
Hi Nishat
You can control the speed of DC motor using PWM signal, discussed here.
Thanx for the above information
Hi; I have a readymade motor driver board of 10amp. It has only one DIR pin. I attached that DIR pin to pin 14 of Atmega 8A 32 pin. How will I write the C lines for clockwise & anti-clockwise direction ?
Hi Mohit,
This totally depends upon the way your board is made. You say that you have connected DIR pin to PB0 (pin14) of ATmega8A. Most probably, if you give HIGH, it will rotate clockwise, and vice-versa. In any case, I have absolutely no idea how your board is made. If you could send me the datasheet of your board, then I might help you out with it.
I purchased it from robokits.co.in. They don’t provide schematics. Only foreign companies provide schematics. After purchasing any hobby electronics from indian websites, they don’t help. They started side-business of workshops.
If you could send me the exact link from where you bought, I might try to figure it out.
http://robokits.co.in/shop/index.php?main_page=product_info&cPath=73&products_id=334
It says, “Sorry, the product was not found.”
ok leave it. I am planning to buy motor driver board from nex-robotics. It has 2 pins for direction.
Why buy it? I would suggest you to make one yourself! You just need to do some soldering, and that’s it! The circuit is already given here in this post.
i need 5amp your diagram is fo 1amp. My project is very challanging. Making a dc servo motor from dc motor of 5amp 12volts.
i am using atmega32 and l293d to drive 2 motrors as according to your diagram.i not using adruino to drive motors. can you help me to complete the circuit where and how the pin1,pin 9 and pin16 of l293d to be connect with atmega32 pins and breadboard ? i have connected pin8 of l293d with battery. can you send me the images of breadboard circuits ?
Hi Praful
The above post is made by keeping ATmega32 in mind (not Arduino)! Just follow the connections!
I made the connections on breadboard as shown above but still the motor is not spinning. Can i send you the breadboard images so please tell me where the connections goes wrong ?
Hi Praful,
The circuit shown above is a standard one, and the most commonly used and tested circuit. So what I would suggest is grab your nearest multimeter, and check for continuity in your breadboard circuit.
Hi ma-yank ,
Iam currently doing a project with peltier element as a temperature controller . I generated a PWM pulse to control the circuit .cooling is only done when the control voltage is negative .
can we generate a pulse of negative half from a microcontroller in order to control peltier element to make it ON and OFF.
Hi Sandeep
Well, to generate a negative voltage, you need to take reference from a higher voltage level. For example, you have connected two pins to your peltier element. If you provide it as 10, then assuming it corresponds to positive voltage, then 01 should represent negative voltage. Will it do for your project or are you looking for something different?
Hi mayank I generated negative voltge by using op_amp . thanks for the response
Excellent Tutorial Mayank bhai, I am trying to write an SPI program using atuc3a3256 microcontroller and I have 5 slaves from where i need to collect data thru the USB interface.
Do you have any tutorial that could help me out.
Hi Zubair,
Sorry, but I haven’t worked with USB interfaces yet. If you want an USB interface with the AVR, then perhaps this might help you out.
Pingback: Making an RF Car | maxEmbedded·
hello mayank i am an MCA student i am trying to build a BOT for which i am using atmega16 i want to communicate with it using RF module through my laptop and want to use a wireless camera.All the image
taken by the camera will display in my laptop interface.So for this what should i do,and can you help with some sample codes for controling it remotely,and displaying it in my laptop.THANKS!
Hi Abhinandan,
You can have have a look at this post regarding manual RF communication. If you want to control using laptop, then here is how you should do:
Laptop with a terminal software (like Hyperterminal, Realterm, PuTTy, etc.) –> USB to Serial –> RF Tx –> RF Rx –> USART of ATMega16
As far as your camera is concerned, I assume that you are using a wireless camera which sends data directly to your laptop where you can monitor/process your data.
Another great tutuorial, but i the ic you used i.e l293d could it be used to drive motor of differnet power or the motor should be of same power. if i am right the voltage supplied to the motor will be the one that is connected across pin 8 (Vs),
Dear Mayank,
Information of L293D is very useful for me. I also like your attitude with extreme electronics.
Thanks Guru
Hi Bharat
Thanks!
excellent tutorial,
thank you verymuch for the valuable information.
Thanks Viresh!
5amp motor drive boards have current sensing pin. Can you tell me where cs pin goes into atmega ic ? Is that compulsory to use cs pin ?
Please tell me which motor driver are you using? If possible, send us link of the datasheet.
i have AVR(atmega16) developmentboard in which motordriver (L293D) is embedded.please give me details of connecting battery to developmentboard & where to connect it?
Hi Saiteja,
Ideally you should connect two power sources to your development board. One to power up the microcontroller and accessories, other one completely dedicated for the motors. You should connect your power source to pin 8 of your L293D IC on your board. If you can send me some link/website from where you bought it, we can tell you exactly where you need to connect the batteries.