Search

Arduino Motor Control: L293D Motor Driver for DC Motors

If you’re preparing to build your new robot companion, one essential skill to master is controlling DC motors. The most straightforward and cost-effective method for this is by using the L293D Motor Driver IC in conjunction with the Arduino. This versatile IC allows you to manage the speed and direction of two DC motors effortlessly.

Moreover, the L293D Motor Driver IC offers an added advantage—it can also control a unipolar stepper motor such as the 28BYJ-48 or a bipolar stepper motor like the NEMA 17. This flexibility makes it a valuable component for a wide range of motor control applications in your robotic projects.

Controlling a DC Motor

To have precise control over a DC motor, we need to manage both its speed and rotation direction. This can be achieved by combining two fundamental techniques.

PWM – to control speed

The speed of a DC motor can be regulated by altering its input voltage. One commonly used method for this purpose is PWM (Pulse Width Modulation).

PWM involves sending a series of ON-OFF pulses, where the average value of the input voltage is adjusted. The width of these pulses, known as the “Duty Cycle,” determines the average voltage applied to the DC motor.

A higher duty cycle results in a higher average voltage, leading to increased speed, while a shorter duty cycle lowers the average voltage, resulting in decreased speed.

The diagram below illustrates PWM with different duty cycles and their corresponding average voltages.

H-Bridge – to control the rotation direction

The spinning direction of a DC motor can be controlled by changing the polarity of its input voltage. This is typically achieved using an H-bridge circuit.

The H-bridge circuit comprises four switches arranged in an H-like configuration, with the motor placed at the center.

By selectively closing specific switches at a time, the polarity of the voltage applied to the motor can be reversed. This reversal causes the motor to change its spinning direction.

The animation below demonstrates the functioning of the H-bridge circuit, allowing precise control over the rotation direction of the DC motor.

L293D Motor Driver IC

The L293D is a dual-channel H-Bridge motor driver integrated circuit (IC) commonly used in robotics and electronics projects to control DC motors and other inductive loads. It is designed to provide an easy and efficient way to control the speed and direction of two DC motors or a single stepper motor.

The IC comes with four H-Bridge switches that allow it to control the direction of the current flowing through the connected motors. By appropriately activating these switches, the L293D arduino can change the polarity of the voltage applied to the motors, thereby determining their spinning direction. This feature makes it an ideal choice for creating two-wheeled robotic platforms and other motion control systems.

One of the key advantages of the L293D is its capability to handle a wide range of voltages, from 4.5V to 36V, making it compatible with various motor power requirements. Each channel of the driver can deliver a peak output current of up to 1.2A, enabling it to drive small to medium-sized DC motors efficiently.

Furthermore, the L293D includes built-in protection in the form of kick-back diodes. These diodes serve to suppress voltage spikes and protect the IC from potential damage that may occur when a motor is turned off, preventing harmful reverse currents.

Overall, the L293D motor driver IC is a reliable and versatile choice for motor control applications, commonly used in hobbyist and educational projects to add motion and automation to various devices.

Technical Specifications

Here are the specifications:

Motor output voltage4.5V – 36V
Logic input voltage5V
Output Current per channel600mA
Peak Output Current per Channel1.2A

For more details, please refer below datasheet.

L293D Motor Driver IC Pinout

The L293D IC has a total of 16 pins that connect it to the outside world. The pinout is as follows:

Let’s get acquainted with all the pins one by one.

Power Pins

The L293D motor driver IC has two power-related pins, namely VS and VSS.

  1. VS (Vcc2) Pin: This pin provides the power supply to the internal H-Bridge of the L293D IC, which is responsible for driving the connected motors. It is the main power input for the motors. You can connect an input voltage ranging from 4.5V to 36V to this pin. The voltage applied to this pin determines the maximum voltage that the motors can receive.
  2. VSS (Vcc1) Pin: This pin supplies power to the internal logic circuitry of the L293D IC. It needs to be connected to a stable 5V voltage source. This voltage is used for the operation of the internal control logic within the IC.

Additionally, the L293D IC has multiple GND (Ground) pins. All four GND pins are internally connected and serve as a common ground reference for the IC and the motors. They also help dissipate the heat generated by the IC, especially under high load conditions, ensuring stable operation. Connecting the GND pins properly is essential for the reliable functioning of the motor driver and the connected motors.

Output Pins

The L293D motor driver IC has four output pins, which are used to connect and control the motors. These output pins are divided into two sets, one for each motor (Motor A and Motor B). The pinout is as follows:

Motor A:

  • OUT1: Output 1 for Motor A.
  • OUT2: Output 2 for Motor A.

Motor B:

  • OUT3: Output 1 for Motor B.
  • OUT4: Output 2 for Motor B.

Each pair of output pins (OUT1 and OUT2 for Motor A, and OUT3 and OUT4 for Motor B) are used to drive a DC motor connected to the L293D IC. These pins control the direction of rotation and the speed of the motors.

By providing appropriate logic levels (HIGH or LOW) to these output pins, you can control the H-Bridge circuit inside the L293D IC, which, in turn, controls the direction of current flow through the connected motor. Depending on the input signals, the motor can rotate in forward, reverse, or stop states.

The L293D motor driver arduino can handle motors with voltages ranging from 5V to 36V. It is capable of delivering up to 600mA of current to each motor channel. However, the actual current delivered to the motor depends on the system’s power supply and the motor’s characteristics.

When using the L293D IC, it’s important to connect the motors properly to the correct output pins (OUT1/OUT2 for Motor A and OUT3/OUT4 for Motor B) and apply the appropriate control signals to achieve the desired motor rotation and speed.

Direction Control Pins

The L293D motor driver IC has two sets of direction control pins, which are used to control the spinning direction of each motor (Motor A and Motor B). These direction control pins are used to manipulate the switches of the H-Bridge circuit inside the L293D IC, determining the direction of current flow through the connected motors. The pinout for direction control is as follows:

For Motor A:

  • IN1: Input 1 for Motor A.
  • IN2: Input 2 for Motor A.

For Motor B:

  • IN3: Input 1 for Motor B.
  • IN4: Input 2 for Motor B.

Each motor has two direction control pins. By applying logic HIGH (5V) or logic LOW (Ground) to these pins, you can control the spinning direction of the respective motor. The table below illustrates how to control the direction using the direction control pins:

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

For example, if you set IN1 to HIGH and IN2 to LOW for Motor A, it will spin forward. If you set IN1 to LOW and IN2 to HIGH, it will spin in the reverse direction. Setting both IN1 and IN2 to LOW will stop the motor by applying a brake, and setting both to HIGH will also stop the motor, but this time without braking.

By appropriately configuring the direction control pins for each motor, you can control the rotation direction of your connected DC motors using the L293D motor driver IC.

Speed Control Pins

The L293D motor driver IC has two speed control pins, labeled as ENA and ENB, which are used to enable or disable the motors and control their speed. These pins allow you to adjust the PWM (Pulse Width Modulation) signal to regulate the average voltage applied to the connected motors, thus controlling their speed. The pinout for speed control is as follows:

  • ENA: Speed control pin for Motor A.
  • ENB: Speed control pin for Motor B.

To control the speed of the motors, you need to apply a PWM signal to these pins. By varying the duty cycle of the PWM signal, you can adjust the average voltage supplied to the motors, which directly affects their speed. The higher the duty cycle, the higher the average voltage, and the faster the motor will spin. Conversely, a lower duty cycle will result in a lower average voltage and slower motor speed.

Typically, you can use the analogWrite() function in Arduino to generate the PWM signal for speed control. The range of duty cycle values is from 0 (0% duty cycle – motor stopped) to 255 (100% duty cycle – maximum speed).

For example, to set the speed of Motor A, you can use the analogWrite() function like this:

analogWrite(ENA, speedValue); // 'speedValue' is the desired duty cycle value (0 to 255).

Similarly, you can set the speed of Motor B using the ENB pin in the same manner.

Keep in mind that the actual speed of the motor will depend on the motor’s characteristics and the applied power supply voltage. The L293D IC can deliver up to 600mA to the motors per channel, but the actual current supplied to the motor will depend on the power supply and the load conditions.

By manipulating the PWM signal on the speed control pins, you can easily control the speed of your connected DC motors using the L293D motor driver IC.

Wiring a L293D Motor Driver IC to an Arduino

Now that we know everything about the IC, we can start connecting it to our Arduino!

Let’s start by connecting the power supply to the motors. In our experiment we are using DC gearbox motors (also known as ‘TT’ motors) commonly found in two-wheel-drive robots. They are rated for 3 to 12V. Therefore, we will connect the external 5V power supply to the VS (Vcc2) pin.

Next, we need to supply 5V to the logic circuitry of the L293D arduino. Connect the VSS (Vcc1) pin to the 5V output on the Arduino. And make sure your circuit and Arduino share a common ground.

Now connect the L293D IC’s Input and Enable pins (ENA, IN1, IN2, IN3, IN4 and ENB) to the six Arduino digital output pins (9, 8, 7, 5, 4 and 3). Note that Arduino output pins 9 and 3 are both PWM-enabled.

Finally, connect one motor to OUT1 and OUT2 and the other motor to OUT3 and OUT4. You can interchange the connections of your motor. There is technically no right or wrong way.

When you are done you should have something that looks similar to the illustration shown below.

Arduino Example Code

The following sketch will give you a complete understanding on how to control the speed and spinning direction of a DC motor with the L293D motor driver IC and will serve as the basis for more practical experiments and projects.

// Motor A connections
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor B connections
int enB = 3;
int in3 = 5;
int in4 = 4;

void setup() {
	// Set all the motor control pins to outputs
	pinMode(enA, OUTPUT);
	pinMode(enB, OUTPUT);
	pinMode(in1, OUTPUT);
	pinMode(in2, OUTPUT);
	pinMode(in3, OUTPUT);
	pinMode(in4, OUTPUT);
	
	// Turn off motors - Initial state
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

void loop() {
	directionControl();
	delay(1000);
	speedControl();
	delay(1000);
}

// This function lets you control spinning direction of motors
void directionControl() {
	// Set motors to maximum speed
	// For PWM maximum possible values are 0 to 255
	analogWrite(enA, 255);
	analogWrite(enB, 255);

	// Turn on motor A & B
	digitalWrite(in1, HIGH);
	digitalWrite(in2, LOW);
	digitalWrite(in3, HIGH);
	digitalWrite(in4, LOW);
	delay(2000);
	
	// Now change motor directions
	digitalWrite(in1, LOW);
	digitalWrite(in2, HIGH);
	digitalWrite(in3, LOW);
	digitalWrite(in4, HIGH);
	delay(2000);
	
	// Turn off motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

// This function lets you control speed of the motors
void speedControl() {
	// Turn on motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, HIGH);
	digitalWrite(in3, LOW);
	digitalWrite(in4, HIGH);
	
	// Accelerate from zero to maximum speed
	for (int i = 0; i < 256; i++) {
		analogWrite(enA, i);
		analogWrite(enB, i);
		delay(20);
	}
	
	// Decelerate from maximum speed to zero
	for (int i = 255; i >= 0; --i) {
		analogWrite(enA, i);
		analogWrite(enB, i);
		delay(20);
	}
	
	// Now turn off motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

Code Explanation:

The code begins by declaring six variables to store the Arduino pins connected to the L293D motor driver IC. The pins are labeled as enA, in1, in2 for Motor A and enB, in3, in4 for Motor B.

// Motor A connections
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor B connections
int enB = 3;
int in3 = 5;
int in4 = 4;

In the setup() function, the code sets all the motor control pins as OUTPUTs to indicate that these pins will be used to send signals to the motor driver. It also sets the initial state of all these pins to LOW, ensuring that both motors are initially turned off.

void setup() {
	// Set all the motor control pins to outputs
	pinMode(enA, OUTPUT);
	pinMode(enB, OUTPUT);
	pinMode(in1, OUTPUT);
	pinMode(in2, OUTPUT);
	pinMode(in3, OUTPUT);
	pinMode(in4, OUTPUT);
	
	// Turn off motors - Initial state
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

The loop() function is the main part of the code that runs repeatedly. In this case, it calls two other functions: directionControl() and speedControl(). It waits for one second (1000 milliseconds) between each function call using delay().

void loop() {
	directionControl();
	delay(1000);
	speedControl();
	delay(1000);
}

The directionControl() function demonstrates the spinning direction control of the motors. The code starts by setting the enable pins (enA and enB) to the maximum PWM value of 255, which means the motors will operate at full speed.

It then sets the direction control pins (in1, in2, in3, in4) in a specific pattern to make the motors spin in one direction for 2 seconds. After that, it changes the pattern to make the motors spin in the opposite direction for another 2 seconds. Finally, it turns off both motors by setting all the direction control pins to LOW.

void directionControl() {
	// Set motors to maximum speed
	// For PWM maximum possible values are 0 to 255
	analogWrite(enA, 255);
	analogWrite(enB, 255);

	// Turn on motor A & B
	digitalWrite(in1, HIGH);
	digitalWrite(in2, LOW);
	digitalWrite(in3, HIGH);
	digitalWrite(in4, LOW);
	delay(2000);
	
	// Now change motor directions
	digitalWrite(in1, LOW);
	digitalWrite(in2, HIGH);
	digitalWrite(in3, LOW);
	digitalWrite(in4, HIGH);
	delay(2000);
	
	// Turn off motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

The speedControl() function demonstrates speed control of the motors using PWM. It first sets the direction control pins to make the motors spin in one direction.

It then uses a for loop to gradually increase the PWM value from 0 to 255, effectively accelerating the motors from zero to maximum speed. The delay(20) inside the loop creates a small delay between each increase, controlling the acceleration rate.

After reaching maximum speed, the code enters another for loop to gradually decrease the PWM value from 255 back to 0, effectively decelerating the motors. Again, the delay(20) creates a small delay between each decrease, controlling the deceleration rate.

Finally, it turns off both motors by setting all the direction control pins to LOW.

By combining direction control and speed control techniques, this code provides a comprehensive example of how to control the DC motors using the L293D motor driver IC with an Arduino. You can modify and expand this code to suit various motor control applications in your projects.

void speedControl() {
	// Turn on motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, HIGH);
	digitalWrite(in3, LOW);
	digitalWrite(in4, HIGH);
	
	// Accelerate from zero to maximum speed
	for (int i = 0; i < 256; i++) {
		analogWrite(enA, i);
		analogWrite(enB, i);
		delay(20);
	}
	
	// Decelerate from maximum speed to zero
	for (int i = 255; i >= 0; --i) {
		analogWrite(enA, i);
		analogWrite(enB, i);
		delay(20);
	}
	
	// Now turn off motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

Leave a Comment