DEV Community

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

Posted on

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

Motor control is one of the most common requirements in robotics and automation projects. The L293D Motor Driver Shield makes this process simple by allowing an Arduino board to control multiple DC motors, stepper motors, and servo motors simultaneously — without complex wiring.

In this overview, we’ll understand how the shield works and how it can be used to control speed and direction efficiently.

What is L293D Motor Driver Shield?

The L293D Motor Driver Shield is an expansion board designed to simplify motor interfacing with an Arduino Uno. It uses two L293D H-bridge driver ICs and a 74HC595 shift register to efficiently control multiple motors using limited Arduino pins.

Each L293D IC can control:

  • Two DC motors
  • Or one stepper motor

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

  • Up to 4 DC motors
  • Or 2 stepper motors
  • Plus 2 servo motors

Each motor channel supports:

  • Motor voltage: 4.5V to 24V
  • Continuous current: 600mA per channel (1.2A peak)

Key Features

  • Drives up to 4 bidirectional DC motors
  • Supports 2 unipolar or bipolar stepper motors
  • Two dedicated servo headers
  • 5V logic compatible
  • Pull-down resistor network for safe startup
  • Power selection jumper for flexible supply options
  • External motor power terminal (EXT_PWR)

L293D Motor Driver Shield Hardware Overview

Pin Usage on Arduino UNO

The shield occupies the following digital pins:

D3, D4, D5, D6, D7, D8, D9, D10, D11, D12

That leaves limited digital I/O, so analog pins (A0–A5) can be used as digital inputs when required.

Power Configuration Options

The shield allows two powering methods:
1️⃣ Single Supply Mode
If motors operate within 12V range, you can power both Arduino and shield from a single adapter via Arduino’s DC jack.
(Keep the PWR jumper connected.)

2️⃣ Separate Supply Mode
Remove the power jumper.
Power Arduino via USB and motors via external supply connected to EXT_PWR terminal.

Important: Never keep the jumper installed when using external motor supply — it may cause a short circuit.

Wiring of DC motor with L293D shield and Arduino UNO

Pin Connections
5V - Vcc pin of LCD and pin 1 of POT
Gnd - Gnd pin of LCD and pin 3 of POT
A0 - pin 2 of POT
A1 - Clockwise rotation Button
A2 - Anti-Clockwise rotation Button
A3 - Stop Button
SCL - SCL pin of LCD
SDA - SDA pin of LCD

/* 
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

For complete details on how to control servo and stepper motor including wiring diagrams, code examples, and detailed explanations, you can read the full step-by-step tutorial at Play with Circuit:

👉 https://playwithcircuit.com/l293d-motor-driver-shield-arduino-tutorial/

Top comments (0)