DC Motor Control using AVR

AVR Series

Dear readers, please note that this is the old website of maxEmbedded. The articles are now no longer supported, updated and maintained. Please visit the new website here and search for this post. Alternatively, you can remove .wordpress from the address bar to reach the new location.

Example: If the website address is http://maxEmbedded.wordpress.com/contact/, then removing .wordpress from it will become http://maxEmbedded.com/contact/.

We apologize for the inconvenience. We just want to give you a better viewing and learning experience! Thanks!

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.

DC Geared Motor

DC Geared Motor

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 - Motor Control

Block Diagram – Motor Control

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.

L293D DIP16 Package

L293D DIP16 Package

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.

L293D Pin Configuration

L293D Pin Configuration

Now let’s have a look at its connections for bidirectional motor control.

L293D Based Motor Driver

L293D Based Motor Driver

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.

AVR - L293D Connection

AVR – L293D Connection

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. The code can also be found on pastebin and in the code gallery.

#include <avr/io.h>
#include <util/delay.h>			// for _delay_ms()

int main(void)
	DDRC = 0x0F;			// initialize port C
					// motors connected across PC0...Pc3
	// 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.


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!

68 responses to “DC Motor Control using AVR

  1. dude you are just awesome.. well i have 1 doubt.. many times i have seen that for servo motor, L293 and L294 motor driving ICs are combined.. do you have any idea about it??

    • To run a servo motor, you need to provide it with 50 Hz PWM signal. L293 basically acts as a driver. Which means L294 should somehow give a PWM output. I don’t know about L294. So may be you could look up in its datasheet how it behaves.

  2. Hi mayank I want to buy micro DC gear motor for my College project please let me know how and where I can buy thnx🙂


    • Hi Sushil,
      You can check out your local hobby robotics store where they sell these stuffs. Or else you can also check out some online stores like vegarobokits, etc.

  3. hey Mayank,
    I am working on stepper motor. I’ve purchased one. It is hybrid. But, it has 10 wires (mostly, I heard about 4,6,8 wires). Actually, I don’t know how to use them (no wire specification). Can you help me on this?? How can we check it is unipolar or not?

    Thanks in advance!

    • Hi Amit,
      Well, I haven’t worked with such stepper motors before, so I may not be able to help you out here. The point is, stepper motors can have more number of pins as well. More number of pins implies that it has more number of magnetic cores, which means better resolution. I would suggest you to look out for datasheets for similar motors online. I googled and found quite a few, so you may want to check it and see which one matches your motor.

  4. i am just start to learn about m.cu. kindly guide me which book i reffer.is there is any default program in it.

    • I wouldn’t suggest any book for learning microcontrollers. Look out for help online. Like maxEmbedded, you can find several other resources online to help you learn about microcontrollers.

    • Hello muatez,
      Sorry, but we are no genie who can fulfill everybody’s wish. We don’t write codes for anyone. We teach the concept and empower you to write code yourself. If you could explain us in more detail what your requirements are, we could tell you a possible method. Thanks.

  5. sir,
    do you have a tutorial for stepper motor ? or will it publish soon on your web site.

  6. Hey mayank,your post is awesome…I just want to ask you that if we can change the direction by just reversing the polarity,then why we need ATMega16 microcontroller??

  7. hello sir
    after connecting all terminals my motor is stop working after 20-30 sec
    and also current is not coming properly

    i have connected l293d to portd
    my connection are
    i/p 1 = pd4
    i/p 2 = pd2
    i/p 3 = pd6
    i/p 4 = pd5
    enable 1 = pd3
    enable 2 = pd7

    my programming is http://pastebin.com/JbVkjWM6
    pls help sir

    • Divyam,
      I am surprised that the motors are even running for 20-30 seconds! You haven’t specified anywhere in your code that PORTD should be an output port. Change DDRB to DDRD in your code and try again.

      • sir sir programming is wrong
        i give output to the 0xff to port b but still not running properly

        some time it run somtime not
        pls help

        • Okay, so this is a good time to take out your multimeter and start debugging! Check whether the voltage across all the pins of PORTB are as you expect. Also, try changing to some other port to see if it works. Were you successfully able to blink an LED before?

We'd love to hear from you!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s