The L293D Motor Driver Shield is one of the most versatile shields for driving DC, stepper and servo motors with an Arduino. This full-featured shield can control up to 4 DC motors, two steppers and two 5V servos.
In this tutorial, we will learn about how to use an L293D motor driver shield with Arduino to control the speed and direction of rotation of these motors.
What is L293D Motor Driver Shield?
The L293D motor driver shield acts as an interface between the Arduino and the motors, providing bidirectional control for up to four DC motor or two stepper motors and two Servo Motors simultaneously. The shield is equipped with the L293D IC, which contains two H-bridge circuits capable of driving motors with voltages up to 36V and currents up to 600mA per channel.
L293D shield simplifies motor control tasks by offering simple connections and control pins for controlling direction and speed. It can be easily integrated into their projects to power various motor-driven mechanisms such as robots, vehicles, and automated systems.
L293D Motor Driver Shield Features
- Two servo motors connections.
- It can drive up to four bidirectional DC motors.
- It can drive up to two unipolar or bipolar stepper motors.
- Offers bidirectional control for easy motor direction changes.
- Pull-down resistors disable motors during power-up.
- For separate logic/motor supplies, a 2-pin terminal block and a jumper are used to connect external power.
- 5V compatible on logic pins.
L293D Motor Driver Shield Hardware Overview
L293D IC L293D IC is the heart of the motor driver shield. It is a 16-pin IC with eight pins on each side for controlling the motor. A single IC is able to control two DC motors or one stepper motor. The motor driver shield has two L293D ICs, so it can control four DC motors or two stepper motors. One L293D IC controls port M1 and M2 and another controls ports M3 and M4.
74HC595 Shift Register The 74HC595 shift register is an 8-bit serial input and serial output shift register. It is used to extend the number of direction control pins of the L293D motor driver ICs. The eight parallel outputs of this shift register IC are connected to the input pins 2, 7, 10 and 15 of both L293D IC.
Reset Button To reset Arduino UNO, this is the same rest button which is available at Arduino UNO. It is just brought on the shield to make access easier.
Power LED It indicates that power supply for motors is available.
Resistor Array A 10k pull down network resistor is added to pull down the motor pin, when the board is powered up.
L293D Motor Driver Pinout
DC Motor Connections
- The shield features two L293D ICs, each with two output channels. These channels are accessible through four terminals labelled M1, M2, M3, and M4. There is ground connection between M1-M2 and M3-M4 connectors.
- You can connect up to four DC motors operating at voltages between 4.5V and 24V to these terminals.
- Each channel can supply up to 600 mA of continuous current (with a peak of 1.2A), depending on the capacity of the motor power supply.
Stepper Motor Connections
- The shield provides the connection for two stepper motors.
- One stepper motor can be connected to terminals M1-M2, and the other can be connected to terminals M3-M4.
Servo Motor Connections
- The shield provides 16-bit PWM output lines accessible via two 3-pin headers. A single servo motor comes with three wires so it allows the connection of two servo motors which can be connected at port Servo 1 and Servo 2. Servo 1 can be controlled using PWM pin 10 and Servo 2 can be controlled using PWM pin 9 of the Arduino.
- Servo motors are powered directly from the Arduino’s 5V supply, which can lead to issues such as overheating of the Arduino’s onboard 5V regulator thus the shield has a 100uF capacitor on the power pins of the servo headers to mitigate these issues. It is advisable to check the power ratings of the servo motor before connecting it with a shield.
Power Supply and Jumper Connections
The shield is compatible with motor voltages ranging from 4.5 to 24 volts. We can power the motors and shield in different ways. A power selection jumper (PWR) is provided near the power connector allowing you to choose between different ways to power the motor and shield.
Single Power Supply for Motors and Shield: If you’re using motors that operate within a 12V range, you can use a single DC power supply for both the motor driver and the Arduino. You can power the driver shield through the Arduino’s DC Jack. This method simplifies wiring by requiring only one power supply. Make sure that the power selection jumper is placed on the shield.
Separate Power Supplies for Motors and Shield: You can also use separate power supplies for the motors and the shield. First remove the jumper then power the Arduino through its USB and the shield through an external DC power supply connected to the two-terminal power connector labelled “EXT_PWR.” Make sure that the power selection jumper is not placed on the shield.
Warning
When using the external power supply terminals on the shield, it’s important to ensure that the power selection jumper is removed from the shield. Leaving the jumper in place can cause a short circuit between the two power supplies that could damage both the motor shield and the Arduino board.
Arduino Power Pins
Arduino 5V, GND and Vin pins are given for easy access. In above pic the pin labelled 9V is actually Vin pin. Whatever voltage is applied at power jack of Arduino, it is available at this Pin and when the power Jumper is connected, this Vin pin is connected to the Power supply pin of Motor on L293D IC.
Analog Input Pins
Analog Input Pins A0 to A5 is given for connecting with Arduino for easy access.
How many Arduino UNO pins are used by L293D Motor Driver Shield?
Pin D3, D4, D5, D6, D7, D8, D9, D10, D11, and D12 are used by the Shield.
Here is the schematic of L293D Motor Driver Shield:
Let us correlate above schematic with the pins on the shield.
Connector J1
Connector J3
Connector JP1
Normally we should not use the pins which are used to run the shield. If we have to use those pins then we have to judiciously use the pins e.g., if we are using only M1 and M2 port of the shield then we can use other pins of Arduino connected to port M3 and M4 and SER1 and SERVO_2.
If we are using any DC motor port weather M1, M2, M3 or M4 we can’t use pins D4, D7, D8 and D12 as it is used by 74HC595 serial shift register IC.
Controlling DC Motor with Arduino UNO and L293D Motor Driver Shield
Let’s learn how to control 5V DC motors using Arduino and L293D shield. We will be controlling the direction of rotation and speed of the Motor.
Hardware and Software Requirements
Hardware Required
Software Required
- Arduino IDE, Version 2.1.1 or above installed on your PC
- Adafruit Motor Shield Library(V1) by Adafruit version 1.0.1.
- LiquidCrystal I2C Library by Frank de Barbander 1.1.2
Installing AFMotor Library
To communicate with the shield, the first step is to install the AFMotor.h library. This library enables us to control DC, stepper, and servo motors using straightforward commands.
To install the AFMotor library, you can follow these steps:
- Open Arduino IDE.
- Navigate to Sketch > Include Library > Manage Libraries (or press ctrl + shift + I).
- In the search bar, enter AF motor V1.
- Look for Adafruit Motor Shield library (V1 Firmware) by Adafruit.
- Click on it and choose Install.
Installing LCD Library
To communicate with the LCD, we need to install the LiquidCrystal library. Here are the steps to install the LiquidCrystal library:
- Open Arduino IDE.
- Navigate to Sketch > Include Library > Manage Libraries (or press ctrl + shift + I).
- In Library Manager enter LiquidCrystal I2C into the search bar.
- Click on the library, and choose Install.
Commonly Used Functions of AFMotor Library for running DC motor
AF_DCMotor Class
Creates an instance of the AF_DCMotor class, representing a DC motor connected to the motor shield.
Syntax
1 AF_DCMotor motorname(portnum);
Parameters
- portnum: It can be 1, 2, 3 or 4 based on port (M1, M2, M3 and M4 respectively) on which DC motor is connected.
setSpeed()
The setSpeed() function sets the speed of the motor.
Syntax
1 motorname.setSpeed(speedValue);
Parameters
- speedValue: A value ranging from 0 (stopped) to 255 (maximum speed).
run()
Controls the direction and state of the motor.
Syntax
1 motorname.run(cmd)
Parameters
- cmd: The command to control the motor, which can be FORWARD, BACKWARD, or RELEASE.
Wiring of DC motor with L293D shield and Arduino UNO
In the above wiring diagram, the L293D Shield shown beside the Arduino should be mounted on the Arduino. It is shown like this for simplicity and for showing button and POT connections.
Pin A0 is the Analog input pin connected with the POT’s middle pin. The other two POT pins are connected to the Arduino’s VCC and GND pins. This POT changes the voltage on the A0 pin. According to the voltage on the A0 pin the speed of the motor changes higher the voltage higher the speed.
As pin numbers D3, D4, D5, D6, D7, D8, D9, D10, D11, and D12 are used by the Shield and D0 and D1 are the Serial pins. D13 is connected to the on-board LED. There is only 1 digital pin left i.e., D2. Hence in this article, we are using Analog Input pins of Arduino as digital input pins.
Hence for the button connections A1, A2, and A3 pins are used. The button connected to the A1 pin is responsible for clockwise rotation, A2 is for Anti-clockwise rotation and A3 is to stop the motor.
The 16×2 LCD is connected to the I2C pins of Arduino UNO to display speed and direction of rotation of motor. 5V DC motor is connected at port M3 of the shield. External 5V DC supply is provided at the EXT_PWR pin of the Shield via DC Jack.
❕Note
Make sure that the Jumper is not connected to the PWR pins of the shield.
The connections are shown in the following table:
Arduino Code
This following code will show you how to control a DC motor using the L293D motor driver shield. The motor’s direction and speed are controlled using three buttons (for forward, reverse, and stop) and a potentiometer to adjust the speed. LCD is used to display the motor’s direction and speed.
Code
1 /* 2 Interfacing DC Motor with Arduino UNO using L293D motor Driver shield 3 by www.playwithcircuit.com 4 */ 5 6 #include <AFMotor.h> 7 // Library to run DC Motor Using Motor Driver Shield 8 #include <LiquidCrystal_I2C.h> 9 // Library to Run I2C LCD 10 11 LiquidCrystal_I2C lcd(0x27, 16, 2); // Format -> (Address,Columns,Rows ) 12 13 // Create the motor object connected to M3 14 AF_DCMotor motor(3); 15 16 // Define button pins 17 const int forwardButtonPin = A1; 18 const int reverseButtonPin = A2; 19 const int stopButtonPin = A3; 20 21 // Define potentiometer pin 22 const int potPin = A0; 23 24 // Variables to store motor state and direction 25 bool motorRunning = false; 26 int motorDirection = BACKWARD; // FORWARD or BACKWARD 27 28 // Read the potentiometer value 29 int potValue; 30 int motorSpeed; 31 32 // Variable to store button states 33 bool forwardButtonState; 34 bool stopButtonState; 35 bool reverseButtonState; 36 37 // Inline function to check if button is pressed packed with debouncing logic 38 inline bool chkButtonState(int pinNum, int checkState, int debounceDelay) { 39 if (((digitalRead(pinNum) == checkState) ? true : false) == true) { 40 delay(debounceDelay); 41 return (((digitalRead(pinNum) == checkState) ? (true) : (false)) == true); 42 } else { 43 return false; 44 } 45 } 46 47 void setup() { 48 // initialize the lcd 49 lcd.init(); 50 // Turn on the Backlight 51 lcd.backlight(); 52 // Clear the display buffer 53 lcd.clear(); 54 55 // Set cursor (Column, Row) 56 lcd.setCursor(0, 0); 57 lcd.print("DC Motor using"); 58 lcd.setCursor(0, 1); 59 lcd.print("L293D Shield"); 60 61 // Set button pins as inputs 62 pinMode(forwardButtonPin, INPUT_PULLUP); 63 pinMode(stopButtonPin , INPUT_PULLUP); 64 pinMode(reverseButtonPin, INPUT_PULLUP); 65 66 // Start with motor off 67 motor.setSpeed(0); 68 motor.run(RELEASE); 69 70 delay(2000); 71 72 // Clear the display buffer 73 lcd.clear(); 74 // Set cursor (Column, Row) 75 lcd.setCursor(0, 0); 76 lcd.print("Motor Direction:"); 77 lcd.setCursor(0, 1); 78 lcd.print("Stopped "); 79 } 80 81 void loop() { 82 // Read the potentiometer value for changing speed as per Analog input 83 potValue = analogRead(potPin); 84 motorSpeed = map(potValue, 0, 1023, 0, 255); 85 86 // Read the button states 87 forwardButtonState = chkButtonState(forwardButtonPin, LOW, 20); 88 reverseButtonState = chkButtonState(reverseButtonPin, LOW, 20); 89 stopButtonState = chkButtonState(stopButtonPin, LOW, 20); 90 91 // check for Forward run 92 if (forwardButtonState && (!motorRunning || motorDirection == BACKWARD)) { 93 // Set cursor (Column, Row) 94 lcd.setCursor(0, 1); 95 lcd.print("Clock "); 96 if (motorDirection == BACKWARD) { 97 motor.setSpeed(0); 98 motor.run(RELEASE); 99 delay(1000); 100 } 101 motorRunning = true; 102 motorDirection = FORWARD; 103 motor.setSpeed(motorSpeed); 104 motor.run(FORWARD); 105 } 106 107 // check for Reverse run 108 else if (reverseButtonState && (!motorRunning || motorDirection == FORWARD)) { 109 // Set cursor (Column, Row) 110 lcd.setCursor(0, 1); 111 lcd.print("Anti-Clk"); 112 if (motorDirection == FORWARD) { 113 motor.setSpeed(0); 114 motor.run(RELEASE); 115 delay(1000); 116 } 117 motorRunning = true; 118 motorDirection = BACKWARD; 119 motor.setSpeed(motorSpeed); 120 motor.run(BACKWARD); 121 } 122 123 // Stop motor 124 else if (stopButtonState && motorRunning) { 125 // Set cursor (Column, Row) 126 lcd.setCursor(0, 1); 127 lcd.print("Stopped "); 128 motorRunning = false; 129 motor.setSpeed(0); 130 motor.run(RELEASE); 131 } 132 133 // Adjust motor speed if running and display speed on LCD 134 if (motorRunning) { 135 motor.setSpeed(motorSpeed); 136 // Set cursor (Column, Row) 137 lcd.setCursor(9, 1); 138 lcd.print("SPD:"); 139 lcd.print(((motorSpeed*100)/255)); 140 lcd.print("% "); 141 } 142 }
Code Explanation
Firstly we include AFMotor library and LCD library.
Then we create an LCD object with the I2C address 0x27, and it is configured for 16 columns and 2 rows.
Then we create a motor object AF_DCMotor and assign it to port M3 on the motor shield.
Next we define Pins and Variables:
- Button Pins: We define three analog pins (A1, A2, A3) for the forward, reverse, and stop buttons.
- Potentiometer Pin: We define an analog pin (A0) for the potentiometer.
- Motor State Variables: We define variables to keep track of whether the motor is running (motorRunning), the direction of the motor (motorDirection), and to store the potentiometer value and the motor speed.
- Button State Variables: Variables are defined to store the current state of each button (pressed or not).
Then we use chkButtonState function to check the state of a button with debouncing logic. This ensures that the button press is stable and not affected by mechanical noise. The function reads the button state, adds a delay for debouncing, and reads the state again to confirm the button press.
In the Setup function, we initialize the LCD, configure the button pins as inputs with internal pull-up resistors and initialize the motor.
In the Loop function,
- We read the potentiometer value and map it to a range of 0-255 for motor speed. Then we read the states of the forward, reverse, and stop buttons with debouncing.
- If the forward button is pressed and the motor is either not running or running backward, the motor will start running forward. The LCD displays “Clock” (for Clockwise).
- If the reverse button is pressed and the motor is either not running or running forward, the motor will start running backward. The LCD displays “Anti-Clk” (for Anti-Clockwise).
- If the stop button is pressed and the motor is running, the motor stops. The LCD displays “Stopped”.
- Adjusting Motor Speed: If the motor is running, the speed is continuously adjusted based on the potentiometer value. The speed percentage is calculated and displayed on the LCD.
💡Must Read
DC Motor Control with Arduino
This article will give you more in-depth information about DC Motor, its working and interfacing it with Arduino using L293D IC.
Controlling Micro Servo Motor with Arduino UNO and L293D Motor Driver Shield
Let’s learn how to control 5V Micro Servo Motor SG90 using Arduino and L293D shield. We will be controlling the direction of the Arm of the Servo Motor and the speed of the Motor.
Hardware and Software Requirements
Hardware Required
Software Required
- Arduino IDE, Version 2.1.1 or above installed on your PC
- Servo library by Arduino (inbuilt Library).
- LiquidCrystal I2C Library by Frank de Barbander 1.1.2
Wiring of Servo Motor with L293D shield and Arduino UNO
In the above wiring diagram, the Shield shown beside the Arduino should be mounted on the Arduino. It is shown like this for simplicity and for showing button and POT connections.
Pin A0 is the Analog input pin connected with the POT’s middle pin.
The other two POT pins are connected to the Arduino’s VCC and GND pin.
This POT changes the voltage on the A0 pin. According to the voltage on the A0 pin the speed of the motor changes higher the voltage higher the speed.
We are using Analog Input pins of Arduino as digital input pins.
Hence for the button connections A1 and A2 pins are used. The button connected to the A1 pin is responsible for moving Arm in the forward direction (from left to right) and the button connected to the A2 pin is responsible for moving Arm in the backward direction (from right to left). As long as the button is pressed the arm moves. When the circuit is powered up, the arm moves to the centre.
The 16×2 LCD is connected to the I2C pins of Arduino UNO to display speed and motor direction.
5V SG 90 Servo Motor is connected at port SER1 of the shield. It will get power from the Arduino’s 5V pin and its control (orange wire) pin is connected to PWM pin 10 of Arduino.
The connections are shown in the following table:
Arduino Code
The following Arduino sketch will show you how to control a Micro Servo Motor SG90 using an L293D Motor Driver Shield and displays the motor’s status on an I2C LCD.
The motor’s direction is controlled using two buttons (for forward and reverse), and the speed is adjusted using a potentiometer.
Code
1 /* 2 Interfacing Micro Servo Motor SG90 with Arduino UNO using L293D motor Driver shield 3 by www.playwithcircuit.com 4 */ 5 #include <Servo.h> 6 // Library to run Servo Motor 7 #include <LiquidCrystal_I2C.h> 8 // Library to Run I2C LCD 9 10 LiquidCrystal_I2C lcd(0x27, 16, 2); // Format -> (Address,Columns,Rows ) 11 12 // Create the servo object connected to SER1 13 Servo servo; 14 15 // Define button pins 16 const int forwardButtonPin = A1; 17 const int reverseButtonPin = A2; 18 19 // Variable so save current Servo Angle 20 int servoAngle; 21 22 // Define potentiometer pin 23 const int potPin = A0; 24 25 // Read the potentiometer value 26 int potValue; 27 // Save motor Speed 28 int motorSpeed; 29 // Save previous motor Speed 30 int previousSpeed; 31 // counter to clear speed when motor is stopped 32 int counter = 100;; 33 34 void setup() { 35 // initialize the lcd 36 lcd.init(); 37 // Turn on the Backlight 38 lcd.backlight(); 39 // Clear the display buffer 40 lcd.clear(); 41 42 // Set cursor (Column, Row) 43 lcd.setCursor(0, 0); 44 lcd.print("Servo Motor using"); 45 lcd.setCursor(0, 1); 46 lcd.print("L293D Shield"); 47 48 // Set the arm in middle i.e at 90 degree 49 servoAngle = 90; 50 51 // Set button pins as inputs 52 pinMode(forwardButtonPin, INPUT_PULLUP); 53 pinMode(reverseButtonPin, INPUT_PULLUP); 54 55 // Initialize the servo motor, Pin 10 is connected to the PWM pin of Ser1 port of Arduino Shield 56 servo.attach(10); 57 servo.write(servoAngle); // Set servo to neutral position (90 degrees) 58 59 delay(2000); 60 61 // Clear the display buffer 62 lcd.clear(); 63 // Set cursor (Column, Row) 64 lcd.setCursor(0, 0); 65 lcd.print("Motor Direction:"); 66 lcd.setCursor(0, 1); 67 lcd.print("Stopped "); 68 } 69 70 void displaySpeed(void){ 71 // Set cursor (Column, Row) 72 lcd.setCursor(9, 1); 73 lcd.print("SPD:"); 74 lcd.print(((motorSpeed*100)/10)); 75 lcd.print("% "); 76 counter = 0; 77 } 78 79 void loop() { 80 // Read the potentiometer value for changing speed as per Analog input 81 potValue = analogRead(potPin); 82 motorSpeed = map(potValue, 0, 1023, 0, 10); 83 84 // Read the button states 85 bool forwardButtonState = (digitalRead(forwardButtonPin) == LOW); 86 bool reverseButtonState = (digitalRead(reverseButtonPin) == LOW); 87 88 // Control the servo motor 89 if (forwardButtonState) { 90 // Set cursor (Column, Row) 91 lcd.setCursor(0, 1); 92 lcd.print("Forward "); 93 // Increase Servo Angle 94 servoAngle+=motorSpeed; 95 if(servoAngle>180) 96 { 97 servoAngle = 180; 98 } 99 displaySpeed(); 100 } else if (reverseButtonState) { 101 // Set cursor (Column, Row) 102 lcd.setCursor(0, 1); 103 lcd.print("Backward"); 104 // Decrease Servo Angle 105 servoAngle-=motorSpeed; 106 if(servoAngle<0) 107 { 108 servoAngle = 0; 109 } 110 displaySpeed(); 111 } 112 else 113 { 114 if(counter++ > 100) 115 { 116 lcd.setCursor(0, 1); 117 lcd.print("Stopped "); 118 counter = 101; 119 } 120 else 121 { 122 // Set cursor (Column, Row) 123 lcd.setCursor(0, 1); 124 lcd.print("Stopped "); 125 } 126 127 if(previousSpeed != motorSpeed) 128 { 129 displaySpeed(); 130 previousSpeed = motorSpeed; 131 } 132 } 133 servo.write(servoAngle); // Adjust as needed for your servo's forward position 134 }
Code Explanation
The sketch begins by including two Libraries
- Servo.h for controlling the servo motor.
- LiquidCrystal_I2C.h for controlling the LCD display with I2C communication.
Then we create an LCD object with the I2C address 0x27, and it is configured for 16 columns and 2 rows. Next we create a servo object connected to the PWM pin of the SER1 port on the motor shield.
Next we define two analog pins (A1, A2) for the forward and backward buttons, an analog pin (A0) for the potentiometer. Then we define variables to store the current angle of the servo motor, potentiometer reading and previous motor speed and a counter.
In the Setup Function, we initialize LCD, configure button pins as inputs with internal pull-up resistors. Then we initialize the servo attached to pin 10 (connected to the PWM pin of SER1 port) and set it to the middle position (90 degrees). Then the initial motor direction (“Stopped”) is displayed on the LCD. The Display Speed function updates the LCD to show the current speed percentage of the servo motor.
In the Loop Function, first we read the potentiometer value and map it to a range of 0-10, which corresponds to the motor speed. Then we read the states of the forward and reverse buttons.
- If the forward button is pressed, the motor arm moves forward. The LCD displays “Forward”. Then the servo angle is increased by the motor speed. If the angle exceeds 180 degrees, it is capped at 180 degrees. The displaySpeed function is called to update the speed on the LCD.
- If the reverse button is pressed, the motor arm runs backward. The LCD displays “Backward”. The servo angle is decreased by the motor speed. If the angle is below 0 degrees, it is set to 0 degrees. The displaySpeed function is called to update the speed on the LCD.
- If neither button is pressed, the motor is stopped. The LCD displays “Stopped” and the counter is incremented. If the counter exceeds 100, the speed indication is removed from LCD.
- If the previous speed is different from the current speed, the displaySpeed function is called to update the speed on the LCD. The servo angle is updated to the new position based on the angle calculated.
💡Must Read
Servo Motor Control with Arduino
This article will give you more in-depth information about Servo Motor, its working and using the inbuilt Servo library of Arduino IDE.
Controlling 28BYJ-48 Stepper Motor with Arduino UNO and L293D Motor Driver Shield
Let’s learn how to control a unipolar 5V Stepper motor using Arduino and L293D shield. We will be controlling the direction of rotation and speed of the Motor.
Hardware and Software Requirements
Hardware Required
Software Required
- Arduino IDE, Version 2.1.1 or above installed on your PC
- Adafruit Motor Shield Library(V1) by Adafruit version 1.0.1.
- LiquidCrystal I2C Library by Frank de Barbander 1.1.2
Commonly Used Functions of AFMotor Library for running Stepper motor
AF_Stepper Class
The AF_Stepper class provides single and multi-step control for up to 2 stepper motors
Syntax
1 AF_Stepper motorname(steps, portnumber)
Parameters
- steps: the number of steps motor takes for one complete 360 degree rotation.
- portnumber: It can be
1 -> when stepper motor is connected to M1-M2
2-> when stepper motor is connected to M3-M4
step()
This function sets the stepping properties of the motor. You can step multiple steps at a time with this function.
Syntax
1 motorname.step(steps, direction, style);
Parameters
- steps: Number of steps to take.
- dir: Direction of the movement (FORWARD or BACKWARD).
- style: Specifies the stepping style. The values for ‘style’ are:
- SINGLE: Energizes one coil at a time.
- DOUBLE: Energizes two coils simultaneously for increased torque.
- INTERLEAVE: Alternates between single and double steps, creating a half-step for smoother operation but speed is reduced by half too.
- MICROSTEP: Ramps adjacent coils up and down, creating multiple micro-steps for smoother rotation, but with a reduced torque.
setSpeed()
It sets the speed of the motor.
Syntax
1 motorname.setSpeed(speed)
Parameter
- speed: The speed of motor in RPM(Rotations per minute).
onestep
If you want a lot of control over your steppers, you can use the oneStep function which will make a single step in the style you want.
Syntax
1 motorname.onestep(direction, stepstyle)
Parameters:
- direction: Determines the motor’s rotation direction (FORWARD or BACKWARD).
- stepstyle: Specifies the stepping method.
release()
This function releases the holding torque on the motor. This decreases heating and current demand, but the motor will not actively resist rotation.
Syntax
1 motorname.release();
Wiring of 28BYJ-48 Stepper motor with L293D shield and Arduino UNO
In the above wiring diagram, the Shield shown beside the Arduino should be mounted on the Arduino. It is shown like this for simplicity and for showing button and POT connections.
Pin A0 is the Analog input pin connected with the POT’s middle pin.
The other two POT pins are connected to the Arduino’s VCC and GND pins.
This POT changes the voltage on the A0 pin. According to the voltage on the A0 pin the speed of the motor changes higher the voltage higher the speed.
The button connected to the A1 pin is responsible for clockwise rotation, A2 is for Anti-clockwise rotation and A3 is to stop the motor.
The 16×2 LCD is connected to the I2C pins of Arduino UNO to display speed and motor’s direction of rotation.
A 5V unipolar stepper motor is connected at ports M3 and M4 of the shield. External 5V DC supply is provided at the EXT_PWR pin of the Shield via DC Jack.
Make sure to connect the wires in the correct order, or else the motor can be damaged.
The connections are shown in the following table:
Arduino Code
The following code shows how to control a stepper motor using an Arduino UNO and an L293D motor driver shield. It includes a potentiometer for speed control and an I2C LCD for displaying the motor status. The motor can be controlled to move forward or backward using buttons.
1 /* 2 Interfacing Stepper Motor 28BYJ-48 with Arduino UNO using L293D motor Driver shield 3 by www.playwithcircuit.com 4 */ 5 6 #include <AFMotor.h> 7 // Library to run Stepper Motor Using Motor Driver Shield 8 #include <LiquidCrystal_I2C.h> 9 // Library to Run I2C LCD 10 11 LiquidCrystal_I2C lcd(0x27, 16, 2); // Format -> (Address,Columns,Rows ) 12 13 // Create the stepper motor object connected to M3 and M4 14 AF_Stepper motor(2048, 2); // 2048 steps per rotation for 28BYJ-48, connected to motor ports 3 and 4 15 16 // Define button pins 17 const int forwardButtonPin = A1; 18 const int reverseButtonPin = A2; 19 const int stopButtonPin = A3; 20 21 // Define potentiometer pin 22 const int potPin = A0; 23 24 // Variables to store motor state and direction 25 bool motorRunning = false; 26 int motorDirection = BACKWARD; // FORWARD or BACKWARD 27 28 // Read the potentiometer value 29 int potValue; 30 int motorSpeed; 31 32 // Variable to store button states 33 bool forwardButtonState; 34 bool stopButtonState; 35 bool reverseButtonState; 36 37 // Inline function to check if button is pressed packed with debouncing logic 38 inline bool chkButtonState(int pinNum, int checkState, int debounceDelay) { 39 if (((digitalRead(pinNum) == checkState) ? true : false) == true) { 40 delay(debounceDelay); 41 return (((digitalRead(pinNum) == checkState) ? (true) : (false)) == true); 42 } else { 43 return false; 44 } 45 } 46 47 void setup() { 48 // initialize the lcd 49 lcd.init(); 50 // Turn on the Backlight 51 lcd.backlight(); 52 // Clear the display buffer 53 lcd.clear(); 54 55 // Set cursor (Column, Row) 56 lcd.setCursor(0, 0); 57 lcd.print("Stepper Motor"); 58 lcd.setCursor(0, 1); 59 lcd.print("using Shield"); 60 61 // Set button pins as inputs 62 pinMode(forwardButtonPin, INPUT_PULLUP); 63 pinMode(stopButtonPin, INPUT_PULLUP); 64 pinMode(reverseButtonPin, INPUT_PULLUP); 65 66 // Start with motor off 67 motor.setSpeed(0); 68 motor.release(); // Stop the motor 69 70 delay(2000); 71 72 // Clear the display buffer 73 lcd.clear(); 74 // Set cursor (Column, Row) 75 lcd.setCursor(0, 0); 76 lcd.print("Motor Direction:"); 77 lcd.setCursor(0, 1); 78 lcd.print("Stopped "); 79 } 80 81 void loop() { 82 // Read the potentiometer value for changing speed as per Analog input 83 potValue = analogRead(potPin); 84 motorSpeed = map(potValue, 0, 1023, 3, 15); 85 86 // Read the button states 87 forwardButtonState = chkButtonState(forwardButtonPin, LOW, 20); 88 reverseButtonState = chkButtonState(reverseButtonPin, LOW, 20); 89 stopButtonState = chkButtonState(stopButtonPin, LOW, 20); 90 91 // check for Forward run 92 if (forwardButtonState && (!motorRunning || motorDirection == BACKWARD)) { 93 // Set cursor (Column, Row) 94 lcd.setCursor(0, 1); 95 lcd.print("Clock "); 96 if (motorDirection == BACKWARD) { 97 motor.setSpeed(0); 98 motor.release(); // Stop the motor 99 delay(1000); 100 } 101 motorRunning = true; 102 motorDirection = FORWARD; 103 motor.setSpeed(motorSpeed); 104 motor.step(32, FORWARD, SINGLE); // Move 32 steps forward single step at a time 105 } 106 // check for Reverse run 107 else if (reverseButtonState && (!motorRunning || motorDirection == FORWARD)) { 108 // Set cursor (Column, Row) 109 lcd.setCursor(0, 1); 110 lcd.print("Anti-Clk"); 111 if (motorDirection == FORWARD) { 112 motor.setSpeed(0); 113 motor.release(); // Stop the motor 114 delay(1000); 115 } 116 motorRunning = true; 117 motorDirection = BACKWARD; 118 motor.setSpeed(motorSpeed); 119 motor.step(32, BACKWARD, SINGLE); // Move 32 steps backward single step at a time 120 } 121 // Stop motor 122 else if (stopButtonState && motorRunning) { 123 // Set cursor (Column, Row) 124 lcd.setCursor(0, 1); 125 lcd.print("Stopped "); 126 motorRunning = false; 127 motor.setSpeed(0); 128 motor.release(); // Stop the motor 129 } else if (motorRunning) { 130 if (motorDirection == FORWARD) { 131 motor.step(32, FORWARD, SINGLE); // Continue moving forward 132 } else { 133 motor.step(32, BACKWARD, SINGLE); // Continue moving backward 134 } 135 motor.setSpeed(motorSpeed); 136 // Set cursor (Column, Row) 137 lcd.setCursor(9, 1); 138 lcd.print("SPD:"); 139 lcd.print(((motorSpeed * 100) / 15)); 140 lcd.print("% "); 141 } 142 }
Code Explanation
First we include AFMotor and LiquidCrystal libraries, and initialize the LCD.
Then we create a stepper motor object with 2048 steps per rotation, connected to ports M3 and M4 on the motor driver shield.
Then we define the pins for the forward, reverse, and stop buttons as well as the potentiometer.
Then we initialize the variables to store the motor state, direction, speed, and button states.
In the loop sections of the code, we read the potentiometer value from analog pin A0 and mapped it to a speed range of 3 to 15. Then we check the states of the forward, reverse, and stop buttons.
- If Forward Button is pressed, the motor direction is set to forward, speed is set, and the motor moves one step forward.
- If Reverse Button is pressed, the motor direction is set to reverse, speed is set, and the motor moves one step backward.
- If Stop Button is pressed, the motor stops.
If the motor is running, it continues to move in the set direction at the set speed, and the speed is displayed on the LCD.
💡Must Read
Stepper Motor Control with Arduino
This article will give you more in-depth information about stepper motor, its working, operating modes and how to control it with Arduino using ULN2003 driver.