In this tutorial, you will learn how to control a DC motor using Arduino and L239D. You will be using analog output(  Arduino PWM function ) of Arduino to control the speed of the DC motor. After completing this tutorial you will be able to control spinning Direction, and speed.

Why DC motors need a Motor driver to connect with Arduino?

Driving the electric DC motor needs a high current, along with that we need to control the spinning Direction and speed of the motor. These can be achieved through a microcontroller but there is a problem, microcontrollers cannot provide enough current to run the motors, If the motor is connected directly to the microcontroller, it may get damaged.

For Example: In this tutorial, we are going to use Arduino and L239D, the pins of Arduino nano are limited to 40mA, but a motor required 100-200mA  current. To solve this problem we are going to use a motor driver L239D along with Arduino to control the DC motor. The motor driver connects with the Microcontroller to receive commands and run the motor with a high current.

In this tutorial, we are dealing with Arduino and L239D based DC motor drivers.

DC motor and How to control  that Using Arduino Nano

 For controlling the speed of a Dc motor  by simply controlling the input  voltage to the motor, the most common way we are doing  that is by using the Arduino  PWM signal: Check this to know more about PWM

 PWM or Pulse with modulation is a technique that a user to adjust the average value of the voltage that goes to the electronic device by turning on and off the power at a fast rate. The average value of voltage depends on the duty cycle ( amount of times the signal is on versus  the amount of time the signal is off )

For controlling the Direction of the motor we need to reverse the direction of current flow through the DC motor. This can be achieved by a common method called H-bridge. H- Bridge is a circuit that contains four switching elements with a motor at the center. By activating two particulars switched we can change the direction of current flow, thus change the direction of the DC Motor.

L239D Motor Driver

L239D is an Integrated chip that comes with combined functions to control the Speed and Direction of the DC motor. This module can drive voltages between 5v to 35 volts with a peak current of up to 2A.

Refer to the datasheet for More details about L239D

L293D-Dual-H-Bridge- Dc Motor Driver-IC-Pinout

L298N is a dual-channel H-Bridge motor driver capable of driving 2x DC motors.L239D is a 16 pin IC having two enabled pins, As i mentioned earlier  L293D is a dual H-bridge motor driver, in which enables pin should always be remain high to enable both the H-bridges.

L239D has two power pins marked as Vcc1 ( pin 16 )  and Vcc2 (pin 8 ) marked in the above diagram.Vcc1 used for driving the internal logic circuit of the IC, and it should be 5v. Vcc2 pin provides power supply to H-bridge, which can be 5v to 36v. Pin number 4, 5, 13 & 12  connected to common ground

Output channels for Motor A and Motor B are brought out to the OUT1, OUT2, and OUT3, OUT4, respectively. Each output channel of the IC can deliver up to 600mA current to the DC motor connected to it.

Direction control Pins of Motor A  marked as IN1, IN2 and For the Motor B  marked as IN3, IN4, these are four pins we connect directly to Microcontroller to send the direction signal to IC

IN1IN2Spinning Direction
Low(0)Low(0)Motor OFF
High(1)Low(0)Forward
Low(0)High(1)Backward
High(1)High(1)Motor OFF

 This truth table described the direct operation of the DC motor.

Speed control was achieved using ENA and ENB pins. Applying Pulse width Modulation to these pins, we can control the speed of the motor. For details about L239D refer to the datasheet.





Arduino and L298D Motor Driver

Now we know the need for a motor driver for a Microcontroller; let’s make some practical applications to learn how to control the Speed and Direction of the motor.

In the tutorial, we will control the speed of the DC motor using a potentiometer and change the direction of rotation using a sliding switch.

Parts Required

Let’s grab the below items to work on this project to control the DC Motor using Arduino Nano. All the items are cheaply available on the  e-commerce websites :

  • Arduino Nano
  • L293D
  • Battery Connector 9v
  • Battery
  • Jumper wire
  • Sliding Switch
  • DC toy motor

Schematic Diagram to Connect Arduino nano and L239D

Follow the connection details. In this circuit, we are using a battery connector to power up the motor, if it’s not available you can use a 12v adapter to do this.

Schematic Diagram DC motor and Arduino Nano and L239D

Wiring the H-Bridge

 It’s a quite difficult task, not like Arduino L239D is not marked with pin numbers so everyone asks a simple question  How do we know what each pin on this chip does? For that, you need to open the datasheet. Datasheets give more details about the pin description.

L239D breadboard connection  with pin marking

Connection Slide Switch

We are using a slide switch to control the direction of the motor, Slide switch comes with 3 pins, we connect the center pin of the slide switch to 5V and the other two pins to two Arduino nano input pins. By sliding the switch we can turn on and off the pin.

you can also check out the Potentiometer tutorial using Arduino.

Source Code/Program

Copy the following code to your Arduino IDE, and upload it to your Arduino board.

int switchPinFwd = 12;     //Input from the slide switch to run motor  clock wise rotation
int switchPinBwd = 11;     //Input from the slide switch to run motor anticlick wise 


int POT =A0;               // varible to declare the potentiomenter connected pin 
int potentiometerIn;       //variable to hold the potentiometer input
 
int IN1 = 8;           //Logic level output to the H-Bridge (Forward)
int IN2 = 7;           //Another logic level output to the H-Bridge (Reverse)
int EN1 = 9;           // this pin connected with EN1 to pass PWM signal to control the motor speed


void setup() {
 
  pinMode(switchPinFwd, INPUT);    //set switchPinFwd as input pin
  pinMode(switchPinBwd, INPUT);    //set switchPinBwd as input pin
  pinMode(IN1, OUTPUT);        //Set the IN1 pin to an output
  pinMode(IN2, OUTPUT);    //Set the IN2 pin to an output
}
 
void loop() {

  
  potentiometerIn = analogRead(POT);
  int output = potentiometerIn / 4; //divide the potentiometer input by 4 so it can be used in the AnalogWrite function
 
  if(digitalRead(switchPinFwd) == HIGH) //Check to see if the pin is high or low
  {
    //If the pin is HIGH, it must be set to forward
      analogWrite(EN1, output); //Output of  potentiometer value on theEnable pin to control speed.
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
  }
  else if (digitalRead(switchPinBwd) == HIGH) 
  {
    //Otherwise the switch must be set to Reverse
    analogWrite(EN1, output); //Output of  potentiometer value on theEnable pin to control speed.
    digitalWrite(IN1, LOW);  //reverse the direction of motor
    digitalWrite(IN2, HIGH);
  }
  else 
  {
    analogWrite(EN1, 0); //Output of  potentiometer value on 0 to turn of the motor.
    digitalWrite(IN1, LOW);  
    digitalWrite(IN2, LOW);
  }
  delay(25);
}

How Code Works

Now we can look into the code and how its works

We are using a sliding switch to reverse the direction of the motor. The sliding switch has three pins in which the center pin is connected to 5V and the other pins are connected to pin numbers 12 and 13, also connect these pins to the ground by 10k resistor.

int switchPinFwd = 12;     //Input from the slide switch to run motor  clock wise rotation
int switchPinBwd = 11;     //Input from the slide switch to run motor anticlick wise 

above code is declare variables to store in sliding switch PIN to control the direction

We are using a Potentiometer, PIN A0 is connected to a potentiometer, and POT is used to declare the pin and value that we read from the pot is stored in a variable potentiometer.

int POT =A0;               // varible to declare the potentiomenter connected pin 
int potentiometerIn;       //variable to hold the potentiometer input

IN1, IN2, and EN1 are used to declare the variable to hold the Motor pins and Enable pin, we connect IN1 and IN2 to 7 and 8 pin. Pin number 9 has a PWM function so we connect it to EN1.

int IN1 = 8;           //Logic level output to the H-Bridge (Forward)
int IN2 = 7;           //Another logic level output to the H-Bridge (Reverse)
int EN1 = 9;           // this pin connected with EN1 to pass PWM signal to control the motor speed

After that, we declare the functionality of each pin in the setup() function

  pinMode(switchPinFwd, INPUT);    //set switchPinFwd as input pin
  pinMode(switchPinBwd, INPUT);    //set switchPinBwd as input pin
  pinMode(IN1, OUTPUT);        //Set the IN1 pin to an output
  pinMode(IN2, OUTPUT);    //Set the IN2 pin to an output

Next, we need to write the code inside the loop() function to run continuously

For PWM maximum possible values are 0 to 255, the value we get from the POT is in the range of 0-1023. so we converted to a range of 0-255 using the value divided by 2.

potentiometerIn = analogRead(POT);
int output = potentiometerIn / 4; //divide the potentiometer input by 4 so it can be us in the AnalogWrite function

next is a conditional statement, we have connected two pins of sliding switch to 11, 12 by default any one of the PIN always be high, we are using the condition statement to check the status of these pins and control the direction of motor It performed using if-else if logic system.

  if(digitalRead(switchPinFwd) == HIGH) //Check to see if the pin is high or low
  {//If the pin is HIGH, it must be set to forward
   }
  else if (digitalRead(switchPinBwd) == HIGH) 
  {//Otherwise the switch must be set to Reverse
  }
  else  
  { //Output of  potentiometer value on 0 to turn of the motor.
  }
 

using the analog write () function we control the speed of the motor bypassing the PWM signal. By turn on and off the INI and IN2 helps to change the Spinning direction of the motor.

  analogWrite(EN1, output); //Output of  potentiometer value on theEnable pin to control speed.
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
author avatar
Amith G Nair
Experience as a product developer, innovation coach, and electronics lecturer,a seasoned professional driven by passion for designing projects.expertise extends to 3D modelling, hardware designing, and web development using HTML, WordPress, and Django.