This post explains how to use the ULN2803A IC to control a DC motor, using an Arduino board.
Driving high current loads with microcontrollers
Many times, when creating an electronic design, we want our microcontroller to drive loads that draw a considerable amount of current, such as relays, motors or high power LEDs, amongst many other possibilities.
Nevertheless, the digital pins of a microcontroller can normally provide only a limited amount of current, in the order of the dozens of milliamps. For example, Arduino Uno has a recommended value of 20 mA for continuous operation of its digital pins, with a maximum tolerable value of 40 mA before causing damage to the device . The ESP8266 (the new IoT trend for makers) can only provide a maximum of 12 mA .
From those values, it’s easy to conclude that driving, for example, a DC motor that consumes 100 mA is not possible by directly connecting it to an IO pin of the microcontroller. So, we need some kind of circuit that can be controlled by an IO pin of a microcontroller, and still be able to provide a considerable amount of current to the device to control.
Although there are many solutions for the problem mentioned before, such as directly using transistors, we will explain how to use a ULN2803A, which is an easy to use IC.
The ULN2803A is an array of Darlington transistors, which is a configuration of two transistors (shown in figure 1) that allow for a very high current amplification. This means that, by drawing only a very small amount of current from the input (in this case, the IO pin), the device can provide a much larger amount of current, which is drawn from an external voltage source, and not from the IO pin. In the case of the ULN2803A, each channel can provide a maximum of 500 mA .
Figure 1 – Darlington pair configuration of a ULN2803A channel. Taken from .
Controlling a motor with Arduino
Using an ULN2803A to control a motor with an Arduino is very simple, as shown in figure 2. This example uses a regular 5V DC motor.
Keep in mind that each ULN channel will work as a switch, turning on and off the connection of the motor to GND, depending on the voltage of the input pin (which is connected to the output pin of the microcontroller).
If the digital pin of the Arduino is High (5 V), then current will flow through the circuit and the motor will operate. If the digital pin is Low (0 V), then the connection to GND will be off, and there will be no current flowing through the circuit.
Figure 2 – Connection diagram to control a motor using Arduino and ULN2803A.
It’s important to take into account that the ULN cuts the connection to GND when using it, for example, to drive LEDs, in order to avoid connecting them the wrong way. In the case of a regular DC motor, changing the terminals will only change the rotation direction of the motor.
The Arduino code to make this circuit work is even more simple: just use a digitalWrite to turn the digital pin on and watch the motor spin.
Controlling the speed of the motor
Using this exact same configuration, we can use the arduino PWM capabilities to control the speed of the motor. We jut need to change the digitalWrite function by the analogWrite function to activate the pin, and set it to values between 0 and 255 to watch the speed change.