The Short Answer: Sizing a PWM Controller for Your DC Motor
The correct PWM controller for a DC motor must have a continuous current rating of at least 1.5 times the motor’s stall current, not just its operating current. If you size a driver based only on the nominal running amperage printed on the nameplate, the inrush current during startup or a sudden mechanical jam will instantly fry the driver’s internal MOSFETs.
The Math: 15A (stall) × 1.5 (safety margin) = 22.5A minimum driver rating.
The Pick: A standard L298N (rated 2A continuous) will melt. You need a heavy-duty MOSFET H-bridge like the BTS7960 (43A peak, ~25A continuous with active cooling) to handle the 22.5A requirement safely.
Motor Type Comparison: Which Drive Fits Your Load Profile?
Before selecting a PWM driver, you must confirm the motor topology. Brushed DC, Brushless DC (BLDC), and Stepper motors require fundamentally different control signals. Treating a stepper as a continuous-rotation DC motor, or attempting to drive a BLDC with a simple 2-wire PWM H-bridge, will result in immediate failure.
| Motor Type | Torque Curve & Profile | Control Needs | Relative Cost | Best Application |
|---|---|---|---|---|
| Brushed DC | High starting torque, drops linearly as speed increases. | Simple 2-wire PWM for speed; H-bridge for direction. | $ | Conveyors, winches, simple mobile robots. |
| Brushless (BLDC) | Flat torque curve across a wide RPM range; high efficiency. | 3-phase commutation via ESC or FOC (Field Oriented Control) driver. | $$$ | Drones, high-speed spindles, advanced EV traction. |
| Stepper | Maximum torque at zero RPM (holding torque); drops sharply at speed. | Open-loop step/direction pulses; requires a dedicated chopper driver. | $$ | CNC routers, 3D printers, precise linear actuators. |
Note: Steppers are designed for precise positional holding, not continuous high-speed dynamic loads. Do not substitute a stepper motor where a Brushed DC or BLDC is required for sustained rotational work. For the remainder of this guide, we are focusing strictly on Brushed DC motors, as they are the primary use case for standard 2-wire PWM controllers in embedded projects.
Wiring and Terminal Identification for Brushed DC Drives
When wiring a microcontroller (like an Arduino Uno or ESP32) to a high-power PWM driver, you must isolate the logic-level signals from the high-current motor power. Below is the standard terminal identification for the widely used BTS7960 high-power driver module, which is the workhorse for 12V/24V DC loads up to 30A.
BTS7960 Terminal Map
| Terminal Label | Function | Connection Target |
|---|---|---|
| B+ / B- | Main power input (5.5V to 27V DC). | 12V/24V battery or bench power supply. |
| M+ / M- | Motor output terminals. | Brushed DC motor leads (polarity dictates default direction). |
| 5V / VCC | Logic power input (if not using onboard optocouplers). | Microcontroller 5V or 3.3V pin (check module opto-isolation). |
| GND | Common logic ground. | Microcontroller GND (CRITICAL: must share ground with ESP32/Arduino). |
| PWM (or IN1) | Speed control signal (0-5V/3.3V, 1kHz-20kHz). | ESP32 LEDC pin or Arduino PWM pin. |
| DIR (or IN2) | Direction control (HIGH = Forward, LOW = Reverse). | Any standard digital GPIO pin. |
| EN (Enable) | Activates the H-bridge. | Tied to 5V/VCC for always-on, or a GPIO for fault-shutdown. |
analogWrite() function in its standard Arduino core. You must use the ledc (LED Control) peripheral to generate the PWM signal. Set the frequency to at least 1,000 Hz to prevent the motor from whining, but keep it below 20,000 Hz to avoid excessive switching losses in the driver MOSFETs.
The Decision Path: Picking Your Exact PWM Driver Module
Use this decision tree to select the exact driver module based on your measured stall current and operating voltage. This path terminates in concrete part numbers available from standard makerspace suppliers like Pololu, SparkFun, or Adafruit.
| Load Profile (Stall Current) | Voltage Range | Recommended Driver IC / Module | Why This Pick? |
|---|---|---|---|
| < 1.2A Stall | 4.5V - 13.5V | TB6612FNG (Pololu #713 or SparkFun ROB-14451) | MOSFET-based. Minimal voltage drop (~0.5V) compared to older BJT drivers. Handles 1.2A continuous, 3.2A peak. |
| 1.5A - 5A Stall | 6V - 24V | DRV8871 (TI / Pololu #2991) | Single H-bridge, highly efficient. 3.6A continuous. Replaces the obsolete and inefficient L298N for mid-size loads. |
| 10A - 30A Stall | 5.5V - 27V | BTS7960 (Generic 43A modules) | Massive current handling. Requires a heatsink and active cooling for continuous loads >15A. Internal flyback diodes. |
| > 40A Stall / FOC | 12V - 48V | ODrive v3.6 or VESC 6 | Required when moving from simple PWM to closed-loop Field Oriented Control for high-torque BLDC or massive DC traction motors. |
Source: For deeper technical specifications on motor driver IC topologies, refer to the Texas Instruments Motor Drivers Overview and Pololu’s Guide to DC Motors.
Reading Failure Signatures: Hum, Overheat, and Stall
When a PWM controller and DC motor are mismatched or improperly wired, the system will exhibit specific physical and electrical failure signatures. Diagnose the root cause using these bench-tested symptoms.
1. The Audible Hum or Whine
- Symptom: The motor emits a high-pitched whine or a low-frequency hum, even when the shaft is spinning freely.
- Cause: Your PWM frequency is set incorrectly. A frequency below 20kHz falls into the human hearing range, causing the motor windings and internal laminations to vibrate acoustically. A low-frequency hum (e.g., 50Hz) usually indicates the microcontroller is outputting a standard AC mains frequency or a severely misconfigured timer.
- Fix: Adjust your microcontroller code to output a PWM frequency between 1,000 Hz and 16,000 Hz. On an ESP32, configure
ledcSetup(channel, 5000, 8)for a 5kHz baseline.
2. Driver Overheat and Thermal Shutdown
- Symptom: The driver IC becomes too hot to touch within 30 seconds, and the motor abruptly stops (thermal protection latch).
- Cause: You are exceeding the continuous current rating, or you are using a BJT-based driver (like the L298N) without accounting for its massive internal voltage drop. The L298N drops roughly 2V to 3V across its Darlington pairs; at 2A, that’s 4W to 6W of pure heat dissipated directly into the silicon.
- Fix: Switch to a MOSFET-based driver (TB6612FNG or BTS7960) where the RDS(on) is measured in milliohms, reducing heat generation to a fraction of a watt. Ensure your module has adequate heatsinking and airflow.
3. Microcontroller Brownout and Stall
- Symptom: The moment the motor starts or hits a mechanical load, the ESP32 or Arduino resets, drops its WiFi connection, or the motor simply stalls and clicks.
- Cause: Voltage sag on the shared power rail. The motor’s inrush stall current pulls the supply voltage down below the microcontroller’s brownout detection threshold (typically ~2.8V for an ESP32’s internal regulator).
- Fix:
- Use completely separate power supplies for the motor and the microcontroller, tying only their GND pins together.
- Add bulk capacitance (e.g., a 4700µF electrolytic capacitor) directly across the motor driver’s B+ and B- terminals to absorb the inrush spike.
- Implement a soft-start in your code: ramp the PWM duty cycle from 0 to target over 500ms rather than snapping it to 100% instantly.
Final Recommendation: The Default Workhorse Setup
If you are building a 12V or 24V embedded project involving motors that draw more than a few amps (like a robotic rover, an automated gate, or a motorized winch), skip the outdated L298N entirely.
The Default Pick: Buy a BTS7960 43A module (typically $8–$12 USD). Pair it with an ESP32 DevKit v1 using the ledc peripheral for 5kHz PWM control. Wire the logic grounds together, add a 4700µF bulk capacitor on the motor power rail, and size your inline fuse to 1.2x the motor’s continuous running current. This setup provides massive headroom for stall events, runs cool under load, and eliminates the brownout resets that plague under-specced driver boards.






