Here are two reliable ways to control a brushed DC motor with Arduino—one-direction speed control (simplest) and full direction + speed with an H-bridge.
Option A — One direction (speed only) with a logic-level N-MOSFET
Use when: you just need on/off + speed control.
Parts
- Arduino (Uno/Nano/etc.)
- Logic-level N-MOSFET (e.g., IRLZ44N, IRLZ34N, AOZ1282 equivalent; not IRFZ44N)
- Flyback diode (e.g., 1N5819/SS14 or 1N5408)
- 100 Ω gate resistor, 10 kΩ gate-to-GND resistor
- Motor + external motor supply (e.g., 6–12 V)
- Wires; optional 100 µF bulk capacitor across motor supply
Wiring
Motor + ─────────── +VMOTOR (battery/PSU)
Motor − ──•── D (MOSFET)
|
S (MOSFET) ─── GND (shared with Arduino)
G (MOSFET) ── 100Ω ── D9 (PWM)
└─ 10kΩ ── GND (pull-down)
Flyback diode: anode to MOSFET D / motor−, cathode to +VMOTOR
Arduino GND ──────────────────── common with VMOTOR GND
Code (speed with PWM on pin 9)
const int PWM_PIN = 9; // any PWM-capable pin (Uno: 3,5,6,9,10,11)
void setup() {
pinMode(PWM_PIN, OUTPUT);
}
void loop() {
// ramp up
for (int s = 0; s <= 255; s++) { analogWrite(PWM_PIN, s); delay(10); }
delay(1000);
// ramp down
for (int s = 255; s >= 0; s--) { analogWrite(PWM_PIN, s); delay(10); }
delay(1000);
}
Notes
- Choose a MOSFET with low Rds(on) at Vgs = 4–5 V and current rating ≥ motor stall current.
- Keep Arduino 5 V separate from motor supply; only GND is common.
- Put a 0.1 µF ceramic across motor terminals (and 100 µF across supply) to tame noise.
Option B — Direction + speed with a dual H-bridge (e.g., TB6612FNG or DRV8833)
Use when: you need forward/reverse, brake, and efficient drive (better than L298N).
Parts
- Arduino
- TB6612FNG (pins: AIN1/AIN2/PWMA/STBY + BIN1/BIN2/PWMB if using 2nd channel)
- Motor + external supply (e.g., 6–12 V)
- Wires; decoupling caps
Wiring (one motor on channel A)
VM (driver) ─── +VMOTOR
GND (driver) ─── GND (shared with Arduino & motor supply)
VCC (driver) ─── 5V from Arduino
AIN1 ─────────── D7
AIN2 ─────────── D8
PWMA ─────────── D9 (PWM)
STBY ─────────── D6 (tie HIGH to enable)
Motor A+ ─────── Motor +
Motor A− ─────── Motor −
Code (forward/reverse/brake + PWM speed)
const int AIN1 = 7, AIN2 = 8, PWMA = 9, STBY = 6;
void setup() {
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(STBY, OUTPUT);
digitalWrite(STBY, HIGH); // exit standby
}
void drive(int speed) { // speed: -255..255 (sign = direction)
if (speed > 0) { digitalWrite(AIN1, HIGH); digitalWrite(AIN2, LOW); }
else if (speed < 0) { digitalWrite(AIN1, LOW); digitalWrite(AIN2, HIGH); speed = -speed; }
else { // brake
digitalWrite(AIN1, HIGH); digitalWrite(AIN2, HIGH);
}
analogWrite(PWMA, constrain(speed, 0, 255));
}
void loop() {
drive(180); delay(2000); // forward
drive(0); delay(500); // brake
drive(-180);delay(2000); // reverse
drive(0); delay(1000); // brake
}
Why TB6612/DRV8833 over L298N?
Much lower losses (MOSFET vs bipolar), runs cooler, works well at 3.3–5 V logic, handles fast PWM.
Sizing & safety checklist
- Supply: motor current at load and at stall; PSU must handle stall or use current limiting/slow-start.
- Grounds: Arduino GND ↔ motor driver GND must be common.
- Protection: always include a flyback path (diode or the H-bridge’s body diodes). Add a polyfuse if you expect stalls.
- Noise/EMI: twist motor wires, add caps (0.1 µF at motor, 100 µF near driver), keep high-current loops short.
- PWM frequency: Arduino Uno PWM is ~490 Hz (pins 3,9,10,11 ~490; 5,6 ~980 Hz). For audible whine reduction, use pins 5/6 or change timer prescalers/libraries.
Picking a driver (quick guide)
Top comments (0)