Making Robots With The Arduino part 4.pdf

(1018 KB) Pobierz
Servo 2011-02.pdf
worldmags
Making Robots
With The
A RDUINO
Part 4 -Getting Feedback With Sensors
By Gordon McComb
Robots need information about the world around them, or they just
stumble about looking stupid. Just like us humans, a robot uses senses
to know when it’s run into something; when it’s light or dark; when it’s
too hot or too cold; when it’s about to fall over; or when it’s found the
way to the cheese at the center of a maze.
the basic senses make do with the most basic of
sensors: mechanical switches for detecting contact
with objects, and photosensitive resistors and
transistors for detecting the presence (or absence) of light.
A robot can perform a remarkable amount of work with
just the sense of touch and the gift of simple sight.
In this month’s installment, you’ll learn about
interfacing switches and photosensors to the Arduino,
along with how to use the information these sensors
provide to interactively command a robot’s motors. These
are the fundamental building blocks of most any
autonomous robot you build. Once you learn how to use
these sensors to do your bidding, you can apply them in
dozens of ways, for all kinds of robotic chores.
Part 1 introduced the ArdBot project, the Arduino, and
basic programming fundamentals of this powerful
controller.
Part 2 detailed the construction of the ArdBot, using
common materials such as plastic or aircraft grade plywood.
Part 3 covered the Arduino in more depth, and
examined the ins and outs of programming R/C servo
motors with the Arduino.
Arduino Robotics:
What We ve Covered So Far
This article builds upon previous installments in this
series, which is all about the construction and use of the
ArdBot (see FIGURE 1 ) — an inexpensive two-wheeled
differentially-steered robot based on the popular Arduino
Uno and compatible microcontrollers. If you’d like to follow
along, be sure to check out the previous three episodes, so
you’re familiar with the plot and characters.
FIGURE 1. THE
ARDBOT ROBOT USES AN
ARDUINO MICROCONTROLLER
AND TWO R/C SERVO MOTORS.
SERVO 02.2011 67
worldmags
S enses require sensors. In the practice of robotics,
527809725.005.png 527809725.006.png
worldmags
www.servomagazine.com/index.php?/magazine/article/february2011_McComb
FIGURE 2. The leaf switch acts as a kind of
cat’s whiskers. It’s connected to a digital
I/O pin using a pull-down resistor.
What’s covered here applies to most any robot that
uses the Arduino microcontroller, and that runs on two
motors and rolls on wheels or tracks. You’re free to adapt
the techniques and programming code to whatever bots
you’re constructing. The ArdBot is an expandable platform,
but it’s also a concept that represents the typical desktop-
size robot.
The subject of sensors is pretty involved. There’s no
way to cover all the interesting things in just one article.
So, next month you’ll learn about other kinds of
inexpensive sensors you can use with your ArdBot (or
other robot).
Getting in Touch
With Your Robot
Sensors — whether in humans or in
robots — are designed to produce a
reaction. What that reaction is depends
on the nature of the sensation. Type and
quantity matter. We interpret the feeling
of a soft summer breeze as a good
sensation. Increase the amount of air
pressure to hurricane force and decrease
the temperature to something below
freezing, and suddenly the same senses produce a highly
negative reaction.
Touch also called TACTILE FEEDBACK — is a primitive
reactive sense. The robot determines its environment by
making physical contact; this contact is registered through a
variety of touch sensors. What happens when contact is
made is entirely determined by the programming you apply
within your robot.
Most often, a collision with an object is a cause for
alarm. So, the reaction of the robot is to stop what it’s
doing, and back away from the condition. In other cases,
contact can mean your robot has found its home base, or
that it’s located an enemy bot and is
about to pound the living batteries out
of it.
The lowly mechanical switch is the
most common — and most simple —
form of tactile (touch) feedback
mechanism. Just about any
momentary, spring-loaded switch will
do. When the robot makes contact,
the switch closes, completing a circuit.
I like to use LEAF (or LEVER ) switches
(see Figure 2 ) because they function a
lot like a cat’s whiskers. These things
are sometimes referred to as a
microswitch — after a popular brand
name — but I’ll call them leaf switches
to avoid confusion. Regardless of make
or model, most are easy to mount, and
come with plastic or metal strips of
different lengths that enhance the
sensitivity of the switch.
You can enlarge the contact area
of the leaf by gluing or soldering
bigger pieces of plastic or metal to it.
For example, you can cut up some stiff
music wire (available at hardware
stores) or a cheap wire clothes hanger,
and bend it to some fancy shape.
Making Reusable Sensor Components
the more you’ll want to build a drawer-
full of reusable parts that easily plug into
your projects. Sensors especially.
With just a bit of wire, some heat
shrink tubing, and a length of snap-off
male header pins you can build modular
sensors that can be shared between
projects. The pins easily plug into a
solderless breadboard. FIGURE A shows a
photoresistor attached to an eight inch
length of wire which is terminated into a
three-prong male header (only two pins
are used; the third is cut off).
First, start by cutting some 22 or 24
gauge insulated stranded conductor wire
to the desired length. Don’t be stingy with
the wire, but don’t make it so long the
extra gets in the way. Give yourself an
additional inch or two so you can twist
the leads together to make a nice pigtail.
Strip about 1/4” insulation off both
ends, and use your soldering pencil to
pre-tin the wire. Do the same for the leads
on the photocell and the header pins.
Exercise care when soldering to the
photocell leads, as excessive heat can
damage the component. After tinning is
complete, carefully tack-solder the wires
to the leads or pins.
I like to use heat shrink tubing to
finish off the soldered ends. The tubing
FIGURE A. Use male header pins to
prepare connectors for easy
interchange with your various
projects. The connectors plug into
a solderless breadboard.
makes for a more professional look, plus it
helps prevent short circuits. When applied
properly, it acts as a strain relief to help
keep the wires from pulling apart from
their joints. Buy a small assorted package
of tubing, and use the smallest diameter
for the best fit.
Header pins have a 0.100” spacing
which is a fairly tight space for all but the
most seasoned solder pros. So, you’ll
probably want to snap off a set of three
or four pins, and remove the center pins
to make extra room for your solder joints.
68 SERVO 02.2011
worldmags
T he more you experiment with robotics,
527809725.007.png
worldmags
worldmags
FIGURE 3. A pair of leaf switches on the
ArdBot. You can attach things to the leaf of each
switch to enlarge its contact area.
Solder the end(s) to the leaf. Or, you can use
thin pieces of wood, plastic, or metal. Just be
sure the weight of the extension doesn’t
accidentally activate the switch. You don’t
want false alarms.
The switch may be directly connected to
a motor or, more commonly, it may be
connected to a microcontroller. A typical
wiring diagram for the switch is shown in
Figure 2 . The 10 k W pull-down resistor is
there to provide a consistent digital LOW (0 volts) output
for the switch when there is no contact. When contact is
made, the switch closes, and the output of the switch goes
HIGH — usually five volts, as shown here.
Using Leaf Switches
as Bumpers
Two standard leaf switches mounted to the front of
your ArdBot let it detect when it’s hit something. With
the switches situated to the sides, your bot can determine
if the object is on the left or on the right, and then steer
around it.
Figure 3 shows a pair of leaf switches mounted like
bumpers to the front of the ArdBot. Switches like these
are available at many online electronics outlets, and are
common as surplus. I bought these at All Electronics
(a SERVO MAGAZINE advertiser) for $1.60 a pop.
I haven’t augmented the switches with a larger contact
area, as I’m more interested in demonstrating the concepts
involved. Use your creativity in enhancing the switches to
provide the level of sense detection you want. For example,
right off you can see that the robot is “blind” to small
objects directly between the switches. You can deal with
this either by enlarging the contact area, or (my choice)
using another form of “sense” to avoid collision in the
first place.
To mount each switch, find two suitable holes in the
base of your robot, or drill new ones. Most leaf switches
have three connections: common, normally open (NO), and
normally closed (NC). Wire the COMMON and NO
connections. If space is tight, break off the NC connection
to make room.
Figure 4 shows the diagram for connecting the two
switches to digital pins D2 and D3 of the Arduino. Figure 5
shows the same circuit, but in breadboard view. Use the
upper half of the ArdBot’s 170 tie point solderless
breadboard. The bottom half is already in use by the servo
wiring for the ArdBot (see Part 2 of this series).
On my prototype, I made connectors for the switches
by soldering the two wires to pins of a breakaway male
header. With these, you break off the number of pins you
FIGURE 4. Schematic view of connecting two bumper switches
to the Arduino microcontroller.
FIGURE 5. Breadboard view of connecting the bumper
switches. Note that the bottom half of the solderless
breadboard is already in use, wired for the two servo motors.
(See Part 2 of this series for details.)
SERVO 02.2011 69
worldmags
527809725.008.png 527809725.001.png
worldmags
/*
ArdBot bumper switch demo
Requires Arduino IDE version 0017
or later (0019 or later preferred)
want to use. I cut one connector to three pins wide,
removing the middle pin; I soldered the wires from the
switch to the outer two pins. For the other connector, I cut
it to four pins wide, removing the middle two pins. You can
see in Figure 5 how the two connectors plug into the
breadboard.
Important! Make sure all the wires and other
components are firmly seated into their breadboard tie-
point sockets. Loose connections are the second most
common cause of problems when using a solderless
breadboard — the most common is plugging the wires into
the wrong tie points!
Listing 1 shows the demo program bumper.pde . The
ArdBot sets off going forward until one of its front bumper
switches makes contact with an object. The moment the
switch closes, the robot quickly reverses direction, then
turns in the opposite direction of the obstacle. Time delays
are specified in milliseconds. The robot backs up for 500
milliseconds (half a second). It then turns — actually spins —
to the right or left for 1,500 milliseconds (1.5 seconds).
You can experiment with other delay settings,
depending on how fast your robot travels. With faster servo
motors, you can use a shorter delay. The idea is to spin the
robot about one-quarter to one-half turn, so it moves away
from the obstacle.
Note that “left” and “right” (and “front” and “back”)
are somewhat objective in a robot like the ArdBot. Either
end can be the front, so left and right is relative. In my
prototype, I put the two leaf switches on the end that had
more mounting space available. That end became the
“front.” The coding in bumper.pde reflects this design
choice. If your robot seems to behave opposite to what it
should, swap the values in the motion routines (forward,
reverse, etc.). See Part 3 of this series for more details on
what the servo commands do, and how they work.
*/
#include <Servo.h>
const int ledPin = 13; // Built-in LED
const int bumpLeft = 2; // Left bumper pin 2
const int bumpRight = 3; // Left bumper pin 3
int pbLeft = 0; // Var for left bump
int pbRight = 0; // Var for left bump
Servo servoLeft; // Define left servo
Servo servoRight; // Define right servo
void setup() {
servoLeft.attach(10); // Left servo pin D10
servoRight.attach(9); // Right servo pin D9
// Set pin modes
pinMode(bumpLeft, INPUT);
pinMode(bumpRight, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
forward(); // Start forward
// Test bumper switches
pbLeft = digitalRead(bumpLeft);
pbRight = digitalRead(bumpRight);
// Show LED indicator
showLED();
// If left bumper hit
if (pbLeft == HIGH) {
reverse();
delay(500);
turnRight();
delay(1500);
}
// If right bumper hit
if (pbRight == HIGH) {
reverse();
delay(500);
turnLeft();
delay(1500);
}
}
// Motion routines
void forward() {
servoLeft.write(180);
servoRight.write(0);
}
void reverse() {
servoLeft.write(0);
servoRight.write(180);
Understanding the
bumper.pde Sketch
As with all Arduino sketches, bumper.pde has three
principle parts: declaration, setup() function, and loop()
function.
The declaration area at the top of the sketch sets up
the variables used throughout the program. It also prepares
two objects of the servo class. As you read in Part 3 of
Making Robots with the Arduino , the servo class is
provided as a library that comes with the Arduino
programming tools. You use it to control one or more R/C
servos. The declaration also defines the two leaf switches as
connected to digital pins D2 and D3, and that we’ll be
using the Arduino’s built-in LED (internally connected to pin
D13) as a visual indicator.
In the setup() function, the servos are defined as
connected to digital pins D9 and D10. The pins used for the
LED and two switches are set as outputs and input,
respectively.
The main body of the sketch is the loop() function
}
void turnRight() {
servoLeft.write(180);
servoRight.write(180);
}
void turnLeft() {
servoLeft.write(0);
servoRight.write(0);
}
void stopRobot() {
servoLeft.write(90);
servoRight.write(90);
Listing 1 -
bumper.pde.
}
void showLED() {
// Show LED if a bumper is hit
if (pbRight == HIGH || pbLeft == HIGH) {
// Turn LED on
digitalWrite(ledPin, HIGH);
}
else {
// Turn LED off
digitalWrite(ledPin, LOW);
}
}
70 SERVO 02.2011
worldmags
527809725.002.png
worldmags
which repeats indefinitely. It begins by activating the two
servos to move the robot forward. The sketch then uses the
digitalRead statement to store the current state of the two
switches. The instantaneous value of the switches is kept in
a pair of variables ( pbLeft and pbRight — the pb for
pushbutton). These variables are used elsewhere.
Of main interest in the loop() function are the two if
statements. Here’s the one that tests the left leaf switch:
*/
#include <Servo.h>
const int ledPin = 13;
const int bumpLeft = 2;
const int bumpRight = 3;
int pbLeft = 0;
int pbRight = 0;
Servo servoLeft;
Servo servoRight;
void setup() {
servoLeft.attach(10);
servoRight.attach(9);
// Set pin modes
pinMode(bumpLeft, INPUT);
pinMode(bumpRight, INPUT);
pinMode(ledPin, OUTPUT);
// Set up interrupts
attachInterrupt(0, hitLeft, RISING);
attachInterrupt(1, hitRight, RISING);
if (pbLeft == HIGH)
reverse();
delay(500);
turnRight();
delay(1500);
}
}
void loop() {
forward(); // Start forward
showLED(); // Show LED indicator
// If left bumper hit
if (pbLeft == HIGH) {
reverse();
delay(500);
turnRight();
delay(1500);
pbLeft = LOW;
pbLeft == HIGH checks to see if the contents of the
pbLeft variable (set earlier based on the state of the left
leaf switch) is HIGH. If it is, then the left switch is closed,
and the robot has made contact with something. If it’s
LOW, then the switch is open, and the robot continues on
its way.
B umper.pde also includes a number of user-defined
functions. Most — like forward() and reverse() — relate to
driving the servo motors. Another function, showLED() ,
toggles the LED on pin D13 of the Arduino on or off,
depending on whether a switch is closed. Use this as a
visual indicator that the programming code is working as it
should.
}
// If right bumper hit
if (pbRight == HIGH) {
reverse();
delay(500);
turnLeft();
delay(1500);
pbRight = LOW;
}
}
// Motion routines
void forward() {
servoLeft.write(180);
servoRight.write(0);
Switch Triggers Using
Polling or Interrupts
The programming in bumper.pde relies on what’s
known as polling : The sketch repeatedly checks the status
of the two switches. If a switch is closed, its value goes
from LOW to HIGH; when HIGH, the robot is commanded
to steer to a new heading. The switches are checked —
polled — many times each second.
Polling is an acceptable method when the sketch is
relatively simple, and the demands on the Arduino are light.
For code that is more processing intensive, there is a
remote chance the controller will miss when a leaf switch
has closed. It’ll be busy doing something else in between
polls and be unaware anything has happened.
In truth, you can have a fairly involved sketch and it will
still detect 99 percent of all switch closures. The reason:
The switch will likely be closed for what are very long
periods of time to a microcontroller. For a microcontroller
running at 16 MHz, even a brief 100 millisecond (one-tenth
second) contact is like a lifetime, and so in all likelihood the
switch closure will be registered.
Still, if you absolutely must ensure that even the most
fleeting contact is registered, you might want to consider
using hardware interrupts rather than polling. With an
interrupt, special code is run if — and only when — a
specific external event occurs. Because the main program
}
void reverse() {
servoLeft.write(0);
servoRight.write(180);
}
void turnRight() {
servoLeft.write(180);
servoRight.write(180);
}
void turnLeft() {
servoLeft.write(0);
servoRight.write(0);
}
void stopRobot() {
servoLeft.write(90);
servoRight.write(90);
}
void showLED() {
// Show LED if a bumper is hit
if (pbRight == HIGH || pbLeft == HIGH) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
}
// Interrupt handlers
void hitLeft() {
pbLeft = HIGH;
}
void hitRight() {
pbRight = HIGH;
Listing 2 -
interrupt.pde.
}
SERVO 02.2011 71
worldmags
/*
ArdBot interrupt bumper demo
Requires Arduino IDE version 0017
or later (0019 or later preferred)
527809725.003.png 527809725.004.png
Zgłoś jeśli naruszono regulamin