The TB6612FNG is a small MOSFET dual motor driver. It does the same job as the familiar L298N, but wastes far less voltage and needs no heatsink. That makes it the better pick for battery robots with small gear motors.
On the Uno each motor needs one PWM pin and two direction pins: PWMA on D5 with AIN1/AIN2 on D7/D8, and PWMB on D6 with BIN1/BIN2 on D9/D10. STBY on D4 puts the driver to sleep when LOW. The chip’s logic runs from the Uno’s 5V, while the motors get their own battery on VM, with the grounds joined.
The sketch ramps both motors up, brakes, reverses, and then puts the driver into standby — every mode the chip has.
Wiring
| Arduino Uno R3 | TB6612FNG dual DC motor driver | Wire | Notes |
|---|---|---|---|
| — | A01 | — | To Motor A (+) (not drawn) |
| — | A02 | — | To Motor A (−) (not drawn) |
| — | B01 | — | To Motor B (+) (not drawn) |
| — | B02 | — | To Motor B (−) (not drawn) |
| 2× 18650 pack (7.4 V) or 4× AA · + | VM | red | Motor supply, 4.5–13.5 V. 10–100 µF capacitor across VM and GND. |
| 2× 18650 pack (7.4 V) or 4× AA · - | GND | black | |
| 5V | VCC | red | Logic supply, a few mA. |
| GND | GND | black | Common ground with the battery. |
| D5 | PWMA | orange | |
| D7 | AIN1 | yellow | |
| D8 | AIN2 | green | |
| D6 | PWMB | purple | |
| D9 | BIN1 | blue | |
| D10 | BIN2 | cyan | |
| D4 | STBY | white | HIGH = run, LOW = sleep. Tie it to 5V if you don’t need standby. |
Motor 4.5–13.5 V on VM; logic 2.7–5.5 V on VCC part, 5 V board. Logic follows VCC. Power VCC from 3.3 V on ESP32 and Pico, 5 V on Uno, and every control pin connects directly. The motor supply on VM is separate.
Board quirks
- MOSFET outputs drop only about 0.5 V at 1 A, so a 7.4 V pack gives the motors almost 7 V — about 1.5 V more than through an L298N. It also runs cool without a heatsink.
- The limit is current: 1.2 A per channel continuous (3.2 A peak). Small BO and N20 motors are fine; big 12 V geared motors that stall at 3 A+ need a bigger driver.
- PWM on D5/D6 runs at about 980 Hz. If the motors whine, that is why — the TB6612 can switch up to 100 kHz, but changing Timer0 on the Uno breaks
millis()anddelay(). - Both inputs HIGH is a short brake (the motor stops quickly); both LOW lets it coast. STBY LOW turns the outputs off entirely.
- Pin labels differ between boards:
A01/A02orAO1/AO2— they are the same outputs.
Code
// TB6612FNG dual motor driver on an Arduino Uno R3.
// PWMA → D5, AIN1 → D7, AIN2 → D8 (motor A); PWMB → D6, BIN1 → D9, BIN2 → D10 (motor B).
// STBY → D4 (HIGH = run). VCC → 5V, GND → GND, VM → battery + (4.5–13.5 V), battery − → GND.
const uint8_t PWMA = 5, AIN1 = 7, AIN2 = 8;
const uint8_t PWMB = 6, BIN1 = 9, BIN2 = 10;
const uint8_t STBY = 4;
// speed: -255 (reverse) .. 0 (coast) .. 255 (forward)
void motor(uint8_t pwm, uint8_t in1, uint8_t in2, int speed) {
digitalWrite(in1, speed > 0);
digitalWrite(in2, speed < 0);
analogWrite(pwm, abs(speed));
}
void brake() { // both inputs HIGH = short brake (stops faster than coasting)
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, HIGH);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, HIGH);
analogWrite(PWMA, 255);
analogWrite(PWMB, 255);
}
void setup() {
uint8_t pins[] = {PWMA, AIN1, AIN2, PWMB, BIN1, BIN2, STBY};
for (uint8_t p : pins) pinMode(p, OUTPUT);
digitalWrite(STBY, HIGH); // LOW puts the driver to sleep (outputs off)
Serial.begin(9600);
Serial.println(F("TB6612FNG test"));
}
void loop() {
Serial.println(F("Forward, ramping up"));
for (int s = 0; s <= 255; s += 5) {
motor(PWMA, AIN1, AIN2, s);
motor(PWMB, BIN1, BIN2, s);
delay(20);
}
delay(1000);
Serial.println(F("Brake"));
brake();
delay(500);
Serial.println(F("Reverse"));
motor(PWMA, AIN1, AIN2, -180);
motor(PWMB, BIN1, BIN2, -180);
delay(1500);
Serial.println(F("Standby"));
digitalWrite(STBY, LOW);
delay(2000);
digitalWrite(STBY, HIGH);
}// TB6612FNG dual motor driver on an Arduino Uno R3.
// PWMA → D5, AIN1 → D7, AIN2 → D8 (motor A); PWMB → D6, BIN1 → D9, BIN2 → D10 (motor B).
// STBY → D4 (HIGH = run). VCC → 5V, GND → GND, VM → battery + (4.5–13.5 V), battery − → GND.
const uint8_t PWMA = 5, AIN1 = 7, AIN2 = 8;
const uint8_t PWMB = 6, BIN1 = 9, BIN2 = 10;
const uint8_t STBY = 4;
// speed: -255 (reverse) .. 0 (coast) .. 255 (forward)
void motor(uint8_t pwm, uint8_t in1, uint8_t in2, int speed) {
digitalWrite(in1, speed > 0);
digitalWrite(in2, speed < 0);
analogWrite(pwm, abs(speed));
}
void brake() { // both inputs HIGH = short brake (stops faster than coasting)
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, HIGH);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, HIGH);
analogWrite(PWMA, 255);
analogWrite(PWMB, 255);
}
void setup() {
uint8_t pins[] = {PWMA, AIN1, AIN2, PWMB, BIN1, BIN2, STBY};
for (uint8_t p : pins) pinMode(p, OUTPUT);
digitalWrite(STBY, HIGH); // LOW puts the driver to sleep (outputs off)
Serial.begin(9600);
Serial.println(F("TB6612FNG test"));
}
void loop() {
Serial.println(F("Forward, ramping up"));
for (int s = 0; s <= 255; s += 5) {
motor(PWMA, AIN1, AIN2, s);
motor(PWMB, BIN1, BIN2, s);
delay(20);
}
delay(1000);
Serial.println(F("Brake"));
brake();
delay(500);
Serial.println(F("Reverse"));
motor(PWMA, AIN1, AIN2, -180);
motor(PWMB, BIN1, BIN2, -180);
delay(1500);
Serial.println(F("Standby"));
digitalWrite(STBY, LOW);
delay(2000);
digitalWrite(STBY, HIGH);
}Expected serial output
TB6612FNG test
Forward, ramping up
Brake
Reverse
StandbyTB6612FNG test Forward, ramping up Brake Reverse Standby
Common errors
Nothing moves, no heat, no sound
STBY is LOW or floating — it must be HIGH. Also check VM has the battery and GND is shared.
One direction works, the other doesn’t
One of the IN pins isn’t connected. Each motor needs both its IN1 and IN2 wired.
Driver gets hot and the motors slow down
More than 1.2 A per channel. The chip shuts down when it overheats; use smaller motors or a stronger driver.