Project

How To Control a DC Motor with an Arduino

July 07, 2018 by Tim Youngblood

By connecting an L298 bridge IC to an Arduino, you can control a DC motor.

By connecting an L298 bridge IC to an Arduino, you can control a DC motor.

A direct current, or DC, motor is the most common type of motor. DC motors normally have just two leads, one positive and one negative. If you connect these two leads directly to a battery, the motor will rotate. If you switch the leads, the motor will rotate in the opposite direction.

To control the direction of the spin of DC motor, without changing the way that the leads are connected, you can use a circuit called an H-Bridge. An H bridge is an electronic circuit that can drive the motor in both directions. H-bridges are used in many different applications, one of the most common being to control motors in robots. It is called an H-bridge because it uses four transistors connected in such a way that the schematic diagram looks like an "H." 

You can use discrete transistors to make this circuit, but for this tutorial, we will be using the L298 H-Bridge IC. The L298 can control the speed and direction of DC motors and stepper motors and can control two motors simultaneously. Its current rating is 2A for each motor. At these currents, however, you will need to use heat sinks.

The pinouts for the L298 are shown below. You can find a datasheet the L298 at http://www.tech.dmu.ac.uk/~mgongora/Resources/L298N.pdf.

L298 Pinout (top view)

Hardware Required

  • 1 x L298 bridge IC
  • 1 x DC motor
  • 1 x Arduino Mega2560
  • 1 x breadboard
  • 10 x jumper wires

The schematic above shows how to connect the L298 IC to control two motors. There are three input pins for each motor, including Input1 (IN1), Input2 (IN2), and Enable1 (EN1) for Motor1 and Input3, Input4, and Enable2 for Motor2.

Since we will be controlling only one motor in this tutorial, we will connect the Arduino to IN1 (pin 5), IN2 (pin 7), and Enable1 (pin 6) of the L298 IC. Pins 5 and 7 are digital, i.e. ON or OFF inputs, while pin 6 needs a pulse-width modulated (PWM) signal to control the motor speed.

The following table shows which direction the motor will turn based on the digital values of IN1 and IN2.

IN1IN2MOTOR
00BRAKE
10FORWARD
01BACKWARD
11BRAKE

IN1 pin of the L298 IC is connected to pin 8 of the Arduino while IN2 is connected to pin 9. These two digital pins of Arduino  control the direction of the motor. The EN A pin of IC is connected to the PWM pin 2 of Arduino. This will control the speed of the motor. 

To set the values of Arduino pins 8 and 9, we will use the digitalWrite() function, and to set the value of pin 2, we will use the using analogWrite() function.

Below is a photo of the set up.

​Code

const int pwm = 2 ;	//initializing pin 2 as pwm
const int in_1 = 8 ;
const int in_2 = 9 ;

//For providing logic to L298 IC to choose the direction of the DC motor 

void setup()
{
pinMode(pwm,OUTPUT) ;  	//we have to set PWM pin as output
pinMode(in_1,OUTPUT) ; 	//Logic pins are also set as output
pinMode(in_2,OUTPUT) ;
}

void loop()
{
//For Clock wise motion , in_1 = High , in_2 = Low

digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,LOW) ;
analogWrite(pwm,255) ;

/*setting pwm of the motor to 255
we can change the speed of rotaion
by chaning pwm input but we are only
using arduino so we are using higest
value to driver the motor  */

//Clockwise for 3 secs
delay(3000) ; 		

//For brake
digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,HIGH) ;
delay(1000) ;

//For Anti Clock-wise motion - IN_1 = LOW , IN_2 = HIGH
digitalWrite(in_1,LOW) ;
digitalWrite(in_2,HIGH) ;
delay(3000) ;

//For brake
digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,HIGH) ;
delay(1000) ;
 }

dc_motor.ino.zip

Arduino Motor Control Setup

  1. Connect 5V and ground of the IC to 5V and ground of Arduino.
  2. Connect the motor to pins 2 and 3 of the IC.
  3. Connect IN1 of the IC to pin 8 of Arduino.
  4. Connect IN2 of the IC to pin 9 of Arduino.
  5. Connect EN1 of IC to pin 2 of Arduino.
  6. Connect SENS A pin of IC to the ground.
  7. Connect the Arduino using Arduino USB cable and upload the program to the Arduino using Arduino IDE software or Arduino Web Editor.
  8. Provide power to the Arduino board using power supply, battery or USB cable.
The motor should now run first in the clockwise (CW) direction for 3 seconds and then counter-clockwise (CCW) for 3 seconds.


Video

Give this project a try for yourself! Get the BOM.

20 Comments
  • Clint Zang June 27, 2015

    OK. Understandable, however I want to beef it up to control a treadmill motor. Anybody done that with success? I’d like to know how.

    Like. Reply
  • mertcapanoglu August 27, 2015

    This article doesn’t say anything about the Vs(supply voltage) of the IC, just the logic supply. I’m guessing using a high power dc motor would fry the usb and possibly the motherboard of the computer.

    Like. Reply
  • EdFone October 31, 2015
  • jwolfdam November 20, 2015

    Me too I will like to know how.

    Like. Reply
  • Whatashame December 06, 2015

    I only have arduino nano 3.3, “amego 328” , or an “uno”, and I think it’s the same thing as the “328”. Will your sketch (above) work for the “nano” or the “uno”. I’m just a beginner people, be kind. If not , what part would be different?

    Like. Reply
    • rohit.04ramos April 18, 2018
      If you got any replies or answers about this one plz tell me aswell
      Like. Reply
      • Jamie2 December 31, 2018
        The sketch above would work for all arduinos. Just make sure you arn't using too much current < 25 mAh (Most Arduinos can draw up to 40 mAh but just be careful). PMW pins can also be different. Make sure they have this marking ~. Overall it should work, but just check beforehand, as drawing too much current will destroy your Arduino.
        Like. Reply
  • jiaming March 18, 2016

    Hello guys, i am new learner for arduino uno, now going to make a final project for the last semester in studies, which is portable smart pump, now i am facing some programming or hardware problem request to get some help from all the programming learner. The problem is when the set point is reach and over the prsss(KPA value being calculate after pressure sensor(prssPin) sense the pressure) the motor driver is not active after the programming statement is true. Thanks for help.

    Here goes my programming:

    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12,11,5,4,3,2); //pin lcd

    const int button1 = 8;            // + Setpoint button
    const int button2 = 7;              // - Setpoint button

    int setpoint = 0;
    int button1State = 0;              // Store state of Button1
    int button2State = 0;              // Store state of Button2
    int prss; //value of psi
    float prsss; //value of kpa
    int motor_start = 13; //dc motor
    int prssPin = A0;
    int setLimit1 = 100;              // Set limit setpoint KPA = 100
    int setLimit2 = 0;                // Set limit setpoint KPA = 0
    int pwm = 6;


    void setup()
      {
    {
    pinMode (button1, INPUT_PULLUP); // set the button1 pin 10 up as an input.
    pinMode (button2, INPUT_PULLUP); // set the button2 pin 9 up as an input.
    pinMode(motor_start, OUTPUT); //dc motor as output
    }
        {
    lcd.begin(16,2);
    lcd.print("Smart Pump");
    lcd.setCursor(8,1);
    lcd.print("Portable");
    lcd.display();
    delay(3000);
    lcd.begin(16,2);
    lcd.print(" ");
    lcd.setCursor(8,1);
    lcd.print(" ");
    delay(500); //lcd display for 3 seconds and blink for 0.5 seconds
    prss = analogRead(prssPin); //pressure sensor read value of psi
    prss = prss / 6.8;
    lcd.begin(16,2);
    lcd.print("PSI ");
    lcd.print(prss);
    lcd.println();
    prsss = analogRead(prssPin); //pressure sensor read value of kpa
    lcd.setCursor(0,1);
    lcd.print("KPA ");
    lcd.print(prsss);
    lcd.println();
    delay(5000); //display value on 5 seconds
    lcd.noDisplay();
    delay(500);
    }
      }


    void loop()
    {
    {
    button1State = digitalRead(button1);
    if (button1State == 0 && setpoint < setLimit1)
    setpoint ++;

    button2State = digitalRead(button2);
    if (button2State == 0 && setpoint > setLimit2)
    setpoint--;


    lcd.begin(16,2);
    lcd.print("Setpoint= ");
    lcd.print(setpoint);
    lcd.display();
    delay(100);
    prss = analogRead(prssPin);
    if (prsss < setpoint)
    {
    digitalWrite(motor_start, HIGH);
    }
            else
              {
    digitalWrite(motor_start, LOW);
    }
      }
    }

    Like. Reply
  • Ankit Kr. Mishra September 18, 2016

    I have tried exactly the same setup but motor is still, not rotating at all. however, the code uploading is done and X1 ans Rx lights blinking when code is uploading. what does it indicate?

    Like. Reply
    • rohit.04ramos April 18, 2018
      If u found the answer please tell me
      Like. Reply
    • ElliottBridge August 30, 2018
      Those lights just show communication with the program, showing the code being uploaded. It is not to do with that. Have you verified the code? Does your pin support PWM?
      Like. Reply
  • Nikhil Anvekar March 09, 2017

    I ve used the circuit and program that was posted can the website
    But it is showing error,
    Sketch uses 1074 bytes, max is 32256 bytes.
    Global variables use 9 bytes of dynamic memory, leaving 2039 bytes
    For local variables, max is 2048 bytes

    Like. Reply
  • danykas December 07, 2017

    Hi is very good but I wind to speed control with potentiometer how I can’t? thank you

    Like. Reply
    • RK37 January 30, 2018
      Hi, if you have a specific question regarding your own circuit or implementation, please post it in the forum so that our forum members can provide the assistance that you need.
      Like. Reply
    • Jamie2 December 31, 2018
      If you want to control with potentiometer you can make the potentometer's output a variable. Then put that variable into the "analog.write(pmw,255)" Instead of 255 put the variable's name. Another solution which I have done is to take the electronics of a servo out. You will see a motor which is connected onto 2 points of a circut board. solder your own motor onto the places where the servo's motor was. Then use "servo.write(90)" The 90 can be changed to 180 (Turn right) or 0 (Turn Left). A number around 90 will stop the motor. Experiminent to find out
      Like. Reply
  • danykas December 09, 2017

    hi how i can’t with pot. prm; thank you.

    Like. Reply
  • rohit.04ramos April 18, 2018

    Please anyone can help me out . This above one is notworking with the arduino uno .
    Please tell me the whole configuration for arduino uno.

    Like. Reply
    • RK37 April 19, 2018
      If you have a question regarding your specific application or implementation, please post it in the forum. It's a great place to get help with all sorts of circuits and projects.
      Like. Reply
  • Smithp260 May 23, 2019

    Can any one post the ciruit diagram

    Like. Reply
  • ernstwichard October 06, 2019

    1. The supply voltage of the L298 must be bigger (by about 2 V) then the 5V of the arduino
    2. If you do not use protection diodes (4 per motor) you may blow up the L298

    Like. Reply