Arduino - DC Motor
Arduino - Controlling a DC Motor
Section titled “Arduino - Controlling a DC Motor”A DC motor (Direct Current motor) is the most common type of motor, used in everything from toys to fans to robot wheels. This tutorial will guide you through controlling a DC motor’s on/off state, speed, and direction using modern components and best practices.
Critical Safety Warning: Never connect a motor directly to an Arduino’s digital pins. Motors are inductive loads that can draw far more current than a pin can supply, and they generate voltage spikes when turned off. Doing so will permanently damage your Arduino. Always use a dedicated motor driver circuit.
Part 1: Simple On/Off Control with a MOSFET
Section titled “Part 1: Simple On/Off Control with a MOSFET”To safely switch a motor on and off, we will use a MOSFET, which acts as a robust, electronically controlled switch.
Components Required
Section titled “Components Required”- 1 × Arduino UNO
- 1 × Small DC Motor (e.g., 5V-9V)
- 1 × Logic-Level N-Channel MOSFET (e.g., TIP120, IRLZ44N). A TIP120 is a Darlington Transistor but works similarly here.
- 1 × 1N4001 Diode (or similar). This is the crucial flyback diode.
- 1 × Separate Power Supply for the Motor (e.g., a 9V battery or a 4xAA battery pack). This is highly recommended.
- Jumper Wires and a Breadboard
Procedure and Wiring
Section titled “Procedure and Wiring”The MOSFET has three pins: Gate, Drain, and Source. The Arduino sends a signal to the Gate to control the flow of current from the Drain to the Source.
- Connect the MOSFET Source to the Ground rail of your breadboard.
- Connect the Arduino’s GND pin to the same Ground rail.
- Connect the Ground of your motor’s power supply to the same Ground rail. All grounds must be connected.
- Connect Arduino Pin 9 to the MOSFET Gate.
- Connect one motor terminal to the MOSFET Drain.
- Connect the other motor terminal to the Positive terminal of your motor’s power supply.
- Crucially, connect the 1N4001 diode in parallel with the motor. The diode’s stripe (cathode) must connect to the positive side, and the non-striped side (anode) to the negative (MOSFET Drain) side. This protects your circuit from voltage spikes.
On/Off Control Code
Section titled “On/Off Control Code”const int motorPin = 9; // Use a PWM pin
void setup() { // Set the motor control pin as an output pinMode(motorPin, OUTPUT);}
void loop() { // Turn the motor on to full speed digitalWrite(motorPin, HIGH); delay(2000); // Run for 2 seconds
// Turn the motor off digitalWrite(motorPin, LOW); delay(2000); // Wait for 2 seconds}Part 2: Controlling Motor Speed with PWM
Section titled “Part 2: Controlling Motor Speed with PWM”We can easily extend the previous circuit to control speed. By using Pulse-Width Modulation (PWM) with analogWrite(), we can vary the average voltage supplied to the motor, thus controlling its speed.
Speed Control Code
Section titled “Speed Control Code”This code will make the motor ramp up to full speed and then ramp down.
const int motorPin = 9; // Must be a PWM pin (marked with ~ on Uno)
void setup() { pinMode(motorPin, OUTPUT);}
void loop() { // Ramp up speed for (int speed = 0; speed <= 255; speed++) { analogWrite(motorPin, speed); delay(10); }
// Ramp down speed for (int speed = 255; speed >= 0; speed--) { analogWrite(motorPin, speed); delay(10); }}Part 3: Controlling Direction with an H-Bridge
Section titled “Part 3: Controlling Direction with an H-Bridge”To make a motor spin in both directions, we need an H-Bridge. This circuit can reverse the polarity of the voltage applied to the motor. The L298N module is a common, though inefficient, H-bridge driver perfect for beginners.
Modern Alternative: The TB6612FNG
Section titled “Modern Alternative: The TB6612FNG”While we will use the L298N, for your future projects, consider a more modern driver like the TB6612FNG. It is much more efficient (less power wasted as heat), smaller, and requires less current to operate, making it a superior choice.
L298N Wiring and Code
Section titled “L298N Wiring and Code”The L298N module controls two motors. We will use ‘Motor A’.
- Connect your motor to the
OUT1andOUT2screw terminals. - Connect your motor’s external power supply to the
VMS(or12V) andGNDscrew terminals. - Remove the
5Venable jumper if one is present. - Connect the L298N
GNDto the ArduinoGND. - Connect L298N
IN1to Arduino Pin 8. - Connect L298N
IN2to Arduino Pin 7. - Connect L298N
ENA(Enable A) to Arduino PWM Pin 9.
This code uses helper functions for clean, readable control.
// L298N H-Bridge Pin Definitionsconst int motorEnablePin = 9; // ENA - Must be PWMconst int motorIn1Pin = 8; // IN1const int motorIn2Pin = 7; // IN2
void setup() { // Set all control pins to outputs pinMode(motorEnablePin, OUTPUT); pinMode(motorIn1Pin, OUTPUT); pinMode(motorIn2Pin, OUTPUT);}
void loop() { // Move forward at full speed for 2 seconds moveMotor(255, true); delay(2000);
// Stop for 1 second stopMotor(); delay(1000);
// Move backward at half speed for 2 seconds moveMotor(128, false); delay(2000);
// Brake for 1 second brakeMotor(); delay(1000);}
/** * @brief Controls the motor's speed and direction. * @param speed The speed from 0 (off) to 255 (full). * @param forward True for forward, false for backward. */void moveMotor(int speed, bool forward) { if (forward) { digitalWrite(motorIn1Pin, HIGH); digitalWrite(motorIn2Pin, LOW); } else { digitalWrite(motorIn1Pin, LOW); digitalWrite(motorIn2Pin, HIGH); } analogWrite(motorEnablePin, speed);}
/** * @brief Stops the motor by letting it coast freely. */void stopMotor() { // Disables the motor driver analogWrite(motorEnablePin, 0);}
/** * @brief Actively brakes the motor by shorting its terminals. */void brakeMotor() { digitalWrite(motorIn1Pin, HIGH); digitalWrite(motorIn2Pin, HIGH); analogWrite(motorEnablePin, 255); // Brake needs to be enabled}