SparkFun Inventor's Kit for RedBot
This Tutorial is Retired!
This tutorial covers concepts or technologies that are no longer current. It's still here for you to read and enjoy, but may not be as useful as our newest tutorials.
View the updated tutorial: Experiment Guide for RedBot with Shadow Chassis
Experiment 5: Bumpers
Now let's experiment with the whisker bumpers. These super simple switches let you detect a collision before it happens - the whisker will feel a bump just before your robot crashes into it.
One of the most useful elements of the Arduino is its ability to send messages back to a computer over a USB connection. This is accomplished with the "Serial" library, and it allows you to, among other things,report fairly complicated debugging information (reading back variable values, setting multiple different messages to occur under different circumstances, etc).
We're also going to introduce the concept of "conditional" code - code that only executes when some condition is true. Conditionals are the key to making robots do interesting things; here, we're going to use the simplest conditional: the if() statement.
Let’s load this experiment onto the RedBot. Go to File > Examples > RedBot_Experiments > Exp5_Bumpers or copy and paste the example code below:
language:c
/***********************************************************************
* Exp5_Bumpers -- RedBot Experiment 5
*
* Now let's experiment with the whisker bumpers. These super-simple switches
* let you detect a collision before it really happens- the whisker will
* bump something before your robot crashes into it.
*
* This sketch was written by SparkFun Electronics, with lots of help from
* the Arduino community.
* This code is completely free for any use.
* Visit https://learn.sparkfun.com/tutorials/redbot-inventors-kit-guide
* for SIK information.
*
* 8 Oct 2013 M. Hord
* Revised 30 Oct 2014 B. Huang
***********************************************************************/
#include <RedBot.h>
RedBotMotors motors;
RedBotBumper lBumper = RedBotBumper(3); // initialzes bumper object on pin 3
RedBotBumper rBumper = RedBotBumper(11); // initialzes bumper object on pin 11
int buttonPin = 12; // variable to store the button Pin
int lBumperState; // state variable to store the bumper value
int rBumperState; // state variable to store the bumper value
void setup()
{
// nothing here.
}
void loop()
{
motors.drive(255);
lBumperState = lBumper.read(); // default INPUT state is HIGH, it is LOW when bumped
rBumperState = rBumper.read(); // default INPUT state is HIGH, it is LOW when bumped
if (lBumperState == LOW) // left side is bumped/
{
reverse(); // backs up
turnRight(); // turns
}
if (rBumperState == LOW) // right side is bumped/
{
reverse(); // backs up
turnLeft(); // turns
}
}
// reverse() function -- backs up at full power
void reverse()
{
motors.drive(-255);
delay(500);
motors.brake();
delay(100); // short delay to let robot fully stop
}
// turnRight() function -- turns RedBot to the Right
void turnRight()
{
motors.leftMotor(-150); // spin CCW
motors.rightMotor(-150); // spin CCW
delay(500);
motors.brake();
delay(100); // short delay to let robot fully stop
}
// turnRight() function -- turns RedBot to the Left
void turnLeft()
{
motors.leftMotor(+150); // spin CW
motors.rightMotor(+150); // spin CW
delay(500);
motors.brake();
delay(100); // short delay to let robot fully stop
}
What You Should See
In this experiment, the RedBot should start driving forward until one of the bumpers is hit. When the right side is bumped, the RedBot should reverse and turn the left. When the left side is bumped, the RedBot should reverse and turn right.
Manipulate the timing and the motorPower settings so that your RedBot backs up 12 inches and turns a full 90 degrees after each bump.
Code to Note
Above the setup() and loop(), we declare and initialize two bumper objects using the RedBotBumper class. The initialize statement takes a single parameter indicating which pin the whisker is connected to.
language:c
RedBotBumper lBumper = RedBotBumper(3); // initializes bumper object on pin 3
RedBotBumper rBumper = RedBotBumper(11); // initializes bumper object on pin 11
The initialize statement automatically sets up the pin with an internal pull-up resistor. This forces the default / nominal state of the input to be HIGH. Not sure what a pull-up resistor is? Check out our Pull-up Resistors tutorial!
lBumper.read()
and rBumper.read()
returns the state of the bumper. When the RedBot is bumped, the whisker makes contact with a screw bolt that is connected to GND. Therefore, a bump is detected as LOW
. We introduce the use of state variables in this example. We read in the state of each bumper and store these in two variables called lBumperState
and rBumperState
.
language:c
lBumperState = lBumper.read(); // default INPUT state is HIGH, it is LOW when bumped
rBumperState = rBumper.read(); // default INPUT state is HIGH, it is LOW when bumped
Learn More: if() Statements
Want to know how to use logic like a Vulcan? One of the things that makes the RedBot so useful is that it can make complex decisions based on the input it's getting. For example, you could make a thermostat that turns on a heater if it gets too cold, or a fan if it gets too hot, waters your plants if they get too dry, etc.
Conditional Statements
In order to make these decisions, the Arduino environment provides a set of logic operations that let you make decisions based on conditions or comparisons. Conditional statements should be grouped together using parentheses - e.g. (A == B). These "test" statements or comparisons include:
Symbol | Name | Description |
== | IS EQUAL TO? | A == B is true if A and B are the SAME. |
!= | IS NOT EQUAL TO? | (A != B) is true if A and B are NOT THE SAME. |
> | GREATER THAN | (A > B) is true if A is greater than B. |
< | LESS THAN | (A< B) is true if A is less than B. |
>= | GREATER THAN OR EQUAL TO | (A >= B) is true if A is greater than or equal to B. |
<= | LESS THAN OR EQUAL TO | (A <= B) is true if A is less than or equal to B. |
Compound Conditional Statements
Often you might want to string together multiple conditional statements together. The Arduino environment allows us to "chain together" or combine multiple conditional statements with a few symbols. You can combine these symbols to build complex if() statements.
Symbol | Name | Description |
&& | AND | (condition X) && (condition Y) is true only if BOTH (condition X) and (condition Y) are true. |
|| | OR | (condition X) || (condition Y) is true if condition X is TRUE or condition Y is TRUE or BOTH are TRUE. These are sometimes called "pipes." |
! | NOT or INVERSE | !(condition X) is true if (condition X) is false. !(condition X) is false if (condition X) is true. |
For example:
language:c
if ((mode == 1) && ((temperature < threshold) || (override == true)))
{
digitalWrite(heaterPin, HIGH);
}
...will turn on a heater if the mode varaible is equal to 1 (heating mode) "AND" the temperature is below the threshold, OR if the override variable is set to true. Notice the order of operations are controlled with the parentheses () in these compound conditional statements. Using these logic operators, you can program your RedBoard to make intelligent decisions and take control of the world around it!
Going Further
The current example has the RedBot backing up and turning if either the right or the left bumpers are hit. What should the RedBot do if both bumpers are pressed at the same time? Change the code so that the RedBot backs up and rotates a full 180 degrees when both left and right bumpers are hit.
Troubleshooting
The whiskers aren't triggering anything!
- Check and be sure that they make good contact with the screws when the whisker bumps into something.
- Make sure that you've got them plugged into the right pins on the mainboard, and that the other ends plug onto OUT and GND on the sensor board.