Bumper car on an Arduino Uno
A 2WD robot car on a DRV8833 with two lever microswitches for bumpers. It drives until a bumper is hit, then backs off and turns away from that side. 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.
IntermediateRuns in your browser. Free, and no account needed.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Bumper car: a 2WD chassis on a DRV8833, with two lever microswitches
// mounted on the front corners as bumpers.
//
// DRV8833 AIN1 pin 5, AIN2 pin 6 left motor
// BIN1 pin 9, BIN2 pin 10 right motor
// VM from the four-AA pack (6 V), GND to the Uno's GND
// SLP left unwired: the breakout pulls it up, so the chip is awake
// bumpers COM to GND, NO to pin 7 (left) and pin 8 (right), INPUT_PULLUP
//
// The DRV8833 has two inputs per motor and no enable pin. One input held low
// and a PWM on the other is drive and coast in turn, so the duty is the speed.
// Both low coasts; both high brakes.
//
// A bumper reads LOW while it is pressed, because its NO contact joins the pin
// to ground. The car backs off and turns away from whichever side hit. Hold a
// switch with the mouse to bump the car on the canvas.
const int AIN1 = 5;
const int AIN2 = 6;
const int BIN1 = 9;
const int BIN2 = 10;
const int BUMP_LEFT = 7;
const int BUMP_RIGHT = 8;
const int CRUISE = 180;
// One motor as a signed speed, -255 to 255: PWM on one input, the other low.
void motor(int in1, int in2, int speed) {
if (speed >= 0) {
digitalWrite(in2, LOW);
analogWrite(in1, speed > 255 ? 255 : speed);
} else {
digitalWrite(in1, LOW);
analogWrite(in2, -speed > 255 ? 255 : -speed);
}
}
void drive(int left, int right) {
motor(AIN1, AIN2, left);
motor(BIN1, BIN2, right);
}
void brake() {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, HIGH);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, HIGH);
}
void escape(const char *side, int turnLeft, int turnRight) {
Serial.print("bumped on the ");
Serial.print(side);
Serial.println(": back off and turn away");
brake();
delay(150);
drive(-CRUISE, -CRUISE);
delay(500);
drive(turnLeft, turnRight);
delay(400);
}
void setup() {
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(BUMP_LEFT, INPUT_PULLUP);
pinMode(BUMP_RIGHT, INPUT_PULLUP);
Serial.begin(115200);
Serial.println("bumper car: ready");
}
void loop() {
if (digitalRead(BUMP_LEFT) == LOW) {
escape("left", CRUISE, -CRUISE);
} else if (digitalRead(BUMP_RIGHT) == LOW) {
escape("right", -CRUISE, CRUISE);
} else {
drive(CRUISE, CRUISE);
}
delay(10);
}
Parts list
6 parts, plus the jumper wires. Every one is in the editor's parts bin.
How it is wired
15 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
- Arduino Uno R3 pin 10; Motor driver, DRV8833 pin BIN2
- Arduino Uno R3 pin 9; Motor driver, DRV8833 pin BIN1
- Arduino Uno R3 pin 8; Limit switch, lever microswitch (2) pin NO
- Arduino Uno R3 pin 7; Limit switch, lever microswitch (1) pin NO
- Arduino Uno R3 pin 6; Motor driver, DRV8833 pin AIN2
- Arduino Uno R3 pin 5; Motor driver, DRV8833 pin AIN1
- 6 V: Motor driver, DRV8833 pin VM
- Ground: Motor driver, DRV8833 pin GND
- Motor driver, DRV8833 pin AOUT1; Robot car chassis, 2WD pin L+
- Motor driver, DRV8833 pin AOUT2; Robot car chassis, 2WD pin L-
- Motor driver, DRV8833 pin BOUT1; Robot car chassis, 2WD pin R+
- Motor driver, DRV8833 pin BOUT2; Robot car chassis, 2WD pin R-
- Ground: Limit switch, lever microswitch (1) pin COM
- Ground: Limit switch, lever microswitch (2) pin COM
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.