Built-in project · Arduino Uno R3

IBT-2 motor speed control with a knob on an Arduino Uno

A knob on A0 runs a 12 V motor on an IBT-2 (BTS7960): stop in the middle, forward one way and reverse the other, with a dead band and a soft ramp. 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 Runs in your browser. Free, and no account needed.

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

IBT-2 motor speed control with a knob · Arduino Uno R3live0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

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
// IBT-2 (BTS7960) motor speed control with a knob: the middle of the knob is
// stop, turn it one way for forward and the other for reverse, faster the
// further it goes.
//
//   A0      the potentiometer's wiper (its ends on 5 V and GND)
//   IBT-2   RPWM -> pin 5, LPWM -> pin 6, R_EN and L_EN -> pin 7
//           VCC -> 5V, GND -> GND
//           B+ / B- -> a 12 V battery, M+ / M- -> the motor
//
// The IBT-2 is two BTS7960 half bridges, good for a big 12 V motor that would
// cook an L298N. With both enables high, PWM on RPWM drives M+ (forward) and
// PWM on LPWM drives M- (reverse). Never PWM both at once: the sketch always
// sets one side to 0 before it drives the other.
//
// Two things a bare analogWrite(knob / 4) gets wrong on a big motor:
//
// A dead band. A knob never sits exactly in the middle, and a motor that
// creeps at "stop" is a nuisance, so the middle DEAD counts are stop.
//
// A ramp. Snapping a heavy motor from full forward to full reverse slams the
// gearbox and pulls a current spike from the battery. The output moves at
// most STEP every 10 ms, so 0 to full takes about half a second, and a
// reversal always passes through stop.
//
// Press Run, then turn the knob either side of the middle.

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

const int DEAD = 50;  // counts either side of 512
const int STEP = 5;   // the most the output changes in 10 ms

int output = 0;  // -255 full reverse .. 255 full forward
int printed = 999;

void drive(int s) {
  if (s >= 0) {
    analogWrite(LPWM, 0);
    analogWrite(RPWM, s);
  } else {
    analogWrite(RPWM, 0);
    analogWrite(LPWM, -s);
  }
}

// The knob as a target from -255 to 255, stop in the middle.
int target() {
  int offset = analogRead(KNOB) - 512;
  if (abs(offset) <= DEAD) return 0;
  int s = map(abs(offset), DEAD, 511, 0, 255);
  if (s > 255) s = 255;
  return offset > 0 ? s : -s;
}

void setup() {
  pinMode(EN, OUTPUT);
  digitalWrite(EN, HIGH);
  drive(0);
  Serial.begin(9600);
  Serial.println("IBT-2 speed control: middle is stop, turn either way");
}

void loop() {
  int want = target();
  if (want > output) output = min(output + STEP, want);
  if (want < output) output = max(output - STEP, want);
  drive(output);

  // Print once the ramp has caught up with the knob.
  if (output == want && output != printed) {
    printed = output;
    if (output > 0) Serial.print("forward ");
    else if (output < 0) Serial.print("reverse ");
    else Serial.print("stop ");
    Serial.print(abs(output) * 100L / 255);
    Serial.println(" %");
  }
  delay(10);
}

Parts list

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

How it is wired

11 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Ground: Arduino Uno R3 pin GND; IBT-2 BTS7960 motor driver, 43 A pin GND
  • Arduino Uno R3 pin 7; IBT-2 BTS7960 motor driver, 43 A pin R_EN; IBT-2 BTS7960 motor driver, 43 A pin L_EN
  • Arduino Uno R3 pin 6; IBT-2 BTS7960 motor driver, 43 A pin LPWM
  • Arduino Uno R3 pin 5; IBT-2 BTS7960 motor driver, 43 A pin RPWM
  • Arduino Uno R3 pin 5V; Potentiometer pin 3; IBT-2 BTS7960 motor driver, 43 A pin VCC
  • Ground: Arduino Uno R3 pin GND; Potentiometer pin 1
  • Arduino Uno R3 pin A0; Potentiometer pin 2
  • 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-; Battery: AA, coin cell, LiPo pin V-
  • IBT-2 BTS7960 motor driver, 43 A pin M+; DC motor pin 1
  • IBT-2 BTS7960 motor driver, 43 A pin M-; DC motor pin 2

Change it and keep it

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