To drive a DC motor with an Arduino, you need a motor with a stall current under your driver's limit (typically 1.2A continuous for a TB6612FNG or 3.6A for a DRV8871), an H-bridge driver to handle back-EMF, and a separate power supply. Never wire a motor directly to an Arduino GPIO pin. For a standard 5V to 12V brushed DC gearmotor, use the TB6612FNG dual driver or the DRV8871 single driver, wire the motor terminals to OUT1 and OUT2, and control speed via PWM on the PWMA or PWMB pins.

Workbench Rule: Always use a separate power supply for the motor (VMOT) and the Arduino logic (VCC). Tying a high-current motor to the Arduino's onboard 5V regulator is the fastest way to fry your microcontroller via voltage sag or back-EMF spikes.

Motor Type Comparison: Which DC Motor Fits Your Load?

Not all 'DC motors' behave the same way on a workbench. While steppers and servos are technically DC-powered, they are position-control devices requiring entirely different pulse trains. For continuous rotation and traction, you are choosing between brushed, coreless, and brushless architectures. Here is how they stack up for embedded projects.

Motor Type Torque Curve & Behavior Control Needs Typical Cost (Hobby) Best Application
Brushed DC (Iron Core) High starting torque, linear speed/voltage curve. Torque drops as speed peaks. Simple H-bridge (PWM for speed, H-bridge for direction). $3 - $15 Robot chassis, winches, conveyor belts.
Coreless DC Extremely low rotor inertia, rapid acceleration, low cogging at low speeds. H-bridge, but requires high-frequency PWM (>20kHz) to avoid audible whine. $10 - $30 RC servos, camera gimbals, precision linear actuators.
Brushless DC (BLDC) High efficiency, flat torque curve across mid-range RPM, requires momentum to start. 3-phase ESC (Electronic Speed Controller) or complex FOC (Field Oriented Control) driver. $25 - $80+ Drones, high-speed cooling fans, heavy-load e-bikes.

For 90% of Arduino DIY projects—like line-following robots or automated blinds—a brushed DC gearmotor (like the Pololu micro metal gearmotors or generic TT motors) is the correct choice. They offer high torque at low speeds without the complexity of 3-phase commutation. Consult Pololu's gearmotor selection guide for specific RPM and torque curves on micro-motors.

Sizing Rule of Thumb and Worked Load Example

A common mistake is sizing a motor based on its 'no-load' RPM or nominal voltage. Motors are sized by their stall torque and stall current. If your load requires 0.2 Nm of torque to move, and you buy a motor rated for exactly 0.2 Nm stall torque, the motor will stall, overheat, and draw maximum current the moment it encounters a carpet seam or slight incline.

The Sizing Rule of Thumb: Select a motor whose continuous rated torque is at least 1.5x your calculated load torque, and whose stall torque is 2.5x to 3x your load torque. Ensure the stall current does not exceed your driver's peak current limit.

Worked Load Example: Desktop Winch
Goal: Lift a 1.2 kg payload using a spool with a 25 mm (0.025 m) radius.
1. Calculate Load Force: F = mass × gravity = 1.2 kg × 9.81 m/s² = 11.77 N.
2. Calculate Required Torque: Torque = Force × radius = 11.77 N × 0.025 m = 0.294 Nm.
3. Apply Safety Factor: 0.294 Nm × 2.5 (stall factor) = 0.735 Nm minimum stall torque required.
4. Select Motor: A 12V DC gearmotor with a 100:1 gearbox yielding 0.85 Nm stall torque and a 2.1A stall current. Note: Because the stall current is 2.1A, an L298N or TB6612FNG will fail or thermal-shutdown. You must use a driver rated for at least 3A, like the DRV8871.

Driver Selection and Terminal Wiring

Microcontrollers operate at 3.3V or 5V logic and can only source about 20mA per GPIO pin. Motors demand amps and generate destructive voltage spikes (back-EMF) when spinning down. You need a motor driver to bridge this gap. Here is the definitive breakdown of hobbyist drivers.

Driver IC Architecture Continuous Current Voltage Drop Verdict
L298N BJT (Bipolar) 2.0A per channel ~2.0V (Massive heat) Avoid. Obsolete, wastes battery life as heat, requires bulky heatsinks.
TB6612FNG MOSFET 1.2A per channel (3.2A peak) ~0.5V Best for dual small motors. Highly efficient, standard on most robot chassis.
DRV8871 MOSFET 3.6A (Single channel) ~0.4V Best for single high-torque loads. See the TI DRV8871 datasheet for integrated current limiting.

Wiring the TB6612FNG to Arduino

The TB6612FNG is the gold standard for dual-micro-gearmotor setups. Refer to the Adafruit TB6612FNG tutorial for breakout-specific pinouts, but the silicon logic remains identical:

  • VMOT: Connect to your external battery pack positive (e.g., 7.4V Li-ion or 6V AA holder). Add a 100µF electrolytic capacitor across VMOT and GND to absorb voltage spikes.
  • VCC: Connect to Arduino 5V (or 3.3V if using an ESP32/Arduino Due). This powers the internal logic gates.
  • GND: Connect to Arduino GND AND Battery GND. Common ground is mandatory for logic referencing.
  • STBY (Standby): Tie directly to VCC (High) to keep the chip active, or wire to a GPIO pin to enable/disable the driver in software.
  • PWMA / PWMB: Connect to Arduino hardware PWM pins (e.g., D5, D6 on Uno). Controls speed via duty cycle.
  • AIN1, AIN2 / BIN1, BIN2: Connect to standard digital GPIO pins. Controls direction (High/Low = Forward, Low/High = Reverse, Low/Low = Coast, High/High = Brake).
  • AO1, AO2 / BO1, BO2: Connect directly to the motor terminals. Polarity dictates forward/reverse baseline.

Failure Signatures: Decoding Hums, Overheats, and Stalls

When a motor circuit misbehaves, the physical symptoms tell you exactly what is failing electrically. Do not just swap parts; read the signatures.

  • The 'Hum' Without Movement: The motor vibrates audibly but the shaft doesn't turn. Cause: The PWM duty cycle is too low to overcome static friction (stiction), or the mechanical load exceeds the motor's stall torque. Fix: Increase the baseline PWM value in code (e.g., from 40 to 80 out of 255) or gear down the motor ratio.
  • Driver Overheating (Thermal Shutdown): The motor runs for 10 seconds, stops, then starts again after a minute. Cause: You are pulling continuous current near the driver's absolute maximum rating, triggering the silicon's thermal protection. The L298N is notorious for this due to its 2V internal drop. Fix: Upgrade to a MOSFET-based driver (TB6612FNG or DRV8871) and ensure adequate copper pour or heatsinking.
  • Arduino Brownout / Random Resets: The moment the motor starts, the Arduino reboots or the ESP32 throws a brownout detector (BOD) error. Cause: The motor's inrush (stall) current is dragging the shared power rail below the microcontroller's minimum operating voltage, or back-EMF is injecting noise into the 5V line. Fix: Use a physically separate battery for the motor, add a flyback diode (1N4007 or Schottky SS34) across the motor terminals, and add bulk capacitance (470µF+) at the motor driver's power input.

Frequently Asked Questions

Can I connect a 12V DC motor directly to an Arduino pin?

No. An Arduino ATmega328P GPIO pin can safely source a maximum of 20mA (absolute max 40mA). A small 12V DC motor will draw 200mA to over 1A under load. Wiring it directly will instantly destroy the microcontroller's output transistor. Furthermore, when the motor stops, the collapsing magnetic field generates a high-voltage reverse spike (back-EMF) that will fry the Arduino. You must always use a motor driver (H-bridge) and flyback diodes.

Why does my Arduino reset when the DC motor starts spinning?

This is a classic brownout. DC motors draw their maximum current (stall current) at the exact moment they start from a dead stop (0 RPM). If your motor and Arduino share the same power supply or voltage regulator, this massive current spike causes the voltage to sag below the Arduino's minimum threshold (usually ~4.5V for a 5V board), triggering a hardware reset. Solve this by powering the motor from a separate battery pack, ensuring both grounds are tied together, and adding a large electrolytic capacitor (e.g., 470µF) across the motor driver's power inputs.

How do I control the speed and direction of a DC motor with Arduino code?

Speed is controlled by sending a Pulse Width Modulation (PWM) signal to the driver's enable/PWM pin using the analogWrite(pin, value) function, where 0 is stopped and 255 is full speed. Direction is controlled by setting the driver's IN1 and IN2 logic pins HIGH or LOW using digitalWrite(). For example, setting IN1 HIGH and IN2 LOW spins the motor forward; swapping them spins it in reverse. Setting both LOW allows the motor to coast to a stop.

Should I use a stepper, servo, or DC motor for my Arduino robot?

These are fundamentally different tools. Use a brushed DC gearmotor for continuous traction (driving wheels) where high speed and simple forward/reverse control are needed, and exact position doesn't matter. Use a stepper motor when you need precise, open-loop positional control (like a 3D printer extruder or CNC axis), accepting that they run hot and lose torque at high RPMs. Use an RC servo for limited-range (usually 180-degree) high-torque articulation, like a robotic arm joint or steering linkage, as they contain their own internal closed-loop feedback and driver circuitry.