Why You Cannot Connect a Motor Directly to an Arduino

Attempting to drive a motor with Arduino by wiring it directly to the GPIO pins is a classic beginner mistake that will permanently destroy your microcontroller. The ATmega328P (found on the Arduino Uno R3) and the Renesas RA4M1 (found on the modern Arduino Uno R4 Minima) have a strict DC current limit per I/O pin of 20mA, with an absolute maximum rating of 40mA. Even a tiny 130-size hobby DC motor requires 150mA to run freely and can spike to 1.5A or more during a stall condition.

To safely control a motor, you must use an intermediary power stage. In this tutorial, we will explore how to drive a DC motor with Arduino using the ubiquitous L298N Dual H-Bridge module. We will cover the exact wiring, power supply requirements, PWM speed control, and the thermal realities of bipolar transistor motor drivers in 2026.

Bill of Materials (BOM) & Component Selection

Before wiring, ensure you have the correct components. Prices reflect average maker-market rates as of early 2026.

Component Specific Model / Spec Est. Price Engineering Notes
Microcontroller Arduino Uno R3 or R4 Minima $27.00 - $28.00 R4 offers 48MHz processing but 5V logic remains identical for this use case.
Motor Driver L298N Dual H-Bridge Module $6.00 - $9.00 Based on STMicroelectronics BJT Darlington array. High voltage drop (~2V).
DC Motor 130-size or 775 DC Gear Motor $4.00 - $15.00 Ensure operating voltage is between 5V and 12V for this specific setup.
Power Supply 2S 18650 Li-Ion Battery Holder $4.00 Provides 7.4V nominal (8.4V fully charged). Capable of 10A+ continuous discharge.
Alternative Driver TB6612FNG Breakout $4.50 MOSFET-based. Much lower voltage drop (0.5V) and higher efficiency than L298N.

The Power Supply Trap: Why 9V PP3 Batteries Fail

Many tutorials suggest using a standard 9V alkaline (PP3) battery to power the L298N and motor. Do not do this. A standard 9V alkaline battery has a very high internal resistance and is designed for low-drain applications like smoke detectors (drawing ~50mA). When your motor demands 500mA on startup, the battery voltage will instantly sag below the L298N's logic threshold, causing the Arduino to brown out and reset continuously. Always use a 2S Lithium-Ion (18650) pack or a high-current 5V/12V bench supply.

Understanding the H-Bridge and Voltage Drop

An H-Bridge allows you to reverse the polarity of the voltage applied to the motor, thereby changing its direction. The L298N achieves this using Bipolar Junction Transistors (BJTs) configured in a Darlington pair. While robust and forgiving of minor wiring errors, BJTs introduce a significant saturation voltage drop (Vce_sat).

According to the STMicroelectronics L298N Datasheet, the typical voltage drop across the driver is between 1.8V and 3.2V depending on the current draw. This means if you supply 9V to the L298N's VCC, your motor will only receive roughly 6.5V to 7V. If you are building a battery-operated robot where every volt of headroom matters, you should bypass the L298N and use a MOSFET-based driver like the TB6612FNG, which drops less than 0.5V.

Step-by-Step Wiring Guide

Follow this exact pinout to wire the Arduino, L298N, and power supply.

CRITICAL WARNING: You must establish a Common Ground. The ground of the battery pack, the ground of the L298N, and the GND pin of the Arduino MUST all be connected together. Without a common ground, the Arduino's 5V PWM logic signals have no reference voltage, and the motor will not respond.
  1. Power Supply to L298N: Connect the positive terminal of your 2S 18650 battery pack to the 12V screw terminal on the L298N. Connect the negative terminal to the GND screw terminal.
  2. Common Ground: Run a jumper wire from the GND screw terminal on the L298N to any GND pin on the Arduino.
  3. Logic Power (5V): If your battery voltage is under 12V, leave the 5V-EN jumper cap ON the L298N. You can optionally wire the L298N's 5V output pin to the Arduino's 5V or VIN pin to power the board, though USB power is safer for initial testing.
  4. Direction Control (IN1 & IN2): Connect L298N IN1 to Arduino Digital Pin 8. Connect L298N IN2 to Arduino Digital Pin 7.
  5. Speed Control (ENA): Remove the jumper cap from the ENA pins. Connect the exposed ENA pin to Arduino Digital Pin 9 (which supports hardware PWM via analogWrite()).
  6. Motor Output: Connect your DC motor wires to the OUT1 and OUT2 screw terminals. Polarity does not matter here; direction is handled in software.

Arduino C++ Code for PWM Speed and Direction Control

The following sketch encapsulates the motor logic into a reusable function. It accelerates the motor forward, stops, reverses, and then brakes.

// Pin Definitions
const int enA = 9;   // PWM Speed Control
const int in1 = 8;   // Direction 1
const int in2 = 7;   // Direction 2

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  
  // Ensure motor is off at startup
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
}

// Function to drive motor: speed (0-255), reverse (boolean)
void driveMotor(int speed, boolean reverse) {
  // Clamp speed to valid PWM range
  speed = constrain(speed, 0, 255);
  
  // Set direction
  digitalWrite(in1, reverse ? LOW : HIGH);
  digitalWrite(in2, reverse ? HIGH : LOW);
  
  // Apply PWM to Enable pin
  analogWrite(enA, speed);
}

void loop() {
  // Accelerate Forward
  for (int i = 0; i <= 255; i += 5) {
    driveMotor(i, false);
    delay(50);
  }
  
  // Coast for 1 second
  driveMotor(0, false); 
  delay(1000);
  
  // Accelerate in Reverse
  for (int i = 0; i <= 255; i += 5) {
    driveMotor(i, true);
    delay(50);
  }
  
  // Hard Brake (Shorting motor terminals via L298N)
  digitalWrite(in1, HIGH);
  digitalWrite(in2, HIGH);
  analogWrite(enA, 255);
  delay(2000);
}

Common Failure Modes and Troubleshooting

When learning how to drive a motor with Arduino, you will inevitably encounter edge cases. Here is how to diagnose the most frequent hardware and software failures.

1. The Motor Whines but Will Not Spin

Cause: Insufficient stall current or PWM frequency mismatch. If the PWM value is too low (e.g., analogWrite(enA, 50)), the voltage may not be high enough to overcome the motor's static friction and internal magnetic cogging. The motor coils will vibrate (whine) at the Arduino's default Timer 1 PWM frequency (~490Hz), but the shaft won't turn.
Fix: Implement a "kickstart" routine in your code. Apply 255 (full power) for 50 milliseconds to break static friction, then immediately drop down to your desired lower PWM cruising speed.

2. The L298N Module is Extremely Hot to the Touch

Cause: Thermal dissipation limits of the Darlington BJT array. If you are pulling 1.5A through the L298N with a 2V voltage drop, the chip is dissipating 3 Watts of pure heat (P = V × I). The stock aluminum heatsink on cheap clone modules is rarely sufficient for continuous operation above 1A.
Fix: If your application requires continuous current above 1A, abandon the L298N. Upgrade to a modern MOSFET driver like the Texas Instruments DRV8871 or the Toshiba TB6612FNG, which operate with minimal thermal loss.

3. Arduino Resets Randomly When Motor Stops or Reverses

Cause: Back-Electromotive Force (Back-EMF) and Ground Bounce. When a spinning motor is suddenly powered off or reversed, its inductance generates a massive reverse voltage spike. While genuine L298N modules include built-in 1N4007 flyback diodes to route this spike back to the power supply, cheap clones often omit them or use undersized diodes. Furthermore, high current surges through thin ground wires can cause the ground reference to "bounce," resetting the Arduino's brown-out detector (BOD).
Fix: Solder external Schottky flyback diodes across the motor terminals if using a clone board. Ensure your ground wires are thick (18 AWG or lower) and keep the motor power wiring physically separated from the Arduino's sensitive logic wiring.