Built-in project · Arduino Uno R3

TB6612 robot drive on an Arduino Uno

Two gearbox motors on a TB6612FNG from a four-AA pack, with the SparkFun library: forward, half speed, a spin, reverse, a brake and standby. The whole build, an Arduino Uno and 4 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Intermediate About 25 minutes to build and run. Runs in your browser. Free, and no account needed.

The parts retail for about $34. On Mokxi they're free.

The circuit runs here once the page has loaded.

What you'll learn

  • Driving two motors with a TB6612FNG and the SparkFun library
  • Keeping a separate motor supply on a common ground
  • Speed and direction from one signed number
  • The difference between braking and coasting
  • Difficulty: Intermediate
  • Time: About 25 minutes
  • Board: Arduino Uno R3
  • Parts: 5

How it works

A TB6612FNG driver runs two motors from a four-AA pack. Pins 5 and 6 set each side's speed with PWM. Pins 2 and 4 set the left direction, and 7 and 8 set the right. Pin 9 is STBY, and the driver does nothing unless it is high. The motors get power through VM from the pack, and the grounds are joined.

The SparkFun library handles the pin work. The loop repeats a show: forward at full speed, forward at half speed, a spin left, reverse, a brake, and a standby where both motors coast. Each step is described in the serial monitor.

Parts list

5 parts, plus the jumper wires. They retail for about $34; on Mokxi they're free.

Wiring table

Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.

Part and pinConnects to
Motor driver, TB6612FNG pin GND1Arduino Uno R3 pin GND
Motor driver, TB6612FNG pin STBYArduino Uno R3 pin 9
Motor driver, TB6612FNG pin BIN2Arduino Uno R3 pin 8
Motor driver, TB6612FNG pin BIN1Arduino Uno R3 pin 7
Motor driver, TB6612FNG pin PWMBArduino Uno R3 pin 6
Motor driver, TB6612FNG pin PWMAArduino Uno R3 pin 5
Motor driver, TB6612FNG pin AIN2Arduino Uno R3 pin 4
Motor driver, TB6612FNG pin AIN1Arduino Uno R3 pin 2
Motor driver, TB6612FNG pin VCCArduino Uno R3 pin 5V
Battery: AA, coin cell, LiPo pin V+Motor driver, TB6612FNG pin VM
DC motor (1) pin 1Motor driver, TB6612FNG pin AO1
DC motor (1) pin 2Motor driver, TB6612FNG pin AO2
DC motor (2) pin 2Motor driver, TB6612FNG pin BO2
DC motor (2) pin 1Motor driver, TB6612FNG pin BO1
Battery: AA, coin cell, LiPo pin V-Motor driver, TB6612FNG pin GND3

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// TB6612 robot drive: two motors on a TB6612FNG, the way the SparkFun
// Inventor's Kit wires it, off a pack of four AA cells.
//
//   pin 5  PWMA, the left motor's speed      pin 6  PWMB, the right motor's
//   pin 2  AIN1   pin 4  AIN2                pin 7  BIN1   pin 8  BIN2
//   pin 9  STBY, which must be high or the driver does nothing
//   VCC    the Uno's 5 V (the logic side)    VM  the battery pack's red lead
//   GND    the Uno's GND and the pack's black lead, on one ground
//
// SparkFun_TB6612.h does the pin work: drive(speed) takes -255 to 255, the
// sign is the direction, and brake() shorts the motor through the bridge.
//
// # Why the pack, and not the Uno's 5 V
//
// Motors are noisy and hungry. A separate motor rail is how every robot is
// built, and the TB6612's MOSFET bridge keeps only a fraction of a volt of
// it, where an L293D keeps more than two. Four fresh AA cells are 6.4 V with
// nothing on them and a little less once the motors start: the battery sags
// by its own internal resistance, and the readout on the pack shows it.
//
// # Brake or coast
//
// On this chip PWM low is a short brake, not a coast, so analogWrite at half
// speed stops the motor firmly between pulses. brake() is the same thing held
// on; standby() lets both motors coast to a stop.

#include <SparkFun_TB6612.h>

const int AIN1 = 2;
const int AIN2 = 4;
const int PWMA = 5;
const int BIN1 = 7;
const int BIN2 = 8;
const int PWMB = 6;
const int STBY = 9;

// 1 or -1: flip one if a motor was wired the other way round.
const int offsetA = 1;
const int offsetB = 1;

Motor leftMotor = Motor(AIN1, AIN2, PWMA, offsetA, STBY);
Motor rightMotor = Motor(BIN1, BIN2, PWMB, offsetB, STBY);

void say(const char *what) {
  Serial.print("drive: ");
  Serial.println(what);
}

void setup() {
  Serial.begin(115200);
  Serial.println("Mokxi Arduino Uno: two motors on a TB6612FNG");
}

void loop() {
  say("forward, full speed");
  forward(leftMotor, rightMotor, 255);
  delay(1500);

  say("forward, half speed (PWM low brakes between pulses)");
  forward(leftMotor, rightMotor, 128);
  delay(1500);

  say("spin left on the spot");
  left(leftMotor, rightMotor, 255);
  delay(1200);

  say("reverse");
  back(leftMotor, rightMotor, 200);
  delay(1500);

  say("brake");
  brake(leftMotor, rightMotor);
  delay(1000);

  say("standby: both motors coast");
  leftMotor.standby();
  delay(1500);
}

Code walkthrough

The key functions of the sketch, and what each one does.

say sketch.ino

Prints a line to the serial monitor that starts with drive: and then the name of the move. It is how you follow which step of the show the motors are on.

void say(const char *what) {
  Serial.print("drive: ");
  Serial.println(what);
}

loop sketch.ino

Runs the show with library calls. forward at 255 and then 128, left to spin on the spot, back at 200, then brake. Last, leftMotor.standby() lets both motors coast. Each step is held with a delay of 1000 to 1500 ms.

void loop() {
  say("forward, full speed");
  forward(leftMotor, rightMotor, 255);
  delay(1500);

  say("forward, half speed (PWM low brakes between pulses)");
  forward(leftMotor, rightMotor, 128);
  delay(1500);

  say("spin left on the spot");
  left(leftMotor, rightMotor, 255);
  delay(1200);

  say("reverse");
  back(leftMotor, rightMotor, 200);
  delay(1500);

  say("brake");
  brake(leftMotor, rightMotor);
  delay(1000);

  say("standby: both motors coast");
  leftMotor.standby();
  delay(1500);
}

Troubleshooting

The usual mistakes with this circuit, and the fix for each.

  • Nothing moves This project
    Check pin 9 goes to STBY. The driver does nothing unless STBY is high.
  • A wheel spins the wrong way This project
    Change offsetA or offsetB from 1 to -1 for that motor.
  • The motors do not move. Motor driver
    Set STBY HIGH. Power the motors at VM (about 4.5 to 13.5 V) and logic at VCC. Join all grounds. Then set the direction pins and a PWM level on the PWM pin.
  • The motor stops hard instead of coasting. Motor driver
    Both input pins HIGH, or PWM at 0, brakes the motor. To let it coast, set both inputs LOW with PWM high. Per channel the chip handles about 1.2 A continuous.
  • The motor does not spin, or the pin gets hot or the board resets when it is wired straight to a GPIO pin. DC motor
    A pin gives about 20 mA and a motor needs far more. Drive it through a transistor or motor driver, with its own supply and a shared ground.
  • The transistor or pin is damaged by spikes when the motor stops. DC motor
    Put a flyback diode across the motor, cathode to the positive side. A motor is a coil and kicks back voltage when switched off. Add a 0.1 uF capacitor across the motor terminals to cut noise.
  • The battery is wired backwards, or the voltage is too low or too high for the circuit. A fresh AA is about 1.5 V, a LiPo is 3.7 V nominal and 4.2 V full. Battery: AA
    Match the plus and minus marks. Check the voltage your parts need. Two AAs make 3 V, four make 6 V. Never feed a LiPo to a 3.3 V chip directly at 4.2 V.
  • The circuit resets or browns out when a motor or servo starts. A battery has internal resistance, so the voltage sags under load. Battery: AA
    Use a fresh pack with enough current rating. Add a 100 uF or larger capacitor near the load. Power motors from their own pack and join the grounds.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.