Control a DC Motor with Arduino, ESP8266 or ESP32 without IC

The objective of this article is to show you how to control a DC motor with your Arduino, ESP8266 or ESP32 microcontroller board but without the use of an IC motor driver.
After a short summary of the basic functionality of the DC motor, we design the DC motor circuit that contains an Arduino, ESP8266 or ESP32 microcontroller, the DC motor itself, a MOSFET, one diode and two resistors.

After we discuss all elements of the circuit, I show you a basic program script to switch the DC motor on and off and a second script to control the speed of the DC motor.

Control DC Motor without IC thumbnail

Table of Contents

Basic Functionality of a DC Motor

Before we start diving into the wiring, programming our microcontroller and the program script, I would like to give you a short summary of the basic functionality of the DC motor. If you are already familiar with the functionality of the DC motor, you can skip this first chapter.
The following picture shows the construction of a DC motor.

DC Motor Construction

Every DC motor consists of two key components that are important for the functionality:

  1. The stator is the stationary part of the motor that provides a rotating magnetic field for the armature.
  2. The armature is the part of the DC motor that rotates and where external components, like a wheel, are connected.

The magnets in the stator (poles) and a coil of wires (field winding), with a current running through it, generate an electromagnetic field. The windings of insulated wire on the outside of the armature (armature winding) are wrapped around the armature to concentrate the magnetic field of the stator.

The armature windings are connected to a commutator, basically a rotary electrical switch, that applies electrical current to the windings. The electrical current energizes each armature coil and creates a steady rotating magnetic field.

If the armature coils are turned on and off in sequence, the rotating magnetic field interacts with the magnetic field of the stator and create a torque, which causes the armature to rotate. Therefore, the DC motor convert electrical energy to mechanical energy.

DC Motor Circuit for Arduino, ESP8266 and ESP32

The following picture shows the circuit that we use to run and control the DC motor without any IC motor driver. This circuit diagram provides the best overview of all components and how they are connected to each other for Arduino and also for ESP8266 or ESP32 microcontroller.

From the following table, you see all electronic components that I use for this DC motor without IC tutorial. I get commissions for purchases made through links in this table.

General ComponentComponent that we use in this tutorialLink AmazonLink Aliexpress
MicrocontrollerORArduino boardArduino UnoArduino Uno
ORESP8266 boardESP8266 NodeMCUESP8266 NodeMCU
ORESP32 boardNodeMCU-32S ESP-WROOM-32NodeMCU-32S ESP-WROOM-32
DC MotorANDDC3V-6V DC drive motorDC Electric Motor 3-6VDC Electric Motor 3-6V
Transistor or MOSFETANDIRLZ44 NPN MOSFETIRFZ44 N-Channel MOSFETIRFZ44 N-Channel MOSFET
DiodeAND1N4001MCIGICM 1N4001 Rectifier DiodeMCIGICM 1N4001 Rectifier Diode
ResistorsAND470Ω, 1KΩ, 47kΩResistor KitResistor Kit

Dependent on your microcontroller that you use, you see the wiring for different Arduino, ESP8266 and ESP32 microcontroller boards in the following section. Because the DC motor that is used has an operation voltage between 3V and 6V, I use a supply voltage of 5V from the Arduino boards and a 3.3V supply voltage from the ESP8266 and ESP32 boards.

For me it is sometimes hard to remember the names of the connection pins of a transistor or MOSFET. Therefore, I created the following picture that shows the scientific names that we also use in this article. Because I use a MOSEFT for my circuit, I will only use the terminals of the MOFET on the right side of the picture for the rest of this tutorial.

Different Terminals BJT and MOSFET

The Arduino, ESP8266 or ESP32 microcontroller provide the power supply for the DC motor. We use an IRLZ44 NPN MOSFET as low-side switch to control the DC motor.

  • NPN transistor: Because we want to turn the DC motor on by setting the digital pin of the microcontroller HIGH.
  • Low-side switch: The transistor is on the low (ground) side of the circuit and the motor is connected on the high (5V or 3.3V) side. Otherwise, we were not able to switch off a load that has a higher voltage than the control voltage (V_DS > V_GS).

The following sub-chapters answers the questions why we use this specific circuit design.

Microcontroller Datasheet eBook

The 35 pages Microcontroller Datasheet Playbook contains the most useful information of 14 Arduino, ESP8266 and ESP32 microcontroller boards.

Why using a Transistor and not run the DC motor directly from the digital I/O pins of the microcontroller?

You may ask yourself if it would be possible to connect the DC motor directly to a digital I/O pin of the microcontroller and control the motor via a digital pin to turn the motor on and off. The problem with this circuit would be that also small DC motors are likely to draw more power than the digital I/O pins of the Arduino, ESP8266 or ESP32 are able to provide. The DC motor that we use in this example draws on average 100mA. If the DC motor draws more current than the maximum current of the digital I/O pin, your microcontroller can be damaged.

The following table shows the maximum current of the digital input/output pins of the most used microcontroller boards, that is by far lower than the 100mA that we need to drive the DC motor.

MicrocontrollerBoardsMax Current Digital I/O Pin
ATmega328PArduino Nano, Arduino Uno, Arduino Pro Mini40mA
ATmega2560Arduino Mega20 mA
ESP8266ESP-01, NodeMCU, WeMos D1 Mini12 mA
ESP32DevKitC, Adafruit HUZZAH32, Sparkfun ESP32 Thing Plus, FireBeetle ESP3220 mA

Now we know that the digital I/O pins cannot be used as power supply for the DC motor. What about the 5V pin or 3.3V pin of the microcontroller? Good choice, because these pins are connected to the general power supply of the microcontroller board that used an USB connection with a maximum current of 250mA. If you want to know in detail if a 5V or 3.3V pin is connected to a voltage regulator or direct to the USB interface, I recommend by Microcontroller Datasheet eBook. The 5V pin as well as the 3.3V pin are the perfect power supply for a DC motor that consumes less than 200mA (because our microcontroller also needs some power). On the downside, we cannot control the 5V or 3.3V pin to turn the DC motor on, off or change the speed.

Therefore, we use a transistor between 5V / 3.3V and ground to control the circuit of the DC motor. The gate of the transistor is connected to a digital pin of the microcontroller through a voltage divider of two resistors.

  • We can turn the DC motor on and off by switching the digital pin HIGH and LOW.
  • By using pulse width modulation on the digital pin, we can also control the speed of the motor, see chapter: How to control the Speed of the DC Motor

When using an external power source for DC Motor?

If you want to use bigger DC motors, that draws more than 200mA like 1A, you even cannot use the supply voltage of the microcontroller. In this case you need an external power source for the DC motor like a laboratory power supply, batteries, or a wall adapter.

You can power the microcontroller via a voltage regulator also from this external power source. If you are not sure which possibilities your microcontroller has for a power supply, or if any internal voltage regulator is limiting the current for the DC motor, check out my Microcontroller Datasheet eBook where you find all this information.

How to choose the right MOSFET to control the DC motor?

For our circuit we choose the IRLZ44 MOSFET. But how did I know that I can use this MOSFET? The decision is based on the microcontroller and the electrical specifications of the DC motor. The following steps show the process, how to find the right transistor for your circuit:

  1. The Gate Threshold Voltage (V_GS) is lower than the operation voltage of the microcontroller. The IRLZ44 has a gate-source threshold voltage between 1V and 2V. Our Arduino with 5V operating voltage and the ESP32 and ESP8266 with an operating voltage of 3.3V have a higher voltage than the gate-source threshold voltage of the IRLZ44.
  2. The drain-source breakdown voltage is not exceeded. Because we use the microcontroller as power source of the DC motor, our drain-source voltage will not be exceeding 5V. The drain-source breakdown voltage of the IRLZ44 is far higher with 55V.
  3. The continuous drain current is not exceeded. The DC motor that we use in this example draws on average 100mA and the absolute maximum rating for the continuous drain current of the IRLZ44 is 35A.

Therefore, the IRLZ44 MOSFET is a good choice for our circuit. If you are an expert regarding transistors and MOSFET and you think that I am missing an important point, use the comment section that the end of this article to share your knowledge with us.

Why do we need a diode in parallel to the DC Motor?

We learned in the first part of this article that the DC motor has coils inside that creates a magnetic field. When a DC motor is switched off, the current in the stator is 0A, and the rotor is freewheeling due to the moment of inertia. This rotation causes a self-induction in the coils of the motor and therefore voltage spikes. The following picture shows the behavior of the voltage during the shutdown.

DC Motor Circuit MOSFET turn off voltage spike

From the picture, you see that the drain – source voltage overshoots due to the MOSFET switching off and the inductance of the motor dumping its current back to the drain of the MOSFET.

The diode, also called flyback diode, that we set in parallel to the DC motor provides a safe path for the inductive current so that the drain – source voltage does not rise and potentially damages the circuit.

Why do we need a resistor in series to the gate of the transistor and how to calculate its size?

Resistor R1 is there to limit current for microcontroller because the gate of the MOSFET is a small capacitor that starts charging if a voltage is applied to the gate. The initial current draw could be too high for the digital I/O pin of the microcontroller, that is shown in the following picture.

When the current exceeds the maximum current of the microcontroller, that we saw in the table of the previous chapter, the microcontroller could be damaged. Therefore, we use the resistor R1 to protect the digital pin and flatten the charging curve of the MOSFET gate. Until we need a high switching frequency above 100 kHz, we can use a resistor R1 of 220Ω.

Why do we need a resistor between the gate of the transistor and ground?

If the digital I/O pin of the Arduino, ESP8266 or ESP32 microcontroller is set to LOW, but the supply voltage of the DC motor at the emitter is still active, there is the possibility that the transistor erroneously switched through. This can also happen at the start of the program, where the microcontroller digital pin is not yet defined as output. With the resistor R2 we set a predefined state in this case pull the gate to ground.

The size of this resistor R2 between gate and ground builds a voltage divider with resistor R1. The output of the voltage divider is gate voltage of the MOSFET. The objective is that the gate voltage is not too much reduced by resistor R2. Otherwise, it could happen that the threshold voltage is not exceeded to switch the MOSFET.

The following pictures show the gate – source voltage for different R2 resistors and without resistor for Arduino and ESP8266 measures because the operation voltage has also an influence on the gate – source voltage.

From the pictures of the oscilloscope, you see that the higher resistor R2, the higher is the gate voltage. Therefore, resistor R2 should be much greater than resistor R1. Values between 47kΩ and 100kΩ are common practice. In our circuit we use an 47kΩ resistor for the Arduino, ESP8266 and ESP32 circuits.

Program Script for the DC Motor Circuit

The program script that controls the DC motor without any IC motor driver, only with the Arduino, ESP8266 or ESP32 microcontroller and a MOSFET is shown in the following section. To control the DC motor, we only need to turn the gate of the MOSFET HIGH so that the DC motor rotates or set the digital pin of the microcontroller LOW to shut down the DC motor.

int motorPin = 6; // for Arduino microcontroller
//int motorPin = D6; // for ESP8266 microcontroller
//int motorPin = 4; // for ESP32 microcontroller

void setup() {
}

void loop() {
  digitalWrite(motorPin, HIGH);
  delay(2000);
  digitalWrite(motorPin, LOW);
  delay(2000);
}

At the beginning of the Arduino script, we define the digital I/O pin that connects the microcontroller with the gate of the MOSFET. The setup function stays empty and is not used. In the loop function, we set the digital pin HIGH and LOW. Between each state we wait for 2 seconds.

The following picture shows the drain – source voltage and gate – source voltage.

PicoScope Arduino Uno V_DS and V_GS

If the gate – source voltage exceeds the threshold voltage of the MOSFET, the drain – source voltage breaks down because the DC motor turns on that results in a large voltage drop across the DC motor.

How to control the Speed of the DC Motor

The speed of the DC motor is proportional to the current flow of the collector. If we look at the characteristic curve of a transistor, we see that we can control the collector current through the current of the base connection.

Transistor characteristic curve

The same principle is also valid for MOSFETs. To increase or reduce the gate current, we use pulse width modulation (PWM) on the connected digital I/O pin of the microcontroller. If you are not familiar with pulse width modulation, I recommend my PWM tutorial.

For the following example, we want to increase and decrease the speed of the DC motor.

Program Script to Control the Speed of the DC Motor

The following script takes advantage of the PWM signal from the microcontroller to control the speed of the DC motor. Because the PWM value range between the Arduino and the ESP8266 and ESP32 are different, I created two different Arduino scripts.

The program script is short and easy to understand. At the beginning, we define the pin that is connected to the transistors base pin. Because we use the PWM functionality on a digital pin, we must define the connected pin as output. In the loop function, we increase the speed of the DC motor during a for loop. The analog signal goes from 0 where the motor stands still to 255 for the Arduino microcontroller and to 1023 for the ESP8266 and ESP32 microcontroller, where the motor rotates with the maximum speed. We use the analogWrite function to crease the PWM signal.

The following video shows the result of the program script.

YouTube

By loading the video, you agree to YouTube's privacy policy.
Learn more

Load video

I hope you learned a lot in my tutorial how to control a DC Motor with Arduino, ESP8266 or ESP32 without IC. If you have any questions, leave a comment below and I will answer your questions as soon as possible.

2 thoughts on “Control a DC Motor with Arduino, ESP8266 or ESP32 without IC”

Leave a Comment