Built-in project · Arduino Uno R3

IBT-2 BTS7960 big motor driver on an Arduino Uno

An IBT-2 on pins 5, 6 and 7 ramps a 12 V motor off a lead-acid battery forward and back with analogWrite, then lets it coast. The whole build, an Arduino Uno and 3 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 20 minutes to build and run. Runs in your browser. Free, and no account needed.

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

The circuit runs here once the page has loaded.

What you'll learn

  • H-bridge drivers and two PWM inputs for two directions
  • Powering a motor from its own battery
  • Using enable pins to switch a driver on and off
  • Signed speed values from -255 to 255
  • Coasting versus driving
  • Difficulty: Intermediate
  • Time: About 20 minutes
  • Board: Arduino Uno R3
  • Parts: 4

How it works

The IBT-2 is a big motor driver with two half bridges. The Uno gives it logic signals, and a separate 12 V battery on B+ and B- powers the motor on M+ and M-. The grounds are joined, and the driver's logic gets 5V from the Uno.

Pin 7 enables both sides. Pin 5 is PWM for one direction (RPWM) and pin 6 is PWM for the other (LPWM). The sketch ramps the motor forward in five steps, stops for half a second, ramps in reverse, then lets it coast for a second.

Parts list

4 parts, plus the jumper wires. They retail for about $39; 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
IBT-2 BTS7960 motor driver, 43 A pin GNDArduino Uno R3 pin GND
IBT-2 BTS7960 motor driver, 43 A pin R_ENArduino Uno R3 pin 7
IBT-2 BTS7960 motor driver, 43 A pin L_ENArduino Uno R3 pin 7
IBT-2 BTS7960 motor driver, 43 A pin LPWMArduino Uno R3 pin 6
IBT-2 BTS7960 motor driver, 43 A pin RPWMArduino Uno R3 pin 5
IBT-2 BTS7960 motor driver, 43 A pin VCCArduino Uno R3 pin 5V
Battery: AA, coin cell, LiPo pin V+IBT-2 BTS7960 motor driver, 43 A pin B+
Battery: AA, coin cell, LiPo pin V-IBT-2 BTS7960 motor driver, 43 A pin B-
DC motor pin 1IBT-2 BTS7960 motor driver, 43 A pin M+
DC motor pin 2IBT-2 BTS7960 motor driver, 43 A pin M-

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
// A big brushed motor on an IBT-2 (two BTS7960 half bridges), from an Uno.
//
//   IBT-2 RPWM -> pin 5    LPWM -> pin 6    R_EN, L_EN -> pin 7
//   IBT-2 VCC -> 5V        GND -> GND
//   IBT-2 B+ / B- -> a 12 V battery,  M+ / M- -> the motor
//
// Each half bridge runs while its EN pin is high: RPWM drives M+, LPWM drives
// M-. PWM on one side with the other side low runs the motor one way; swap
// them for the other. Both low brakes, and the enables low let it coast.
// The IBT-2's inputs go through a 74HC244 on 5 V, so they want 5 V logic.

const int RPWM = 5;
const int LPWM = 6;
const int EN = 7;

void drive(int speed) {
  // speed from -255 (full reverse) to 255 (full forward)
  if (speed >= 0) {
    analogWrite(LPWM, 0);
    analogWrite(RPWM, speed);
  } else {
    analogWrite(RPWM, 0);
    analogWrite(LPWM, -speed);
  }
}

void setup() {
  pinMode(EN, OUTPUT);
  digitalWrite(EN, HIGH);
  Serial.begin(9600);
  Serial.println("Mokxi Uno: IBT-2 ramps the motor forward, then back");
}

void loop() {
  for (int s = 0; s <= 255; s += 51) {
    drive(s);
    Serial.print("forward ");
    Serial.println(s);
    delay(400);
  }
  drive(0);
  delay(500);
  for (int s = 0; s <= 255; s += 51) {
    drive(-s);
    Serial.print("reverse ");
    Serial.println(s);
    delay(400);
  }
  digitalWrite(EN, LOW);
  Serial.println("coast");
  delay(1000);
  digitalWrite(EN, HIGH);
}

Code walkthrough

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

drive sketch.ino

Takes a speed from -255 to 255. If it is zero or more, LPWM is set to 0 and RPWM gets the speed, so the motor turns forward. If it is negative, RPWM is set to 0 and LPWM gets the positive amount, so it turns the other way.

void drive(int speed) {
  // speed from -255 (full reverse) to 255 (full forward)
  if (speed >= 0) {
    analogWrite(LPWM, 0);
    analogWrite(RPWM, speed);
  } else {
    analogWrite(RPWM, 0);
    analogWrite(LPWM, -speed);
  }
}

setup sketch.ino

Makes EN an output and sets it HIGH, which turns on both half bridges. It then opens the serial port and prints a line saying what the sketch will do.

void setup() {
  pinMode(EN, OUTPUT);
  digitalWrite(EN, HIGH);
  Serial.begin(9600);
  Serial.println("Mokxi Uno: IBT-2 ramps the motor forward, then back");
}

loop sketch.ino

Steps the speed from 0 to 255 in jumps of 51, 400 ms each, printing every step. It stops for 500 ms, then does the same in reverse. Finally it drops EN low so the motor coasts for a second, and turns it back on.

void loop() {
  for (int s = 0; s <= 255; s += 51) {
    drive(s);
    Serial.print("forward ");
    Serial.println(s);
    delay(400);
  }
  drive(0);
  delay(500);
  for (int s = 0; s <= 255; s += 51) {
    drive(-s);
    Serial.print("reverse ");
    Serial.println(s);
    delay(400);
  }
  digitalWrite(EN, LOW);
  Serial.println("coast");
  delay(1000);
  digitalWrite(EN, HIGH);
}

Troubleshooting

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

  • The motor does not move This project
    Check that pin 7 reaches both R_EN and L_EN, and that the battery is on B+ and B-.
  • The motor only turns one way This project
    Both RPWM on pin 5 and LPWM on pin 6 must be wired. Each one drives one direction.
  • The motor does not move. IBT-2 BTS7960 motor driver
    Pull R_EN and L_EN high (tie them to 5 V). Send PWM to RPWM for one direction and LPWM for the other. Join the grounds of the Arduino and motor supply.
  • Both PWM inputs are driven at once. IBT-2 BTS7960 motor driver
    Drive only one of RPWM and LPWM at a time, with the other at zero. Driving both fights the bridge and can overheat it.
  • 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.