DEV Community

Cover image for Controlling DC, Servo and Stepper Motors with Arduino Using the L293D Motor Driver Shield
rachna62
rachna62

Posted on

Controlling DC, Servo and Stepper Motors with Arduino Using the L293D Motor Driver Shield

Motor control is an essential part of robotics, automation systems and mechatronics projects. However, driving motors directly from an Arduino is not possible because the microcontroller cannot supply the required current.

This is where a motor driver shield becomes useful. The L293D Motor Driver Shield provides an easy interface between the Arduino and multiple types of motors including DC motors, servo motors and stepper motors.

In this project we will learn how to use the L293D motor shield with an Arduino UNO to control:

• DC motor speed and direction
• Servo motor movement
• Stepper motor rotation and direction

User inputs are taken through push buttons and a potentiometer, while a 16×2 I2C LCD displays the motor status and speed.

L293D Motor Driver Shield Overview

The L293D motor driver shield is designed to simplify motor control projects with Arduino. The shield contains two L293D H-bridge driver ICs which allow bidirectional control of motors.

Each L293D IC can control 2 DC motors or 1 stepper motor.

Since the shield includes two L293D chips, it can control:

• 4 DC motors
• or 2 stepper motors

In addition, the shield provides two dedicated servo connectors.

Hardware Architecture of the Shield

The shield contains several important components that make motor control possible.

L293D Motor Driver IC: The L293D is a dual H-bridge motor driver that controls the direction of current through the motor. This allows the motor to rotate in both clockwise and anticlockwise directions.

Each L293D IC can drive two motors.

Since the shield contains two L293D ICs, four DC motors can be controlled simultaneously.

74HC595 Shift Register: The 74HC595 shift register expands the Arduino's digital output capability.

Instead of using many digital pins directly from Arduino, the shift register allows multiple motor direction signals to be controlled using fewer pins.

Reset Button: A reset button is provided on the shield so the Arduino can be reset easily even when the shield is mounted.

Power Indicator LED: The power LED indicates when the motor power supply is active.

Pull-Down Resistor Network: The resistor array ensures that motor driver inputs remain in a known state during startup.

L293D Motor Driver Pinout

Motor Connection Ports

The shield provides dedicated connectors for different motor types.

DC Motor Connections

The shield provides four motor output ports labeled M1, M2, M3 and M4.

Each port can drive a DC motor.

Important details:

• Voltage range: 4.5V – 24V
• Maximum current per channel: 600mA continuous

Servo Motor Connections

The shield includes two servo ports labeled:

SERVO_1
SERVO_2

Stepper Motor Connections

Stepper motors use two motor channels.

Power Supply Configuration

The shield supports two power configurations.

Option 1: Single Power Supply

If motors operate below 12V, the Arduino and motors can share the same power supply.

Steps:

Connect supply to Arduino DC jack
Keep the PWR jumper installed

Option 2: Separate Motor Power Supply

This is recommended for higher current motors.

Steps:

Remove the PWR jumper
Power Arduino via USB
Connect motor supply to EXT_PWR terminals

Important Warning: Never keep the jumper installed while using external power at EXT_PWR.
This can create a short circuit and damage the board.

Controlling DC Motor

In this example we control:

• Motor direction
• Motor speed

Speed is controlled using a 10K potentiometer.

Components:
Arduino UNO
L293D Motor Driver Shield
5V DC Motor
3 Push Buttons
10K Potentiometer
16×2 LCD (I2C)
External 5V motor supply
Breadboard
Jumper wires

The L293D motor driver shield should be mounted directly on top of the Arduino UNO, but in the wiring diagram it is shown separately for clarity and to better illustrate the external connections such as buttons and the potentiometer. The potentiometer is connected to analog pin A0, with its middle pin acting as the variable output, while the other two pins are connected to 5V and GND. By adjusting the potentiometer, the voltage at A0 changes, which directly controls the motor speed—higher voltage results in higher speed.

Since the shield occupies most of the Arduino’s digital pins (D3 to D12), and D0–D1 are reserved for serial communication while D13 is connected to the onboard LED, only one digital pin (D2) remains free. To overcome this limitation, analog pins A1, A2, and A3 are used as digital input pins for push buttons. These buttons control motor operation: A1 for clockwise rotation, A2 for anticlockwise rotation, and A3 for stopping the motor.

A 16×2 LCD with I2C interface is connected to the Arduino’s SDA and SCL pins to display motor speed and direction. The 5V DC motor is connected to the M3 terminal of the motor shield. An external 5V power supply is provided to the shield through the EXT_PWR terminal to ensure sufficient current for the motor.

⚠️** Important:** Ensure that the power jumper (PWR) is removed when using an external power supply to avoid short circuits and potential damage.

Arduino Code

/* 
Interfacing DC Motor with Arduino UNO using L293D motor Driver shield
by www.playwithcircuit.com 
*/
#include <AFMotor.h>
  // Library to run DC Motor Using Motor Driver Shield  
#include <LiquidCrystal_I2C.h> 
  // Library to Run I2C LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);  // Format -> (Address,Columns,Rows )
// Create the motor object connected to M3
AF_DCMotor motor(3);
// Define button pins
const int forwardButtonPin = A1;
const int reverseButtonPin = A2;
const int stopButtonPin    = A3;
// Define potentiometer pin
const int potPin = A0;
// Variables to store motor state and direction
bool motorRunning  = false;
int motorDirection = BACKWARD;  // FORWARD or BACKWARD
// Read the potentiometer value
int potValue;
int motorSpeed;
// Variable to store button states
bool forwardButtonState;
bool stopButtonState;
bool reverseButtonState;
// Inline function to check if button is pressed packed with debouncing logic
inline bool chkButtonState(int pinNum, int checkState, int debounceDelay) {
  if (((digitalRead(pinNum) == checkState) ? true : false) == true) {
    delay(debounceDelay);
    return (((digitalRead(pinNum) == checkState) ? (true) : (false)) == true);
  } else {
    return false;
  }
}
void setup() {
  // initialize the lcd
  lcd.init();
  // Turn on the Backlight
  lcd.backlight();
  // Clear the display buffer
  lcd.clear();
  // Set cursor (Column, Row)
  lcd.setCursor(0, 0);
  lcd.print("DC Motor using");
  lcd.setCursor(0, 1);
  lcd.print("L293D Shield");
  // Set button pins as inputs
  pinMode(forwardButtonPin, INPUT_PULLUP);
  pinMode(stopButtonPin   , INPUT_PULLUP);
  pinMode(reverseButtonPin, INPUT_PULLUP);
  // Start with motor off
  motor.setSpeed(0);
  motor.run(RELEASE);
  delay(2000);
  // Clear the display buffer
  lcd.clear();
  // Set cursor (Column, Row)
  lcd.setCursor(0, 0);
  lcd.print("Motor Direction:");
  lcd.setCursor(0, 1);
  lcd.print("Stopped   ");
}
void loop() {
  // Read the potentiometer value for changing speed as per Analog input
  potValue   = analogRead(potPin);
  motorSpeed = map(potValue, 0, 1023, 0, 255);
  // Read the button states
  forwardButtonState = chkButtonState(forwardButtonPin, LOW, 20);
  reverseButtonState = chkButtonState(reverseButtonPin, LOW, 20);
  stopButtonState    = chkButtonState(stopButtonPin,    LOW, 20);
  // check for Forward run
  if (forwardButtonState && (!motorRunning || motorDirection == BACKWARD)) {
    // Set cursor (Column, Row)
    lcd.setCursor(0, 1);
    lcd.print("Clock   ");
    if (motorDirection == BACKWARD) {
      motor.setSpeed(0);
      motor.run(RELEASE);
      delay(1000);
    }
    motorRunning = true;
    motorDirection = FORWARD;
    motor.setSpeed(motorSpeed);
    motor.run(FORWARD);
  }

  // check for Reverse run
  else if (reverseButtonState && (!motorRunning || motorDirection == FORWARD)) {
    // Set cursor (Column, Row)
    lcd.setCursor(0, 1);
    lcd.print("Anti-Clk");
    if (motorDirection == FORWARD) {
      motor.setSpeed(0);
      motor.run(RELEASE);
      delay(1000);
    }
    motorRunning = true;
    motorDirection = BACKWARD;
    motor.setSpeed(motorSpeed);
    motor.run(BACKWARD);
  }

  // Stop motor
  else if (stopButtonState && motorRunning) {
    // Set cursor (Column, Row)
    lcd.setCursor(0, 1);
    lcd.print("Stopped         ");
    motorRunning = false;
    motor.setSpeed(0);
    motor.run(RELEASE);
  }

  // Adjust motor speed if running and display speed on LCD
  if (motorRunning) {
    motor.setSpeed(motorSpeed);
    // Set cursor (Column, Row)
    lcd.setCursor(9, 1);
    lcd.print("SPD:");
    lcd.print(((motorSpeed*100)/255));
    lcd.print("%  ");
  }
}
Enter fullscreen mode Exit fullscreen mode

If you want the complete tutorial to learn how to control servo and stepper motor including detailed schematics, Arduino code, and deeper explanation, you can read the full guide here: https://playwithcircuit.com/l293d-motor-driver-shield-arduino-tutorial/

Top comments (0)