If you need high starting torque, simple speed control, and a low component cost, a brushed PWM DC motor setup is your baseline for embedded projects. Unlike steppers that require complex pulse sequencing or BLDC motors that demand three-phase commutation, a standard brushed DC motor paired with a Pulse Width Modulation (PWM) signal gives you proportional speed and torque control using just a single microcontroller GPIO pin and an H-bridge driver.

However, the simplicity of a PWM DC motor masks the underlying physics of inductive loads. Undersizing your driver based on nominal running current rather than stall current will result in melted silicon, while ignoring back-EMF will brownout your microcontroller. This guide covers motor selection, exact sizing math, H-bridge wiring, and the failure signatures you will encounter on the bench.

Choosing the Right Motor: Brushed DC vs. Stepper vs. BLDC

Before committing to a PWM DC motor, verify that your load profile actually matches its torque curve. Hobbyists frequently misuse steppers for high-speed continuous rotation or attempt to use brushed DC motors for precise open-loop positioning. Here is how the three primary embedded motor types compare in real-world applications.

Motor Type Comparison for Embedded Loads
Motor Type Torque Curve Profile Control Needs Cost & Complexity Best Fit Load Profile
Brushed DC (PWM) Highest torque at zero RPM (stall); drops linearly as speed increases. Single PWM pin for speed; H-bridge for direction. No feedback required for basic speed. $ (Low cost, simple wiring) Wheels, conveyors, winches, pumps, fans.
Stepper High holding torque at zero RPM; torque drops off sharply at higher speeds due to inductance. Pulse/Direction signals; requires a dedicated chopper driver (e.g., TMC2209). $$ (Moderate cost, complex tuning) 3D printer axes, CNC routers, camera sliders (open-loop positioning).
BLDC (Brushless) Relatively flat torque curve across a wide RPM range; highly efficient. 3-phase ESC or FOC driver; requires Hall sensors or sensorless back-EMF zero-crossing detection. $$$ (High cost, complex firmware) Drones, high-speed spindles, electric skateboards, gimbals.

The Verdict: Choose a PWM DC motor when your primary goal is moving mass from point A to point B at a variable speed, and you do not need to hold an exact angular position without a separate encoder. If you need the motor to hold a heavy load stationary against gravity without drawing continuous stall current, you must use a stepper or a DC motor with a mechanical brake/worm gear.

Sizing a PWM DC Motor and Driver for Your Load

The most common mistake in embedded motor design is sizing the H-bridge driver based on the motor's nominal running current. Motors draw exponentially more current when starting under load or when mechanically stalled. If your driver cannot handle the stall current, the internal MOSFETs or BJTs will overheat and fail in seconds.

The Sizing Rule of Thumb: Your motor driver's continuous current rating must be at least 1.5x to 2.0x the motor's stall current, not its nominal running current. This accounts for startup inrush, mechanical binding, and thermal derating in enclosed project boxes.

Worked Load Example: DIY 10kg Winch

Let's size a motor and driver for a small winch lifting a 10kg mass using a drum with a 2cm radius.

  1. Calculate Required Torque: Torque = Force × Radius. Force = 10kg × 9.81 m/s² = 98.1N. Torque = 98.1N × 0.02m = 1.96 Nm (approx. 275 oz-in).
  2. Select the Motor: We choose a 12V DC gearmotor rated for 2.5 Nm at 60 RPM to provide a 25% safety margin. The datasheet lists a nominal current of 4A and a stall current of 14A.
  3. Size the Driver: Using the 1.5x rule on the 14A stall current: 14A × 1.5 = 21A minimum continuous rating.

If you attempt to run this 14A-stall motor through a standard L298N driver (rated for 2A continuous), the L298N will trigger its internal thermal shutdown within milliseconds, or the silicon will literally crack from thermal shock. You need a high-current MOSFET-based driver.

Common Microcontroller H-Bridge Driver Specifications
Driver IC / Module Continuous Current Switching Tech Voltage Drop / Rds(on) Best Application
L298N Module 2A (per channel) BJT Darlington ~2.0V dropout (High heat) Small 5V-12V toy motors, low-load prototyping.
TB6612FNG 1.2A (3.2A peak) MOSFET ~0.5Ω (Low heat) NEMA 17 steppers (bipolar), small 6V DC gearmotors.
BTS7960 (IBT-2) 43A (with adequate heatsink) MOSFET Very low Rds(on) 12V-24V high-power actuators, e-bike conversions, large winches.
Cytron MD30C 30A (80A peak) Discrete MOSFET Ultra-low, built-in fan/opto Robotics competitions, heavy-duty 12V-24V PWM DC motors.

For our 10kg winch example, the Cytron MD30C or a BTS7960 module are the correct choices. They utilize MOSFETs, which switch efficiently and generate a fraction of the heat produced by the older BJT-based L298N.

Wiring, Terminals, and Microcontroller Integration

Driving a PWM DC motor requires three distinct circuits: the high-current motor path, the low-voltage logic path, and the PWM control signal. Mixing these up or failing to establish a common ground reference will result in erratic behavior or dead microcontrollers.

Terminal Identification and Pin Mapping

Using an ESP32 DevKit V1 and a Cytron MD30C (or generic BTS7960) as our reference, here is the exact wiring topology:

  • Motor Terminals (M+, M- / OUT1, OUT2): Connect directly to the DC motor. Use thick silicone wire (e.g., 14 AWG for 20A+ loads) and crimp ferrules. Soldering high-current motor wires directly to PCB pads often leads to cold joints that melt under vibration.
  • Power Terminals (VCC/B+, GND): Connect to your main battery or bench power supply. Crucial: The GND of the high-current 12V/24V supply must be tied directly to the GND of your ESP32. Without this common ground, the PWM logic signal has no reference voltage and the driver will not switch.
  • Logic/PWM Inputs (IN1/PWM, IN2/DIR): Connect to ESP32 GPIO pins. The ESP32's 3.3V logic is fully compatible with the opto-isolated or 5V-tolerant logic inputs on modern MOSFET drivers.

ESP32 LEDC PWM Configuration

The ESP32 does not use the standard Arduino analogWrite() function for hardware PWM. Instead, it uses the LED Control (LEDC) peripheral, which offers up to 16-bit resolution. As of the 2026 ESP32 Arduino Core v3.x, the API has been simplified. According to the official Espressif LEDC documentation, you can attach a pin and set the frequency in one line:

// ESP32 Arduino Core v3.x PWM Setup for DC Motor
const int pwmPin = 18;
const int dirPin = 19;
const int pwmFreq = 16000; // 16kHz to avoid audible motor whine
const int pwmResolution = 10; // 10-bit = 0 to 1023 duty cycle

void setup() {
  pinMode(dirPin, OUTPUT);
  digitalWrite(dirPin, HIGH); // Set forward direction
  
  // Attach PWM pin, set frequency and resolution
  ledcAttach(pwmPin, pwmFreq, pwmResolution);
  
  // Ramp up to 75% speed (768 out of 1023)
  ledcWrite(pwmPin, 768);
}

void loop() {
  // Motor runs continuously
}

Choosing the right PWM frequency is critical. Frequencies below 16kHz cause magnetostriction in the motor's steel laminations, resulting in an audible, high-pitched whine. However, pushing the frequency above 20kHz increases switching losses in the H-bridge MOSFETs and generates electromagnetic interference (EMI) that can disrupt I2C sensors on the same breadboard. A 16kHz to 20kHz sweet spot is ideal for most hobbyist PWM DC motor setups.

Diagnosing Failure Signatures: Hum, Overheat, and Stall

When a PWM DC motor circuit fails, it rarely does so silently. The physical symptoms will point you directly to the root cause, whether it is a firmware error, a thermal limit, or an inductive voltage spike.

1. The Motor Hums but Will Not Turn

Symptom: The motor emits a loud buzzing or humming sound, the shaft is locked, and the current draw spikes to the stall limit.
Causes & Fixes:

  • Audible PWM Frequency: If the motor spins but "hums" loudly, your PWM frequency is likely set below 16kHz. Increase the pwmFreq variable in your code to 16000 or higher.
  • Mechanical Bind or Under-voltage: If the shaft is physically stalled, the H-bridge is applying full DC voltage (100% duty cycle) but the mechanical load exceeds the motor's stall torque. Reduce the load, increase the gear reduction ratio, or verify your power supply isn't sagging below 10V under heavy draw.

2. Driver Overheating and Thermal Shutdown

Symptom: The motor runs fine for 10 seconds, then stops. The H-bridge IC is too hot to touch. After a minute of cooling, it works again.
Causes & Fixes:

  • BJT Dropout (L298N): The L298N uses bipolar junction transistors, which inherently drop about 2V across the junction. At 2A, that is 4 Watts of heat dissipated directly into the silicon. Fix: Abandon the L298N for any load over 1A and switch to a MOSFET-based driver like the TB6612FNG or BTS7960, which operate on resistance (Rds(on)) rather than voltage drop, generating minimal heat.
  • Insufficient Heatsinking: Even MOSFET drivers like the BTS7960 will overheat at 30A+ without active cooling. Ensure the module's aluminum tab is mated to a proper heatsink with thermal paste, or add a 5V fan directed at the driver board.

3. Microcontroller Resets or Brownouts During Direction Changes

Symptom: The ESP32 or Arduino randomly reboots, or the serial monitor prints "Brownout detector was triggered" exactly when the motor stops or reverses direction.
Causes & Fixes:

  • Inductive Kickback (Back-EMF): A motor is an inductor. When you abruptly cut power or reverse polarity, the collapsing magnetic field generates a massive reverse voltage spike ($V = L \frac{di}{dt}$). This spike travels back through the power rails, overwhelming the microcontroller's 3.3V voltage regulator. Fix: Ensure your H-bridge has built-in Schottky flyback diodes. If using raw MOSFETs, you must solder external Schottky diodes (like the 1N5822) across the motor terminals. Additionally, power the ESP32 from a separate 5V buck converter rather than sharing the raw 12V rail directly with the motor's noisy supply.
  • Missing Common Ground: If the logic ground and motor ground are not tied together at a single star point, the back-EMF will seek the path of least resistance back to the source—often through your microcontroller's delicate GPIO pins, instantly frying the ESP32. Always verify ground continuity with a multimeter before applying motor power.

By respecting the stall current limits, utilizing MOSFET-based drivers, and properly managing inductive kickback, a PWM DC motor setup remains the most robust, cost-effective actuator choice for heavy-duty embedded projects.