The Arduino Robot. Robotics For Everyone
The Arduino Robot. Robotics For Everyone
- -
11111111
Table of Contents
iii
Next Steps ................................. ....... .............. 43
Table of Contents v
Adding Scanning............................................... 178
This book takes you through the steps needed to build a robot capable of
autonomous movement and remote control. Build instructions are provided
for 2WD (two wheel drive) and 4WD (four wheel drive) platforms. The platforms
shown in Figure 1-1 and Figure 1-2 will make the construction a snap, but you
can build your own robot chassis if you prefer. The connection and use of the
control electronics and sensors are fully explained and the source code is in
cluded in the book and available for download online (see "How to Contact
Us" (page xv) for more information on downloading the sample code).
1
Introduction to Robot Building
2
Introduction to Robot Building
Figure 1-3. Robot moves around but remains within the white area
Chapter 1 3
Why Build a Robot?
Figure 1-5. Two wheeled and four wheeled robots with distance scanners
4
How Robots Move
There are many different kinds of robots, some can crawl, or walk, or slither.
The robots described in this book are the easiest and most popular; they use
two or four wheels driven by motors.
Chapter 1 5
Tools
... _. ..._ .
Tools
These are the tools you need to assemble the robot chassis.
Phillips Screwdriver
A small Phillips screwdriver from your local hardware store.
Small long-nose or needle-nose pliers
For example, Radio Shack 4.5-inch mini long-nose pliers, part number
6 4-062 (see Figure 1- 10) or Xcelite 4-inch mini long-nose pliers, model L 4 G.
Small wire cutters
For example, Radio Shack 5" cutters, part number 6 4-06 4 (Figure 1 - 1 1) or
Jameco 16 1 411
Soldering iron
For example, Radio Shack 640-2070 (Figure 1- 12 ) or Jameco 2094 143 are
low cost irons suitable for beginners. But if you are serious about elec
tronics, a good temperature controlled iron is worth the investment, such
as Radio Shack 55027897 or Jameco 1 46595.
Solder 22 AWG (.6mm) or thinner
For example, Radio Shack 6 40-0013 or Jameco 73605 .
6
Tools
Chapter 1 7
Building the Electronics 2
This chapter guides you through the electronic systems that will control your
robot. Both the two wheeled and four wheeled platforms use the same mod
ules, a pre-built Arduino board (Arduino Uno or L eonardo), and a motor con
troller kit. The motor controller featured in this book is the AFMotor shield from
Adafruit Industries. Although other motor controllers can be used (see Ap
pendix B) the AF Motor shield provides convenient connections for the signals
and power to all the sensors and devices covered in this book. It is also capable
of driving four motors, which is required for the four wheel drive chassis.
Although the attachment of the boards to the robot differs somewhat de
pending on the chassis, the build ing of the AFMotor circuit board kit is the
same for both. If you don't have much experience with soldering, you should
practice soldering on some wires before tackling the circuit board (you can
find soldering tutorials here: http://www.la dya da.n et/learn/so/derin g/
thm.htmn.
Hardware Required
9
Construction Techniques
Construction Techniques
Th i s secti on provi des a n overvi ew of the mot or c ontroll er shi eld c on structi on.
Soldering
S ol dering i s ea sy to do if you un dersta n d the ba si c pri n c i pl es a nd ha ve a l ittl e
pra c ti c e. The t ri c k for making a good solder joi nt i s to provi de the rig h t amount
of heat to the pa rts to be soldered a n d use the rig ht sol der. 22 AWG solder
(0.6mm or .025 inc h) or thi nner i s a g o od c hoi c e for solderi ng pri nted c i rc uit
boards. A 25-watt to 40-watt i ron, i dea l l y with tem perature control, is best. The
com p on ent s to be joined shoul d be m ec ha ni c a ll y secure so they don't m ove
whi le the sol der i s c ooli ng-wi res shoul d be c rim ped a round term i nal s ( see
Fig ure 4- 1 1 a n d Fig ure 4- 1 2). To make the joint, th e tip of th e i ron shoul d ha ve
g ood c onta c t with all the c omp onen ts to be soldered. Feed a sma ll a m oun t of
solder where th e iron i s touc hing t he pa rt s t o be j oi ned. When t he sol der flow s
a round the j oint, rem ove the solder first a n d then the i ron. The con n ection
sho uld be m ec ha ni c a l l y sec ure and the joi nt shi n y.
10
Construction Tech niques
The parts to the right of (as well as below) the board are packed with
the shield, but the three 6-pin headers on the left are not supplied with
the standard shield. These headers are used to connect the sensors.
These headers are included with the Maker Shed companion kits that
go along with this book. You can also purchase female headers from
Adafruit and other suppliers.
S older the sma l l e st componen ts fi rst (F i gure 2-2). The three sma l l ca pacitors
and two resi stors a re n ot polarized so you ca n i n sert th em either way a r oun d.
Chapter 2 11
Construction Techniques
The resistor network (the long thin component with ten pins) is polarized
the end with the white dot goes to the left of the PCB (nearest to C l ) as shown
in Figure 2-3.
Figure 2-3. Solder the resistor network - the marker (circled) indicates correct orientation
The large capacitors, I Cs, and L ED are all polarized. The color of the components
shown in the step-by-step assembly pictures on the Adafruit site (you can find
the link at the beginning of these build notes) may not match the components
or layout for the parts you received (particularly the capacitors) so carefully
12
Construction Techniques
check that you have placed the correct value component in the correct orien
tation. Figure 2-4 shows the layout for version 1 .2 of the shield PCB. The kit
includes two IC sockets for the L 293D chips. As mentioned in the assembly
instructions on the Adafruit site, these are optional but if you like to play safe
and want to use the sockets, solder them so the indent indicating pin 1 matches
the outline printed on the PCB.
Figure 2- 5 shows the board with all of the standard shield components (push
button, headers, screw terminals) soldered. The final assembly step is to solder
the three 6-pin female headers near the analog input pins. These headers are
not included in the shield package or mentioned in Adafruit's step-by-step
build instructions, but are included with the Maker Shed kits.
Chapter 2 13
Construction Techniques
Figure 2-6 s h ows all compon ents i ncl u di ng th e s ensor h eaders sol dered. Tri m
th e component pi ns ( except th e h eader pins th at c onnect th e s h i el d to th e
Ardui no) on th e u ndersi de of th e board so th ey are cl ear of th e Ardu i n o when
th e shi eld is p lugg ed onto th e board. Locate one of th e jumpers suppli ed with
th e s h i el d and pl ug thi s onto th e pi ns m arked power jumper-thi s conn ects
th e motor p ower i nput and th e Ardui no VI N (power i nput) tog ether so both
are fed from th e batteri es th at you will be wiring after you h ave bui l t th e robot
chassis.
14
Construction Techniques
Figure 2-7 shows where all of the sensors and other external devices will be
connected. The three pin female headers are not needed for some of the
projects but you will find it convenient to solder these to the shield at this time.
Figure 2-8 shows two styles of connections. On the left, you'll find the
stripboard-based wiring scheme as described in "Making a L ine Sensor
Mount" (page 17). As you'll see in later chapters, you can experiment with a
variety of mounting methods, including the stripboard-based one. The right
side of Figure 2-8 shows the wiring for separately connected sensors. As you
read through the later chapters and experiment with various mounting tech
niques, you'll use one or the other wiring schemes. Because you'll be using
sockets and ribbon connectors to hook up the sensors, you won't be locked
into any particular connection scheme; you can mix and match.
Chapter 2 15
Construction Techniques
The leff and right designation in the diagram refers to leff and right
from the robot's perspective, and the later chapters will explain where
to connect these.
To
Servo
2 servos
2 s t ep p e r
4 de m o t o r
v1.2
motor control 0
s h i e l d f o r a r du i n o
IR
Module
AS
To
Battery Left Right Center
Reflectance Sensors
16
Construction Techniques
IR IR
Module Module
A5 A5
Figure 2-8. Connec tion detail - stripboard wiring is shown on the left, individual jumpers shown
on the right
Chapter 2 17
Construction Techniques
•
1111
• Gnd +5v
Figure 2-10. Stripboard layout for moun ting QTR-lA reflectance sensors for line following
To ensure that the mounting bolts don't short the tracks, you can either cut
the tracks as shown in Figure 2- 10 (you will be cutting along the third column
from the left, or the "C" column) or use insulated washers between the bolts
heads and the tracks. Figure2- 11 shows how the header sockets are connected,
and Figure 2-12 shows the completed stripboard, with the ribbon cable con
nected. A ten inch length of cable is more than ample. Figure 2-1 3 shows the
other end of the ribbon connected to shield pins.
18
Construction Tech niques
Chapter 2 19
Construction Techniques
The m ethod of m ou nti ng the strip b oa rd depen ds on the rob ot cha ssi s; see
Chap ter 3, Building the Two-Wheeled Mobile Platform or C hap ter 4, Building the
Four-Wheeled Mobile Platform. The three h ol es shown will sui t ei th er cha ssi s
but you may p refer to wa i t until y ou ha ve bui l t the cha ssi s a nd only dri l l the
hol es you need.
Next Steps
The nex t sta g e i n bui l di ng the robot is to a ssem ble the cha ssi s. C hap ter 3 cover s
the two-wheeled robot a nd C hapter 4 i s for the four-wheeled versi on.
20
Building the Two-Wheeled
Mobile Platform
This chapter provi des ad vice on the constructi on of a Two Wheel Dri ve (2WD)
chassis with front caster, as shown in Fi g ure 3- 1 . C onstructi on is st raig htfor
ward; y ou can fol l ow the detai led steps or i mprovise if you want to cust omize
your robot. The chapter als o shows how you attach and c onnect sensors used
i n the projects c overed i n later chapters.
If you prefer to build a two wheeled robot of your own des ign, you should read
the sect ions on attaching control electronics and sens ors; this will prepare you to
use the code for the projects in the chapters to come. Inform ati on in this chapter
my also provi de s ome ideas to help with the des ig n of your own robot.
21
Hardware Required
Hardware Required
22
Mechanical Assembly
Mechanical Assembly
Lay Out the Chassis Parts
Figure 3-2 shows a ll of the parts contai ned in the 2WD chassi s packa g e. The
three bla ck bra ckets to the left of t he figure are not needed fo r a ny of the
proj ects i n t hi s book.
Fig ure 3-3 shows the contents of the bag contai ni ng t he mounting hardwa re.
Locate t he two bolt s with t he flat hea ds a nd put t hem a si de for mounting the
battery case. Also i dentify t he two thi cker (M4) bolts that will be used to attach
the caster. The rema i ning short bolt s in t his pack a re i dent i ca l.
Chapter 3 23
Mechanical Assembly
0
0
Motor Assembly
Use two long bolts with lock washers and nuts, as shown in Figure 3- 5, to attach
each motor to the chassis lower plate. Tighten the nuts snugly but take care
not to stress the plastic motor housing.
Lock washers are used to prevent a nut from accidentally coming lose
due to vibration. This is particularly important for attaching the motor
and switch. These washers have a split ring or serrations that apply
extra friction when tightened.
If you find that things still come lose, don't overtighten the nuts; an
effective solution is retighten the nut and apply a dab of nail polish to
the point where the threads emerge from the nut.
Figure 3- 4 shows the motors in place with the nut seen on the upper right
ready to be tightened.
24
Mechanical Assembly
Chapter 3 25
Mechanical Assembly
Chassis
Lower Plate
-
--
....._..◄
-.-.....◄
M 2 . 5x25mm
Phillips Bolts
Lock M2 .5
Washer N ut
Washer
Figure 3-5. Motor Assembly
26
Mechanical Assembly
Caster
M4 N ut
Chapter 3 27
Mechanical Assembly
Attac h the sensor bracket to the undersi de of the lower c ha ssi s plate, as seen
i n Fi g u re 3-8 a nd Fi gure 3-9.
This robot is sometime s built with the se nsor plate mounted at the
opposite e nd of the cha ssis (furthest from the ca ster). You ca n bu ild
yours however you like, but the orie ntation s hown here enable s the
servo moun ted distance scanner to be attached in the front ofthe rob ot.
Also, the se nsor bracket in this location maximizes the dista nce be
tween the wheels a nd the line sensors a nd this improve s line following
sensitivity.
Figure 3-9 shows the un dersi de of the cha ssi s after mou nti ng t he sen sor brack
et. Note that the sensor bracket i s attac hed to t he bottom of the c ha ssi s plate.
Figure 3-8. Sensor bracket viewed with the robot right Figure 3-9. Sensor bracket viewed with the robot up-
side up side down
The battery pack is bolted to the bottom ba se plate with two cou ntersu nk (flat
headed) Phil li ps bolt s a s shown in Figure 3- 1 0 a nd Figu re 3-1 1 . You may wa nt
to delay thi s step unti l after t he battery lea ds ha ve been soldered to make it
ea si er to po sition a l l the wires.
28
Mechanical Assembly
Chapter 3 29
Mechanical Assembly
The DC power jack is bolted to the top plate using the large (MB) lock washer
and nut. The switch is mounted using two (M6 ) nuts and a lock washer. Put
one nut on the switch leaving around 3/16 " of thread above the nut. Then place
the lock washer on the thread and push this through the opening in the rear
plate and secure with the second M6 nut.
Orient the switch so the toggle moves towards the jack, as shown in Figure 3- 1 3
and Figure 3-1 4 (Figure 3- 1 5 shows the view from beneath).
Top
Plate
�
0 0
0 0
0
0 0
M6 N ut
Lock �
Washer
M6 Nut
' Lock
Power Washer
Switch DC
Charger
Jack
Figure 3-13. Switch and Jack Assembly
30
Mechanical Assembly
Figure 3-14. Top panel showing location of switch and Figure 3-15. Top panel underside showing orientation
DC jack of switch and jack
Power
Switch
Chapter 3 31
Mechanical Assembly
You ca n b ui l d a sim ple trickle charg er i nto the robot if you wi ll be usi ng re
char g eab le N i M H b atteri es. Th e c harg er ca n be built usi ng the circui t shown
in F i g ure 3- 1 S a nd Fi g ure3- 1 9. S ee"TrickleCh argi ng" (pa g e 229) for i nform ation
abou t usi ng the c harg er.
Charging
Jack
9 -1 2V DC
Power
Switch
32
Mechanical Assembly
The easiest way to mount the Arduino board is with a strip of Velcro. A 2.5" x
1 .5" strip is supplied with the Rovera 2W (Arduino- Controlled 2 Wheel Robotics
Platform) kit. To prevent the Arduino pins from accidentally shorting to the
chassis, apply insulating tape to the underside of the Arduino board. Gaffer
tape works well but you can use (non- conductive) duct tape or heavy duty
electrical tape. Attach the 'hairy' side of the Velcro to the taped Arduino board,
the hook side is fastened as shown in Figure 3-20.
Chapter 3 33
Mechanical Assembly
Figure 3-20. Velcro pad in position on the 2WD chassis. Inset shows Velcro attached to the
Arduino board.
Figure 3-21 shows the mounted boards. The Velcro will hold the boards in
position when the robot is moving about, but use one hand to steady the
Arduino when you unplug the shield and take care not to use too much down
ward pressure that could push the Arduino pins through the tape when plug
ging in the shield.
34
Mechanical Assembly
If you prefer a more rigid mo unt, you can use two of the 1 0mm brass standoffs
suppl ied with the chassi s and two M3 bolts and nut s ( seen on the rig ht side of
the board as shown in Figure 3-22). U se a 1 0m m spacer and M2.5 in the hole
near the re set switch. (The hol e near the DC j ack at the lower l eft is not used.)
Fig ure 3-23 shows the location of the mounting poi nt s viewed from the un
dersi de of t he panel.
Chapter 3 35
Mechanical Assembly
Figure 3-22. Mounting the A rduino board as viewed Figure 3-23. Underside showing location of the three
from the top of the chassis Arduino mounting points
Atta ch the top plate wi th four M3 bolts a s s h own in Fig ure 3-24.
M3x6 Truss
(Flange} Bolt
36
Mechanical Assembly
.....,
To
Chapter 3 37
Mounting the I R sensors
38
Mounting the I R sensors
for li ne followi ng. The stripboard mount descri bed in "M aki ng a Li ne Sensor
Mount" ( pag e 1 7) si mplifi es the attachm ent and wiring of the sensors for line
detection and thi s can also be u sed for edg e detection, bu t bear in mi nd th at
the robot will perform the edg e detection task best with the sensors further
apart. If the sensors are clo se tog ether, the ro bot can have diffi culty determin
i ng the best angle to turn when an edge i s encountered.
Chapter 3 39
Mounting the I R sensors
Figure 3-29. Front view showing location of the Edge Figure 3-30. Edge sensors wired and ready to run
Detection Sensors
40
Mounting the IR sensors
--+
--
T.35 - .5
inch
.35 - .5
_ _ J_ inch
If you use the stripboard mount for line sensors covered in Chapter 2, Building
the Electronics, the stripboard can be mounted above or below the sensor
bracket, enabling you to experiment with sensor distance to the ground-but
use insulated washers to ensure that the tracks with sensor connections are
not shorted to the bracket. Figure 3-32 and Figure 3-33 show how the strip
board can be mounted.
Chapter 3 41
Mounting the I R sensors
42
Next Steps
Figure 3-33. Reflectance Sensor location for line following. alternate view
See Figure 3-2 7 for information on connecting the stripboard wires to the mo
tor shield.
Next Steps
Chapter S, Tutoria l: Getting Sta rted with Arduino explains how to set up and use
the development environment that will be used to upload code to the robot.
If you are already an Arduino expert, you can skip to Chapter 6 , Testing the
Rob ot's Basic Fu nctions, but first, see "I nstalling Third-Party Libraries" (page 83)
for advice on the libraries used with the code for this book.
If you have the libraries installed and want run a simple test to verify that the
motors are working correctly, you can run the sketch shown in Example 3- 1 .
Chapter 3 43
Next Steps
int pwM ;
void setup ( )
{
Serial . begin ( 9600 ) ;
blinkNuMbe r ( S ) ; II open port while flashing . Needed for Leon a rdo only
Thi s sketch runs the motors i n o pposite d i rections to cause the robot to rota te
clockwise for 5 second s, then reverses direc tion to ro ta te co un ter-clockwi se.
Th i s will repea t until the power is swi tched off.
44
Building the Four-Wheeled
Mobile Platform ..,.
This chapter provides advice on the construction of the 4WD (4 Wheel Drive)
chassis shown in Figure 4-1 . Construction is straightforward-you can follow
the detailed steps or improvise if you want to customize your robot. The chap
ter also shows how you attach and connect sensors used in the projects cov
ered in later chapters.
If you prefer to build a four wheeled robot of your own design, you should read
the sections on attaching control electronics and sensors if you want to use
the code for the projects in the chapters to come. Information in this chapter
my also provide some ideas to help with the design of your own robot.
45
Ha rdwa re Req u i red
You will need a Phillips screwdriver, long- nose pliers, wire cutters, wire strip
pers, a soldering iron, and solder. If you don't have these on hand, you can find
more information in Chapter 1 , Intro ductio n to Robot Building.
Hardware Required
• Tools listed in "Tools" (page 6 )
• The assembled electronics (see Chapter 2 , Building the Electronics
• 4WD Mobile Platform (four wheeled robot kit made by DFRobot)
• Four 0.1 uF ceramic capacitors
• Two lengths of 3 conductor ribbon cable, two 3 way 0.1" headers for edge
sensors
• Optional: charging circuit resistors and diode, see detailed parts list
46
Mechanical Assembly
Mechanical Assembly
Mechani ca l a ssembly of the 4WD cha ssi s i s stra i g h tforwa rd a nd the only tools
needed a re a Philli p s screwdri ver a nd pliers. Followi ng the steps i n order will
e nsu re that you u se the correct hardwa re in each a ssembly. You w i ll nee d a
solderi ng i ron, wire cutte rs, a nd wire strippe rs to wire u p the m otor a nd power
lead s.
Chapter 4 47
Mechanical Assembly
..
•• • •. . • • • •
48
Mechanical Assembly
0
oo
Motor Assembly
Use four long bolts to attach two motors to each of the s i de plates. The motor
shaft goes through the la rge hole a n d there i s a small locati ng stud on the
motor that fits into the sma ller hole. The lock washer (the one with a ra ised
e dge) goes between the n ut and flat washer. Ensure the m otor is flat agai nst
the plate and ti ghten the n u ts firm ly but take ca re not to use too much force
or you wi ll stress the plastic motor hous i n g. Figure 4-4 a n d Fig ure 4-5 shows
the assembly.
Chapter 4 49
Mechanical Assembly
,,..---
M2 . 5x25mm
Philips Bolts
,
,
,, ,,
.,.'ff,' ,/
@· ,/
M2.5 Washe
Lock Washer
M2.5 Nut
Figure 4-4. Mo tor assembly
M3
Battery
Countersu nk
� Holder
Bolt
f
Chapter 4 51
Mechanical Assembly
The DC power jack i s bolted to the rear pl ate u sing the larg e (MB) lock washer
an d n ut as shown in Figu re 4-8. The switch i s m ounted using two nut s and a
l ock washer (the locatin g washer i s n ot u sed). Put on e n u t on the swi tch, l eaving
abou t enoug h thread for the nut to be att ached to the other si de. Pl ace the
l ock washer on the thread an d pu sh thi s through the open i ng i n the rear plate
an d secure with the secon d M6 n u t. Orient the switch so the toggle m oves
from si de to si de, as shown in the figure. Fig ure 4-9 an d Fig u re 4- 1 0 show two
views of the assembly.
52
Mechanical Assembly
M6 Nut � M8 N ut
�M8 Lock
rWasher
,----l"(
ear Plate
/
M6 Lock
'
�
Washer �
/
'
M6 N ut
Power
Switch
l_ DC Power
Jack
Figure 4-8. Switch and power jack assembly
Figure 4-9. Rear panel switch and power jack assem· Figure 4-10. The other s ide of the panel showing the
bly viewed from the front switch orientation and power jack
Chapter 4 53
Mechanical Assembly
Figure 4-12. Crimp the w ires Figure 4-13. Solder the motor terminals
54
Mechanical Assembly
Power
Switch
Chapter 4 55
Mechanical Assembly
Charging
Jack
9 -1 2V DC
Power
Switch
Figure 4-16. Wiring for trickle charging with Arduino voltage monitoring
56
Mechanical Assembly
Figure 4-17. Wiring for trickle charging with Arduino voltage monitoring
Side Plate j
Rear Plate
Attach th e bot tom p late u sing fou r M3x6 bolts (Fig u re 4- 1 9).
Chapter 4 57
Mechanical Assembly
Bottom Plat
M3x6 Truss
(Flange) Bolt
i
58
Mechanical Assembly
The Velcro will hold the boards in position when the robot is moving about,
but use one hand to steady the Arduino when you unplug the shield and take
care not to use too much downward pressure that could push the Arduino pins
through the tape when plugging in the shield.
Chapter 4 59
Mechanical Assembly
If you prefer a more rigid mount, you can use three 3/8" or 1/4 inch (5mm)
spacers with three 1/2 inch 2-56 bolts and nuts. Figure 4-22 and Figure 4-23
show the location of the mounting hardware.
• • •
•
•
ta II
•
I :,,
:1
,
•
•
• •
Figure 4-22. A rduino board mounted using three Figure 4-23. Underside view showing mounting nuts
spacers
Figure 4-24 shows the motor wires and battery wires inserted through the
cutouts in the top plate ready for the connections shown in Figure 4-25 .
60
Mechanical Assembly
Figure 4-24. Wires ready to connect to shield Figure 4-25. Wires connected
Fi g ure 4-26 sh ows h ow the m otor a nd battery wires attach to the c onnectors
on the motor sh ield.
CCXC
- + s
AAef qnd 1 3 1 2 1 1 1 0 9 8 6 5 4 3 2 l 0
□ □ □ 0• 0M l 502 05 1 0• 0• 0M3 0M4 0e 0M2 □ □ □
� .�----
.. - - --- - - - - �
7
- - - - - - - ..
O Used pins -+
0
·�
2 servos
2 s t epper
4 de motor
0 Left
v1.2 Front
Motor
Left
Rear
Motor
Right
Rear
Motor
------
• • • • ■ • +5
al
Gnd
0
shield f o r arduino ■ ■ ■ ■ ■ I
GND
,e� w!� O D O D D 01
J,= � S T 3v 5v Gnd Vin
■
0
I
1
■
2
■
3
■
4
I
5
l.a,,gJ 0 0 0 0 0 0 0 0Analo
000 [n
0
To
Battery
Chapter 4 61
Mechanical Assembly
Attac h th e sen sor plate wit h two M3 bolt s as shown in Fig ure 4-27; the to p
plate i s attach ed usi ng four M3 bolt s as seen i n Fig u re 4-28.
M3x6 Truss
( Flange) Bolt
Top Plate
M3x6 Truss
(Flange) Bal�
62
Mechanical Assembly
The u pper dec k is b olted to four 50m m sta ndoffs that a re attached a s s hown
in Fi g u re 4-29.
M3x6 Truss
(Flange) Bolt -----,
y
' '
'
'
M2x50
Standoff
Chapter 4 63
Mechanical Assembly
-
Figure 4-30. The assembled chassis Figure 4-31. Side vie w
I I
.,
II
64
Mounting the I R sensors
Chapter 4 65
Mounting the I R sensors
66
Mounting the I R sensors
--
--+ T.35 - .5
i nch
.35 - .5
__ J_ inch
Chapter 4 67
Next Steps
Figure 4-37. Reflectance sensor location for line follow Figure 4-38. Reflectance sensor location for line fol
ing, viewed from front lowing, alternate view
Next Steps
Chapter 5, Tutorial: Getting Started with Arduino explains how to set up and use
the development environment that will be used to upload code to the robot.
If you are already an Arduino expert, you can skip to Chapter 6 , Testing the
Robot's Basic Functions, but first, see "Installing Third-Party Libraries" (page 83)
for advice on the libraries used with the codefor this book and the steps needed
to configure the RobotMotor library for the 4W D robot.
If you have the libraries installed and want run a simple test to verify that the
motors are working correctly, you can run the following sketch:
68
Next Steps
int pwl'I ;
void setup ( )
{
Serial . begin ( 9600 ) ;
blinkNul'lbe r ( S ) ; // open po rt while flashing . Needed for Leonardo only
This sketch runs the motors in opp osite directi ons to cause the rob ot to rotate
cl ockwise for 5 s econds, then stops for 5 s econds. This will rep eat u nti l the
p ower is switch ed off.
Chapter 4 69
Next Steps
This test sketch does not use the RobotMotor library-if this test func
tions correctly but the tes t in Chap ter 6, Testing the Robot's Basic Func
tions does not work, the most likely cause is the configuration of the
motor library-make sure you copy the 4wd version of the library code
as described in "Installing Third-Party Libraries" (page 83).
70
s
Tutorial: Getting Started
with Arduino
The Arduino environment has been designed to be easy to use for beginners
who have no software or electronics experience. If you are new to Arduino, this
chapter will help you get started but you will need to consult the Arduino
online help and a good book on Arduino will be a big help (the author's
"Arduino Cookbook" is highly recommended as reference.)
If you're already familiar with Arduino, please feel free to skip the in
troductory materia l in this chapter. Ho wever, you will need to install
the libraries that are included in the do wnload the code available from:
http:!/s hop.oreilly.com!product/0636920028024.do. The sectio n "In
stalling Third-Party Libraries" (page 83 ) ha s details o n installing the re
quired libraries.
Arduino is best known for its hardware, but you also need software to program
that hardware. Both the hardware a nd the software are called "Arduino:' The
combination enables you to create projects that sense and control the physical
world. The software is free, open source, and cross-platform. The boards are
inexpensive to buy or you can build your own (the hardware designs are also
open source). I n addition, there is an active and supportive Arduino commu
nity that is accessible worldwide through the Arduino forums and the wiki
(known as the Arduino Playground). The forums and the wiki offer project
development examples a nd solutions to problems that can provide inspiration
and assistance as you pursue your own projects.
The information in this chapter will get you started by explaining how to set
up the development environment and how to compile and run an example
sketch.
71
Hardware Required
The Blink sketch, which comes with Arduino, is used as an example sketch in
this chapter. If you have already assembled the robot and downloaded the
source code for this book, feel free to use the HelloRobot sketch described in
Chapter 6, Testing the Robot's Basic Functions.
If you don't have the Arduino software and driver installed on your
machine, wait until "Connecting the Arduino Board" (page 78) to plug
the Arduino into your computer.
Hardware Required
• Computer with Arduino 1 .0. 1 or later installed
• L eonardo (or Uno) Arduino board
• Motor Shield (see Chapter 2, Building the Electronics)
• USB cable
Arduino Software
Software programs, called sketches, are created on a computer using the Ar
duino integrated development environment (IDE). The IDE enables you to write
and edit code and convert this code into instructions that Arduino hardware
understands. The I DE also transfers those instructions to the Arduino board (a
process called uploading) .
Arduino Hardware
The Arduino board is where the code you write is executed. The board can only
control and respond to electricity, so specific components are attached to it to
enable it to interact with the real world. These components can be sensors,
which convert some aspect of the physical world to electricity so that the board
can sense it, or actuators, which get electricity from the board and convert it
into something that changes the world. Examples of sensors include switches,
accelerometers, and ultrasound distance sensors. Actuators are things like
lights and L EDs, speakers, motors, and displays.
72
Arduino Hardware
There are a variety of official boards that you can run your Arduino sketches
on and a wide range of Arduino-compatible boards produced by members of
the community.
The most popular boards contain a USB con nector that is used to provide
power and connectivity for uploading your software onto the board. Figure 5-1
shows the board used for the robots in this book, the Arduino Leonardo.
You can get boards that are smaller and boards with more connections. The
L eonardo is used with these robotics projects because it is inexpensive but you
can use other boards such as the Uno if you prefer.
Ifyou want to use an Uno board (or earlier Arduino boards), you may
need to use a s slightly higher voltage (an additional battery) to power
the robot, see Appendix D).
Add- on boards that plug into Arduino to extend hardware resources are called
shields. The robots covered in this book use a shield that controls the direction
and speed of the motors, see Figure 5-2:
Chapter 5 73
Installi ng the Integrated Development Environment (IDE)
Online guides for getting started with Arduino are available at http://ardui
no. cc/en/Guide/Windows for Windows, http://arduino.cc/en/Guide!MacOSX for
Mac OS X, and http://www.arduino.cc/p/ayground!Learning!Linux for Linux.
74
Installing the I ntegrated Development Environment (I DE)
uduino-1.0-rcl Nam,
drivm
examples
hardware
java
lib
tibmits
reftrenct
tools
E, arduino.ext
� cygiconv-2.dll
i!i cygwinl.dll
.)
Installing Arduino on OS X
The Arduino download for the Mac is a disk image (.dmg); double-click the file
when the download is complete. The image will mount (it will appear like a
memory stick on the desktop). Inside the disk image is the Arduino application.
Copy this to somewhere convenient-the Applications folder is a sensible
place. Double- click the application once you have copied it over (it is not a
good idea to run it from the disk image). The splash screen will appear, followed
by the main program window (Figure 5- 4).
Chapter 5 75
Installi ng the Integrated Development Environment (IDE)
Driver Installation
To enable the Arduino development environment to communicate with the
board, the operating system needs to use the appropriate drivers for your
board.
On Windows, use the USB cable to connect your PC and the Arduino board
and wait for the Found New Hardware Wizard to appear. If you are using a
L eonardo or Uno board let the wizard attempt to find and install drivers.
76
Installing the Integrated Development Environment (I DE)
If you are using an earlier board (any board that uses FTDI drivers) with Win
dows Vista or Windows 7 and are online, you can let the wizard search for drivers
and they will install automatically. On Windows XP (or if you don't have internet
access), you should specify the location of the drivers. Use the file selector to
navigate to the FTDI USB Drivers directory, located in the directory where you
unzipped the Arduino files. When this driver has installed, the Found New
Hardware Wizard will appear again, saying a new serial port has been found.
Follow the same process as before.
On the Mac, the latest Arduino boards can be used without additional drivers.
When you first plug the board in a notification will pop up saying a new network
port has been found; you can dismiss this. If you are using earlier boards (boards
that need FTDI drivers), you will need to install driver software. There is a pack
age named FTDIUSBSeria/Driver, with a range of numbers after it, inside the
Arduino installation disk image. Double- click this and the installer will take you
through the process. You will need to know an administrator password to
complete the process.
On L inux, most distributions have the driver already installed, but follow the
L inux link given in "Arduino Hardware" (page 72) for specific information for
your distribution.
Chapter 5 77
Connecting the Arduino Board
i l. ......
00
USB
: Coo,,.c!or :
.. ................
•
LEONARDO
□
ARDUINO
i
1 o
a
j ICSP
00
; Programrrir,g i
.........................
i Co, nector ,i
00
If you have a factory fresh board, an o ran g e LED (lab eled "Pi n 1 3 LED" i n
Fi g u re 5-5) s hould flash on and off when the board i s powered u p (boards com e
from the factory preloaded w i th software to flas h the L E D as a sim ple c heck
that the board is worki ng).
If the power LED does not illuminate when the board is connected to
your computer, the board is probably not receiving power.
Using the I DE
Use the Arduino IDE to create, o pen, an d mo dify s ketches that defi ne what the
board will do. You can use bu ttons alo n g the to p of the I D E to perform th ese
actions (shown in Fi gure 5-6), or you can use the menus o r keyboard shortcu ts
(som e are shown i n Fi g ure 5-7).
78
Using the IDE
New sketch
Compile
Serial monitor
New tab
Script editor
Text console
(status and
error messages)
The Sketch Editor area is where you view and edit code for a sketch. It supports
common text editing keys such as Ctrl-F (�- F on a Mac) for find, Ctrl- Z (�-Z on
a Mac) for undo, Ctrl-C (�-C on a Mac) to copy highlighted text, and Ctrl-V (�
V on a Mac) to paste highlighted text.
Figure 5- 7 shows how to load the Blink sketch (the sketch that comes preloaded
on a new Arduino board).
After you've started the ID E, go to the File ➔ Examples menu and select 1 .Ba
sics➔ Blink, as shown in Figure 5-7 . The code for blinking the built-in L ED will
be displayed in the Sketch Editor window.
Chapter 5 79
Usi ng the IDE
Close XW
Save XS
Save As... ◊XS
Upload XU
Upload U sing Prog rammer ◊XU 6.Sensors
7.Display
a.Strings
ArduinolSP
EEPROM
Ethernet
Firmata
LiquidCrystal
Mouse
SD
Servo
SoftwareSerial
SPI
Stepper
Wire
Before the code can be sent to the board, it needs to be converted into in
structions that can be read and executed by the Arduino controller chip; this
is called compilin g. To do this, click the compile button (the top-left button
with a tick inside), or select Sketch➔Verify/Compile (Ctrl- R, �- R on a Mac).
You should see a message that reads "Compiling sketch ..:' and a progress bar
in the message area below the text editing window. After a second or two, a
message that reads "Done Compiling" will appear. The black console area will
contain the following additional message:
The exact message may differ depending on your board and Arduino version;
it is telling you the size of the sketch and the maximum size that your board
can accept.
The final message telling you the size of the sketch indicates how much pro
gram space is needed to store the controller instructions on the board. If the
size of the compiled sketch is greater than the available memory on the board,
the following error message is displayed:
80
Uploading and Running the Blink Sketch
If this happens, you need to make your sketch smaller to be able to put it on
the board, or get a board with higher capacity. You will not have this problem
with the Blink example sketch.
If there are errors in the code, the compiler will print one or more error mes
sages in the console window. These messages can help identify the error.
As you develop and modify a sketch, you should also consider using the
File➔ Save As menu option and using a different name or version number reg
ularly so that as you implement each bit, you can go back to an older version
if you need to.
/dev/tty . usbModeMXXXXXXX
/dev/cu . usbModeMXXXXXXX
Chapter 5 81
Usi ng Tabs
Each board will have different values for XXXXXXX. Select either entry.
Click on the upload button (in Figure 5- 6, it's the second button from the left),
or choose File➔ Upload to 1/0 board (Ctrl- U, :Jt- U on a Mac).
The software will compile the code, as in "Using the IDE" (page 78). After the
software is compiled, it is uploaded to the board. If you look at your board, you
will see the LED stop flashing, and two lights (labeled as Serial LEDs in
Figure 5-5) just below the previously flashing LED should flicker for a couple
of seconds as the code uploads. The original light should then start flashing
again as the code runs.
The ID E will display an error message if the upload is not successful. Problems
are usually due to the wrong board or serial port being selected or the board
not being plugged in. The currently selected board and serial port are dis
played in the status bar at the bottom of the Arduino window
If you have trouble identifying the correct port on Windows, try unplugging
the board and then selecting Tools➔ Serial Port to see which COM port is no
longer on the display list. Another approach is to select the ports, one by one,
until you see the lights on the board flicker to indicate that the code is
uploading.
Using Tabs
Tabs provide a convenient way to organize code when your sketch starts to
grow. It enables you to keep functionally related code together and simplifies
sharing this code across more than one sketch.
The arrow in the upper right of Figure 5-8 points to the button which invokes
a drop- down window of tab related functions. This window displays the names
of the tabs and offers a list of commands:
• New Tab creates a new tab that (you will be prompted to name the tab)
• Renar,e enables you to change the name of the currently selected tab
• Delete deletes the current tab (you are asked if you are sure you want to
do that)
82
Installing Third-Party Libraries
� I ""°"'"° LO.I
Rt Edit 5btth look Help
00 n a a □
� Cl
"" '
1,
S.n&I . n (96001 :
1 1 2000 ) :
®��
aotodleqln{JIOTOR_LtrrJ :
aotorBeq1n flKITM_RIGHTJ : Pf1MOU1 hb Ctrl•Alt•ldt
}
M"I (LED_PIN, OUT1UT) ; " 11 tbl LED pin tot 1111q,u,•
I I
, .. 1..., 1 1
f ( 1ootrocOb1ucle (O!IST_IUCHT_DtilJ •• t I I
cal1bUtd�t.et.ionR4tt{l>IR_RJCiHT, 360 ) ; lU,utt CV (Ot.ltiCIO
Each tab is a separate file and when you copy these files to other sketches you
add the tab to that sketch.
Because there are many functional modules used in this book and these are
shared across most of the sketches, tabs are used extensively. Figure 5- 8 shows
the myRobot sketch, discussed in the next chapter, that uses tabs for infrared
sensor code (irSensors) and for program constants and definitions (robotDe
fines. h).
Chapter 5 83
I nstalli ng Thi rd -Party Libraries
If the l ibraries provide example sketches, you can view these from the ID E
menu; click File➔Examples, and the library's examples will be under the li
brary's name in a section between the general examples and the Arduino dis
tributed libraries example listing.
If the library examples do not appear in the Examples menu or you get a mes
sage saying "Library not found" when you try to use the library, check that the
libraries folder is in the correct place with the name spelled correctly. A l ibrary
folder named <LibraryName> (where <LibraryName> is the name for the li
brary) must contain a file named <LibraryName>.h with the same spelling and
capitalization. Check that additional files needed by the library are in the folder.
84
Testi ng the Robot's Basic
Fu nctions
In this chapter, you will upload a test sketch to the robot that will verify that
your robot is working correctly.
Hardware Required
• The assembled robot chassis.
• Motors connected to shield (see Figure 3-25 for 2WD or Figure 4-26 for
4WD).
• Example code and libraries installed, see "Installing Third- Party L ibraries"
(page 83).
• 5 AA cells inserted into the battery holder (USB does not provide sufficient
power to drive the motors).
• Reflectance sensors mounted and connected (left sensor to analog input
0, right to analog 1 ). You can use the stripboard wiring described in "Mak
ing a Line Sensor Mount" (page 1 7). But to run the edge detecting project
described in Chapter 9 , you need more space between the sensors.
Figure 6-1 shows the assembled two wheel robot; Figure 6-2 shows the as
sembledfour wheel robot. Figure 6-3 shows the sensor and motor connections.
85
Software Prerequis ites
Figure 6-1. Two wheeled robot with reflectance sensors Figure 6-2. Four wheeled robot with re flectance sen
sors
0 0 0 0 0 0 0 0 o o o o' o o o o
□�□ □ 0• 0 0 0l 0e 0• 0r 0 0• 0 □ □ 0
....
,,..,
.,,� y-
·-
-------. �or ,wo
Motors fof 'lWO Ooly
\_ rear mo!Ol"S lor 4WO D
'--__..--<. Right
Software Prerequisites
Although the sketch code used in this chapter is printed in the pages that
follow, you will need some libraries that are included in example code (see
"How to Contact Us" (page xv) for the URL). The sketch folders can be copied
to your Arduino sketchbook folder (if you are not familiar with the Arduino
environment, read through Chapter 5). The download files in the library folder
must be copied to your Arduino libraries folder (see "Installing Third- Party L i
braries" (page 83)).
86
S ketches Used in This Chapter
Install the AFMotor library contained in the download zip file. This library is
modified from the one on the Adafruit site to work with the L eonardo board;
the standard Adafruit library can be used with the Uno board.
Install the RobotMotor library contained in the example code download. This
library comes configured for the two wheeled robot; if you have the four
wheeled robot will need to update the library for this robot as described in the
Note below.
If your rob ot uses four wheel drive, you must configure the RobotMo
tor library code by modifying the RobotM otor.h file to tell the compiler
that the library should b e built for the 4WD chassis. See "Installing
Third-Party Libraries" (p age 83) for details o n ho w to do this.
A third library, named lrRemote, is also included in the download. This library
won't be needed until Chapter 11 , but copying it into your libraries folder now
will save you having to do this later.
I I
I Program 11 11 Reflectance1 RobotMoto1
HelloRobot : constants 1 1 sensors I _. -, Library
1 1 I
Figure 6-4. Hel/oRobot Sketch
Chapter 6 87
Load and R u n hel loRobot.ino
- - - - - - --. ,- - - - - - -
1 I
1 I
I Program 1 1 Reflectance 1
Hello Robot : constants 1 1 sensors 1
L- - - 1 1- - --
I
can st c h a r * locationSt ring [ ] = { " Left " , " Rig h t " , " Center " } ; I I Debug labels
II http : lla rduino . cclenl ReferencelSt ring for More on cha racter string a r rays
II obstacles constants
can st int DBST_NONE = 0; II no obstacle detected
can st int OBST_LEFT_EDGE = 1; II left edge detected
can st int OBST_RIGHT_EDGE = 2 ; II right edge detected
can st int OBST_FRONT_EDGE = 3 ; II edge detect at both left a n d right sensors
88
Load and Run helloRobot.ino
MotorBegin(MDTOR_L EFT) ;
MotorBeg i n ( MOTOR_R IGHT ) ;
Seria l . println( " Wai ting for a sensor to detect blocked reflection" ) ;
void loop( )
/ **********************
code to look for obstacles
********************** /
Chapter 6 89
Load and Run helloRobot.ino
/ *************************************
fu nctions to rotate the robot
********************** *************** /
/ / retu r n the tiMe in Milliseconds to turn the g iven angle at the given s peed
long rotationAngleToTiMe ( int a ngle , int speed )
{
int fullRotationTiMe ; // tiMe to rotate 360 degrees at g iven speed
angle = a b s ( angle) ;
de lay( 1000) ;
blinkNuMbe r ( s peed/10 ) ;
90
Load and Run helloRobot.ino
}
else
Serial . println ( " I nvalid senso r " ) ;
de lay( tiMe ) ;
Moto rStop( MOTOR_LEFT ) ;
MotorStop( MOTOR_R I GHT ) ;
delay( 2000 ) ; / / two second delay between s peeds
/ ****************************
i r reflectance sensor code
**************************** /
con st int i r ReflectTh reshold = 10; / / % level below aMbien t to trigger reflection
con st int i r EdgeTh reshold = 90; / / % level above aMbien t to trigger edge
void irSensorBegin ( )
{
for ( int senso r = 0 ; sensor < NBR_SENSORS ; sensor++)
irSensorCalibrate ( senso r ) ;
Chapter 6 91
Load and Run helloRobot.ino
The sketch tests the ca li bra ti on of the robot's speed of movemen t. The front
sen sors are used to i n i ti a te a motor test-the motors rota te the robot 360
degrees in the di recti on of the sensor tha t wa s trigg ered. If the robot is fun c
ti oni ng correctly, i t wil l execute a compl ete revol u ti on a t seven sp eeds ra ngi ng
from sl owest to fa stest.
To ru n the test, pla ce th e robot on a refl ective whi te surfa ce su ch a s a larg e
sheet of pap er. When the robot's u p and ru nni ng, Arduin o's pin 1 3 L E D wil l
fla sh once.
Another way to test is to put the robot on something that will raise the
wheels off the ground by an inch or so. This will enable the motors to
turn without the robot skittering around.
Thi s sketch di splays debugging informa ti on to the seri a l con sol e. If you'd li ke
to vi ew i t, you'll n eed to keep the USB ca bl e p l ugg ed i n to your comp uter and
your rob ot; b e careful, sin ce the robot will be moving. If you're using an Ardui n o
92
Load and Run helloRobot. ino
Leonardo, wait until the robot's L ED flashes to indicate it's ready before open
ing the Arduino Serial Monitor (the Serial Monitor is the rightmost icon on the
Arduino toolbar). When the sketch starts, you should see the following in the
Arduino Serial Monitor:
Waiting fo r a sensor to detect blocked reflection
Swi pe something dark (a small piece of matte black paper the size of a business
card works well) near one of the sensors (panel2 seen in Figure6-7 ). The Serial
monitor should now display the output similar to that shown in Example 6 -2.
The number of lines and the values displayed will vary with different robots
but you should see multiple lines showing the direction of rotation, speed and
time in m illiseconds.
Motors on the left side should spin in reverse, motors on the right should spin
forward for the indicated time in milliseconds (if the robot was on the ground,
it would rotate to the left (counter-clockwise). If you don't see the expected
results, see "Troubleshooting" (page 9 8) for help.
Completing this test will verify that everything (the robot motors, power
source, Arduino and motor shield) is wired up and functioning correctly. Dou
ble check that you have completed all the building steps. Take particular care
that the battery wires to the motor shield are attached to the correct polarity.
Chapter 6 93
Load a nd Run helloRobot.ino
94
About the Sketch
The li ne shown in Example 6-4 i nc ludes the library written for thi s book
(RobotMoto r . h).
Thi s lib rary provides a consi stent interface for motor functions in order to i so
lat e the hig h er le vel logic fro m ha rdwa re specific s. Thi s mea ns that yo u ca n
use the sa me sketch code with (a lmo st) a ny motor hardware si mp l y b y cha ng
i ng the RobotMotor libra ry code to suit the ha rdware. The motor co de is e x
plai ned in the next chapter a nd yo u ca n fi nd exa mple code to support a dif
ferent motor controller i n Appendix B, Using Other Hardware with Your Robot.
The block that begins with: /***** Global Defi. nes **** / contains declara
tions for constants that i dentify: sensors, di re ctions a nd o b sta cle s. The se con
sta nts enable you to refer to ele ment s i n your sketch usi ng mea ni ngful na me s
i nstea d of numbers, for exa mple thi s:
calibrateRotationRate ( D I R_LEFT , 360 ) ;
i nstea d of thi s:
MotorForwa r d ( 0 , 360 ) ;
The setup section cal ls functions to i nitialize the motor a nd se nsor modu le s
(more on these later). The loop function u se s the lookForObstac le function to
determi ne if a reflection i s detecte d. It waits unti l no reflection i s detected o n
Chapter 6 95
About the Sketch
either sensor; the robot is not on the g round (or on a non-reflecti ve s urface).
The lookForObstac le func tion is checke d to determ i ne if the left or ri ght sensor
detects a reflection, and if so, calls the ca l"i.brateRotati.onRate function to
rotate the robot for a short perio d.
The lookFo rObstac le func tio n is told wh ich obstacle to check for (the obsta
cles a re i dentified usi n g the defines described a bo ve). The case sta tement (see
h ttp://arduino.cc/en!Referen ce/SwitchCase) is use d to call i. r EdgeDetect func
tion that returns true if a n object is de tec te d on that sensor. If no object i s
detecte d, the function returns OBST_NONE, shown in Exam ple 6-5 . See "I nfrared
Reflectance Sensors" ( page 1 34) for a detai led ex pl an ation of i. r EdgeDetect and
relate d functions.
96
About the Sketch
Thi s function will return true if th e reflec tion level is reduced. Thi s is deter
mi ned thro ug h a call to ana logRead to g et a raw sensor rea di ng tha t i s co m
pared to a detected/not detected th reshold. Values g re ater th an or eq ual to
the th reshold are co nsi dered a loss of reflec tion ( th e vol tage fro m th e sensor
i ncre ases wh en the reflec ted light decrease s , see "I nfrared R eflec tance Sen
so rs" (page 1 34) for deta i ls on the refl ec ta nce sensors). The resul ts fro m thi s test
is stored in an a rra y named "i.sDetected. The a rra y can be used to recall the
sensor state of th e most recent cal l to "i.rSensorDetect and is used h ere to
sup press printing of the test result if a previo us test alrea dy i ndica ted tha t a n
o bj ec t was detec ted, a s shown i n E xampl e 6-7 .
Motor cod e i s expl ai ned i n d etail i n Ch apter 7, Controlling Speed and Direction.
Rota ti ng the ro bot i s handled by the ca HbrateRotat"i.onRate func tion. For
exampl e. if th e l eft sensor is trigg ered, the cod e wil l spi n the left motor i n
re verse and the rig ht moto r forward, thus rotati ng the robo t towards the left
(counterclockwise):
if( sensor == DIR_LEFT)
{ / / rotate left
MotorReve rse( MOTOR_LEFT , speed ) ;
Moto rForwa rd ( MOTOR_RI GHT , s peed ) ;
Chapter 6 97
Troubleshooting
Troubleshooting
If you are h avi ng t rouble g etti ng H elloRobot w orking th en th e fi rst thing to d o
i s t o put th e robot d own, walk away from your com puter screen and have a
refresh i ng d ri nk. C om e back and look at th i ngs with fresh eyes and ch eck to
see if you h ave thi ngs wi red up and c on nected correctly. If i t looks li ke t he
c onnecti ons are okay, t h en th e next step is t o m ake a list of t h e maj or symp
toms:
Compile errors
• ' AF _DCMotor ' does not nal'le a type error m essag e-this m ess ag e i n
dicates th e AFM otor li brary h as not been found. This li brary is i n cluded
with the d ownload c od e for this book (see "H ow t o Contact Us" (pag e x v)
for the U RL). S ee " I nstalli ng Thi rd-Party Li brari es" ( page 83) i n Cha pter 5,
Tutorial: Getting Started with Arduino for h elp with this.
• " This chip is not supported ! " error m ess ag e-Th is m essag e is dis
played if the chip s elected in the I DE is n ot rec og n ized by the library. This
will occu r if you s elect the Leon ard o board and use a versi on of the AF
m otor library th at d oes not support thi s chi p. Replacing your AFM ot or
li brary with the on e in th e book's example c od e will fix th is problem.
• " expected definition : CHASSI S_ZWD o r CHASSIS_ 4WD not found " will
be displayed if you ch anged the d efi nes i n t h e R obotM ot or library t o an
i nvalid value. This li brary expects to fi nd either CHASSIS_2WD or CHAS
SIS_4WD foll owi ng the #define i n Robot M ot or.h.
Softwa re Errors
• The S eri al M onit or is not dis playing th e text s hown at th e end of "L oad and
Run h elloRobot.i no" (pag e 88)-read th rough Ch apter 5, Tutorial: Getting
Started with Arduino and c h eck th at you have the d ri vers for your board
c orrectly i nstalled.
• The S eri al M oni tor displays th e i ni ti al text but th en dis plays errors or oth er
un expected text-s ee A ppendix C, Debugging Your Robot.
Ha rdware symptoms
98
Making the Sketch Easy to Enhance
You can test each motor by disconnecting the motor wires going to the
motor terminals on the shield and connecting them directly to the battery
terminals. If the motors still do not turn but theshield LED is lit, then double
check the shield soldering.
• Twoof thefourmotors don'tturn onthe4WD robot-Have you configured
the library for 4WD?-see "Software Prerequisites" (page 86).
• Motors run but the robot does not rotate 360 degrees-the robot rotation
does not need to be exact; anything within 20 or 30 degrees is good
enough. See Chapter 7 if you do want to adjust the rotation rate.
Chapter 6 99
Making the Sketch Easy to Enhance
You can download the fTlyRobot sketch from the book's website but you
may want to go through these steps yourself to familiarize yourselfwith
the procedure for creating and using tabs in the /DE.
1 . Load the HelloRobot sketch and use the ID E file menu to save as 'myRobot'.
2. Create a tab by clicking the tab dropdown and selecting 'New Tab' (see
Figure 5-8). Name the tab 'lrSensors'.
3. Click the l'lyRobot tab, scroll down to the end of the sketch and cut all code
from the end up to the i. r reflectance sensor code (Example 6- 8) com
ment and paste it into the I rSensors tab.
void i r SensorBegin ( )
{
fo r ( i n t sensor = 0 ; sensor < NBR_SENSOR S ; senso r++ )
i r SensorCalibrate ( senso r ) ;
100
Making the Sketch Easy to Enhance
}
isDetected [ senso r ] = result;
retu rn result;
}
isDetected [ sen sor] = result;
retu rn result;
The l'lyRobotOk exa mple ske tc h provide d i n the boo k down loa d code shows
the code after the c ode is moved i n to the tabs.
Global Definitions
Definitions that need to be accessed across multiple process will automatically make all of the functions
modules are called 'g lobal' definitions.These are gen i n each tab accessible throughout the sketch, con
erally stored in files called 'header files' (or 'headers'). stant definitions should be explicitly included at the
These files typically have a file extension of . h and top of the main tab as follows:
the file containing these global definitions is here II include the global defines
called robotDefi.nes . h. Although the Arduino build #include " robotDefi. n es . h "
The fin al ste p i n re structuring the sketc h i s t o move the c on stan t defini ti on s
at the top of the sketch i n to a sep arate tab. The se con sta n ts are used by a
n umber of different mod ules and c ollecting the se together m akes i t easier to
ensure th at the val ues are accessible by a l l the modules:
Chapter 6 101
Making the Sketch Easy to Enhance
2. From the top of the myRobot tab, m ove th e defin es start i ng from:
I **** Global Defines **** I
and en di ng at:
I *** End of Global Defines *******I
(Exam ple 6-9) i nto the tab you j u st created.
3. Switch ba ck t o the myR obot ta b, a n d a dd this line at the t op, ri g ht after
the #i.nc lud e s for AFMotor.h and RobotMotor.h:
#include " robotDeftnes . h "
canst char * locationSt ring [ ] = { " Left " , " Right " , " Center " } ; II Debug labels
II http : lla rduino . cclenlRefe rencel String for �ore on cha racter string ar rays
II obstacles constants
canst i n t OBST_NONE = 0; II no obstacle detected
canst i n t OBST_LEFT_EDGE = 1; II left edge detected
canst int OBST_RIGHT_EDGE = 2; II right edge detected
canst int OBST_FRONT_EDGE = 3; II edge detect a t both left a n d right senso r s
102
Controlling Speed and
Direction
This chapter covers the principles of robot motor control that apply to both
two wheeled and four wheeled platforms. The motor controller hardware is
explained, as is the code used to make this functionality accessible to the
sketches. The second half of this chapter ("Software Architecture for Robot
Mobility" (page 1 19)) describes software modulesthat frees the sketch logic from
a dependency on any specific motor hardware. All sketches use the library
named RobotMotor that provides a consistent interface to the hardware spe
cific motor system. An optional software module named Move provides high
level functions to move the robot that simplifies the code in the more complex
sketches that follow in chapters to come.
Hardware Required
• This chapter uses the AFMotor shield described in Chapter 2.
103
Types of Motors
• MyRobotMove . 1.no-This sketch s hows how to use hig her level movement
functi ons. Constants for d efining the cu rrent rob ot movement a re add ed
to the rob otDefin es tab. A n ew tab named M ove is add ed t hat c ontains
the hig h level movement functi ons. The l rS ens or tab and R ob otM otor li
bra r y a re unc hanged (Fig ure 7-1 ).
�
-
Move
myR obotM ove Move state -I RobotMotor
-
(Movement
added Library
Codel
Types of Motors
Brushed DC M ot ors, such as the on es used in the two wheeled and fou r
wheel ed platforms (see Figure 7-2) are the most c ommon t y pe used wit h Ar
d u i n o rob ots. Th es e have two l eads c on n ected to brush es (contacts) that con
trol the mag n etic fi eld of the coi ls th at d rive t he mot or c ore (a rmature) . M ot or
d i recti on can be reversed by reversing the polarity of the power s ourc e. These
m ot ors typically rotate t oo fast t o di rectl y d rive t h e rob ot wheels or tracks, s o
g ea r red ucti on is used t o reduce s peed and increase t orq u e.
104
Types of Motors
O ther ki nds of m otors can be used to power robots; here are som e you m ay
com e across:
Continuous rotation servo
These m otors are u sed on sm al ler robots. Th ey have the advantag e that
the m otor control ler, motor, and g earbox are all m ou nted i n the sam e
hou sing, so they are easy to attach to a robot and can be driven directly
from Ardu i no pins. However they u sually h ave l ess torq ue th an typi cal
stand·alone bru shed motors.
Brush/ess motors
These h ave i ncreased torqu e and effi ci ency com pared to bru shed m otor s
but they are m ore expensive and complex to control. However, pri ces are
droppi ng and they are a g ood choi ce for a l arg er robot.
Chapter 7 105
Motor Controllers
Stepper motors
Th ese motors are u sed on large robots when prec i se c ontrol i s requ ired.
Th ese motors typically requ ire 1 2 or 24 vol ts so they are not often u sed on
smal l battery operated robots. H owever they may becom e m ore popu l ar
d u e to th e recen t avai l abi l i ty of l ow c ost 5 volt steppers.
Motor Controllers
The two wheel a nd four wh eel pl atforms u se sma l l DC m otors tha t are con
trol l ed u si ng an H -Brid g e. The H-Brid g e featu red in th i s book is part of the
AFM otor sh i eld from Ad afru i t I n d u stries. Thi s can d rive up to fou r m otors i n
d epen den tly, alth ough on ly two a re u sed wi th the two wheel ed robot. This
shi eld req u ires a library for i nterfaci ng sketc h c ode wi th th e hard wa re; thi s
l i bra ry is i nc l u d ed with the cod e d ownload for th i s book (see " H ow to Contac t
U s" ( pa ge xv)).
The name H-bridge derives from the characteristic shape that you can
see in these figures.
This library is modified from the one on the Adafruit site to work with
the Leonardo board. The standard Adafruit library can be used with
the Uno board). See "Installing Third-Party Libraries" (page 83) if you
need directions for installing a library. If you followed along with
Chapter 6, you will already have the library installed.
106
Motor Controllers
The followi ng diagra ms ex pla i n how an H-bri dge works a n d the RobotMotor
func ti ons used to con trol the motors:
Supply Voltage
T Figu re 7-3 is a schematic dra wi ng tha t shows
I
how an H-bri dge works. The m otor is connec
ted to the positive su pp ly voltage a nd g rou nd
throug h fou r swi tches (in the actual H-bri dge,
A the swi tchi ng is done wi th transis tors). When
a ll the s wi tches a re open, no cu rrent flows a n d
the m otor i s stopped. The c ode to s top a m otor
is:
MotorStop(Motor ) ;
Supply Voltage Fig ure 7-4 sh ows the two swi tches tha t when
closed will ca u se the motor to ru n forwa rd. The
one marked A c onnects the posi tive m otor ter
m i na l to the p ositive p ower supply. S wi tc h D
Chapter 7 107
Motor Controllers
"
E
8 Ground
.o,(.
0
I
Figure 7-5. H-Bridge with Motor Running i n Reverse
l Supply Voltage
T
Figure7-6 shows switches B and D closed. Both
I
motor terminals are connected together - nei
ther terminal is connected to the positive sup
ply voltage. This is a mode supported by some
A
H-bridge hardware to stop the motor more
quickly than it would in the previous case
where the motor is simply disconnected from
the power. Because the motor terminals are
shorted, the motor will resist rotation. If the
motor had been spinning and then set to this
mode, it will stop more quickly than if the ter
minals were simply disconnected. The code to
brake a motor is:
Mot o r B r a ke (Moto r ) ;
Ground
Figure 7-6. H-Bridge with Motor Brake Not all H-bridges, including the
Adafruit library, support this
mode. The Robo tMotor library will
call !'lotorStop when the !'lotor
Brake function is called.
108
Controll ing Motor S peed
LOW __________________
LOW
::: I I I I I
Motor ¼ speed : AnalogWrite(M_PWM, 191 ) (75% duty cycle}
::: I I I I I I
Motor max speed: AnalogWrite(M_PWM, 255) [1 00% duty cycle}
HIGH
LOW
Battery Positive
r7_J7__
Ground
Chapter 7 109
Controlling Motor Speed
All the code in this book uses a percent value to refer to speed. This value is
the percentage of power given to the motors (technically, its called the duty
cycle). Percent speed is used instead of the raw PWM value to isolate the sketch
logic from the low level motor code. Different motor hardware use various
techniques for controlling motor rotation speed. For example, continuous ro
tation servos can use servo angle (where 90 is stop and O actually rotates the
motor at full reverse speed), and stepper motors don't use PWM to control
speed. Because the h igh level logic always uses percent and this is mapped to
the range needed by the hardware in the motor interface code, the same high
level code can be used with other hardware simply by swapping the appro
priate motor interface module.
l'lap is a ha ndy fu nction that is used exte nsively throughout this b ook.
The fu nction scales a value from one ra nge to a nother ra nge. For ex
a mple, the following scales a value from ana l ogRead (0-1 023) to a
p ercent (0- 1 00):
Bear in mind that the speed percentage is actually controlling motor power
and this is usually not directly proportional to speed, particularly at low power.
110
Control ling Motor S peed
The amount of p ower requ i re d to get the robot movi ng is depen dent on the
motor, gearbox, batte ry voltage, robot wei g ht an d the su rface the robot is on.
The meth od to calib rate the rob ot wi l l be descri be d shortly, bu t first, here is
an exp l an ati on of h ow the s oftware handles robot speed control.
The c ode frag ment shown in Example 7-2 c on tai ns the cons tants that are used
to calculate the app ropri ate delays for different speeds to rotate the rob ot.
rotati.onTi.l'le stores the durati on fo r a 360 de gree rotati on for all practical
speeds. Spee ds less than MIN_SPEED (40%) do n ot provi de suffi cient power to
overc ome fric ti on in the dri ve sys tem.
Example 7-2. Constants for the delays needed to rotate the robot, from RobotMotor.cpp
con st int MIN_SPEED = 40 ; // fi rst table entry is 40% s peed
con st int SPEED_TABL E_INTERVAL = 1 0 ; // each table entry is 10% faster s peed
con s t int NBR_SPEEDS = 1 + ( 100 - MIN_SPEED ) / SPEED_TAB LE_INTERVAL;
The table holds du rati ons in m illisecon ds for speeds in in tervals of 1 0%. The
values we re deri ve d from experi men tat i on wi th the two wheeled robot using
a s ke tch named l'lyRobotCa l i.brateRotati.on sketch an d notin g the an g les for
each of the speeds as s h own in Fi g u re 7-8.
Rotation Angle
for Speeds from 40% to 100%
t 2 50 +----------------------,....-=--t
QI� 200 +--------------==-- �- �--------
-=
O 15 0 +------------,:::,;;;,o+-=-----"'�------------
.5
QI 100 +-----=-S:,.,..,.---_.::.c;_:__________________
� so
o +----�---�---�---�---�---�--�
40 so 60 70 80 90 100
Speed (as percent)
Figure 7-8. Angle that the robot rotates for one second burst at each of the supported speeds
By calc ul ating the ang le as a fracti on of 360 degrees, the time to rotate the
robot one c omplete revoluti on can be determi ned foreach speed ( the calcu
l ati on for the val ue in millisecon ds is: 1000* ( 360/ang le ) .
Chapter 7 111
Controlling Motor Speed
5000
-g0 4000
:: 3000
::JE
.!:
E 2000
i=
1000
0
40 so 60 70 80 90 100
Speed (as percent)
The rel ationshi p between rotation ang l e an d speed percen tag e i s not li near,
so inter polation i s u sed to calc ulate the duration to produ ce a fu ll ro tation for
an y speed (as long as i t i s as fast or faster than the m i n i m um speed).
Exam ple 7-3 shows the code th at u ses the table wi th tim es based on the data
shown in Figu re 7-9.
The RobotMotor l i brar y has the code to determi ne how m uch tim e the robo t
req uires to rotate 360 d egrees. Thi s wil l differ between the two an d fou r
wheeled chassi s and vary as the motor speed vari es. Ex am pl e 7-3 show s the
val u es used in the RobotMotor.cpp code for the 2WD chassi s.
112
Contro l l i ng Motor S peed
Exam ple 7-4 shows the values for the 4WD cha ssi s.
Note that there are fewer entries in the ta bles for the 4WD robot beca use thi s
cha ssi s req ui res a hi gher spee d to get going. "Ca li brating Rotation a n d Tra ck
i ng" ( page 1 1 6) expla i ns how to a dj ust the tab le s to suit yo ur robot.
The table entries a ssume speed i nterva ls of 1 0% so the va lue for M I N_SPEED
should be m ulti ple of 1 0. There m ust be o ne rotation time per spee d so if yo u
i ncrease M I N_SPEED by 1 0 for e xam ple, you will a lso need to remove the fi rst
element i n both speedTa ble and rotationTime.
The code in RobotMotor.cpp that uses the data in the rotationTime ta ble is the
same for both cha ssi s (see Exa m ple 7-5).
Chapter 7 113
Co ntrolling Moto r Speed
Modifying a Library
You know how to modify an Arduino sketch-just 2. Locate the libraries directory i nside, and then
edit it in the Arduino IDE. But modifying a li brary is a open the directory named RobotMotor.
bit more involved. You need to go into the sketch
folder, open up the library directory, and find the file. 3. Right-click (or Control-click on the Mac) the
Then you need to open it i n a text editor. Here's how RobotMotor.h fi l e, and open it with a plain text
to modify the RobotMotor.h file to use the 4WD chas editor. On Windows, you should use Notepad.
sis. On the Mac, you can use TextEdit. On Linux,
use your favorite plain text editor.
First, find the sketchbook location. Go to Arduino's
preferences (File ➔ Preferences on Wi ndows or Li nux, 4. Change #defi.ne CHASSI S_ZWD to #defi.ne
Ardui no➔ Preferences on Mac) . Under Sketchbook CHASSI S_4WD and save the file.
Location, you'll find the name of the d irectory that
contains your sketches and libraries. Next: Although you need to quit and restart the Arduino
IDE when you i nstall a new li brary, you don't need to
1 . Open the sketchbook folder in the Finder do so each time you modify a library.
(Mac) or Explorer (Windows).
a ngle = a b s ( angle) ;
114
Control ling Motor S peed
// Seri.al . pri.nt ( " full rotati.on ti.Me = " ) ; Seri.al . pri.ntl n ( fullRota ti.onTi.Me ) ;
long result = Ma p ( a ngle , 0 , 360 , 0 , fullRotati.onTi.Me ) ;
return result ;
Thi s c ode determin es the i ndex i nto the s peedTab le array that i s c losest to ( but
not greater than) t he desi red speed. Thi s i n dex is stored in the vari abl e t0. The
i nterpolated time will be between th i s valu e an d t he n ext i n dex (tl ) , with the
rotat i on time c alc ul at ed usi ng t h e rati o of the rotat'i.onHMe valu e between tO
and t l i n the sam e proportion as the desi red speed i n the s peedTab le. It may
be easi er to u nderstan d how thi s works by c on su lting Fig ure 7-1 0.
2400 (t0)
C/l 2300 -
2200 -
E
C: 2 1 00 -
Q) 2000 (t1 )
62.5 65 67.5
60% 70%
Speed (as percent)
Figure 7-10. Speed Interpolation
Chapter 7 115
Controlling Motor Speed
For exam ple, for a speed of 65%, whi ch is halfway b etween the valu es for 60%
and 70%, t he tim e a ssociated wit h 65% speed will be 2200, which i s ha lf way
b etween 2400 (the 60% speed value) a n d 2000 (the 70% speed val ue). A speed
of 62.5% i s 1 /4 of the range between t he tabl e entri es (60 a n d 70), so the time
will be 1 /4 of the rang e between t he speeds for that ra nge (2400 and 2000,
whi ch is 2300 mi llisecon ds). The l'lap fun ction is u sed to cal culate thi s pro por
tional value:
fullRotationTiMe = M a p ( s peed , s peedTable [ index ] , s peedTable [ i ndex+ 1 ] , t0 , t 1 ) ;
To calculate the time to rotate an ang l e other tha n 360 deg rees, the r1 a p func
tion i s used again:
long result = r,ap ( a ngle , 0 , 360 , 0 , fullRotatlonTlr,e ) ;
/ / Setup runs at startup and is used configu r e pins a nd init systeM va riables
void setup ( )
{
MotorBeg i n (MOTOR_LEFT) ;
MotorBeg i n ( MOTOR_RIGHT ) ;
calibrateSpeed ( ) ;
void loop( )
{
}
116
Controlling Motor Speed
Running this sketch will rotate the robot left (CCW ) for one second, stop for
one second, then rotate the robot right (CW) for a second. If you mark the angle
of the robot after each CCW rotation, you can calculate how much longer or
shorter it would take the robot to turn360 degrees for each speed. If your robot
does not rotate at all at the slower speeds, note the lowest speed that the robot
does move and set MI N_SPEED in RobotMotor.cpp to this value.
The RobotMotor library also supports the ability to adjust the relative power
to each motor in order to prevent the robot drifting off a straight course due
to differences in performanee between the left and right motor(s). If your robot
does not track a straight line when moving forward or backward, you can
modify the motor library (see next section) to correct this.
The RobotMotor.cpp library file contains a constant that can be adjusted to
correct drift:
con st int differential = 0; / / % faster left Motor t u r n s coMpa red to right
If your robot drifts, adjust the constant d lfferentla l t o compensate. Set the
value using trial and error, positive values nudge the robot to the right, nega
tive values to the left. The correct value will be the difference in speed between
the motors in percent. The drift will vary somewhat with motor speed so best
to set this when testing with the robot running at a speed midway between
the minimum and maximum speeds.
Chapter 7 117
Controlling M otor Speed
Here is a modified version of the previous sketch that will drive the robot in a
straight line when the differential constant is adjusted to correct drift. You can
make di. ffe renti.a l a negative number if your right motor turns faster than
your left (the robot drifts to the left).
/ / Setup runs at startup and is used configu re pins a nd init systeM varia bles
void setup ( )
{
MotorBeg i n ( MOTOR_L EFT) ;
MotorBeg i n ( MOTOR_RIGHT ) ;
calib rateDrift( ) ;
void loop( )
{
}
118
Software Architecture for Robot Mobility
If the robot drifts the right when running this sketch, try setting dHferen
ti.al to 2. If this overcorrects (the robot now drifts to the left), decrease the
differential value. If you need more correction, increase the value. If the robot
was drifting to the left, use negative values of differential to compensate. You
should be able to get the robot running more or less straight after a little trial
and error. Don't worry about minor deviations which are caused by small dif
ferences in the efficiency of the motors at varying battery levels.
After you have settled in a value for di. ffe renti.a l you must change this in the
RobotMotor.cpp file. Open this file with a text editor and (see "Modifying a
Library" (page 11 4)) and find the declaration towards the beginning of the file:
can st tnt dtfferenttal = 0; / / % faster left Motor t u r n s coMpa red to rtght
Replace O with the value determined from the calibration sketch and save the
file.
Chapter 7 119
Software Architecture for Robot Mobility
Sketch
Sketch calls any function at any level
4 M otors 2 M otors
Example 7-9 shows the source code for the RobotMotor library's .cpp file. The
header file RobotMotor . h (Example 7- 8) defines the constants for the left and
right motors and declares the functions for speed and direction.
120
Software Architectu re for Robot Mobility
Chapter 7 121
Software Architecture for Robot Mobility
122
Functions to Encapsulate Robot Movements
The R ob otM otor. cpp file contains code for both the two wheel and four wheel
chassis. Conditional compilation is used to build the library for the appropriate
version. #H defi.ned CHASSIS_2WD and #H defi.ned CHASSIS_ 4WD are checks
to see which chassis has been defined in the Rob otM otor. h file. code between
#H defi.ned CHASSI S_2WD and #end-L f will only be compiled if CHASS IS_2WD is
defined in RobotM otor. h. See "Installing Third- Party L ibraries" (page 83) for
more details on changing the define for the four wheel chassis.
This library can be modified to support different hardware. For example, see
Appendix B for the code to use the Ardumoto shield (but note that Ardumoto
only supports two motors so is not suitable for the four wheeled robot).
Chapter 7 123
Functions to Encapsulate Robot Movements
Enh an ce" ( pag e 99) but uses the rot atio n fu n ctions in the Move tab to drive
the robot. Using the hig her level fun ctions to drive the ro bot not only si mplifi es
your code, it isolates the sketch lo g i c from the h ardware specific motor code.
Th e sketch es in all of th e followi ng ch apters control ro bot movement thro ug h
the fun ctio ns in th e Move tab.
void MoveBegin ( )
{
Moto rBegin( MOTOR_LEFT ) ;
Moto rBegin( MOTOR_RIGHT ) ;
MOVeStop( ) ;
void Moveleft ( )
{
Motor forwa r d ( MOTOR_LEFT , 0);
124
Functions to Encapsulate Robot Movements
votd MoveStop( )
{
MotorSto p ( MOTOR_LEFT ) ;
MotorStop ( MOTOR_RIGHT ) ;
changeMoveState ( MOV_STOP) ;
votd MoveBackwa rd ( )
{
MotorReve rse( MOTOR_LEFT , MoveSpeed ) ;
MOtorReverse(MOTOR_RIGHT , MOVeSpeed ) ;
changeMoveState (MOV_BACK) ;
The co de provi des functions that com bine the i n divid ua l motor co mma n ds
described in "Motor Con trollers" ( page 1 06). For exam ple, the r1oveForward
fu ncti on cal ls the i ndivi dual fu nctions to rotate the left a nd right motors i n the
Chapter 7 125
Functions to Encapsulate Robot Movements
di recti on that m oves the robot forwa rd. Th e speed to move is set by the !'love
Set Speed functi on. l'loveSe tSpeed commands the motors to run at the desi red
speed a nd stores th e speed va l ue so the robot ca n resume runni ng at the last
set speed fo l l owi ng a n eva sive acti on nee de d to avoi d obstacles.
int MoveGetState( )
{
retu rn MOVeState ;
126
Functions to Encapsulate Robot Movements
If you are unfa miliar with enuf'I (enu merated lists), see "Code Style
(A bout the Code)" (pa gexii) in Prefa ce or a n o nline C o r C++ reference.
To assist debu g g i ng, each state has an associ ated te xt label that can be printed
to the seri al monitor to show what the robot sho u l d be doing.
canst c ha r* states ( ] = { " Left" , " Right " , " Forwa rd " ,
11
8 ack 11 ,
11
Rotate'' , ''Stop ' ' } ;
The move state defin e s are loc ated at the e n d of the robotDefi.nes . h tab.
Chapter 7 127
Functions to Encapsulate Robot Movements
/ / retu rn the tiMe in Milliseconds to turn the given angle at the given speed
long rotationAngleToTiMe ( int a ngle , int speed )
{
int fullRotationTiMe ; // tiMe to rotate 360 degrees at g iven s peed
a ngle = a b s ( angle) ;
int index = ( s peed - MI N_SPEED) / SPEED_TABL E_I NTERVAL ; // index into s peed and tiMe tables
int t0 = rota tionTiMe [ index ] ;
int t l = rotationTiMe[ index+ l ] ; / / tiMe o f the next higher speed
fullRotationTiMe = M a p ( s peed , speedTabl e [ index ] , s peedTable [ index+ l ] , t0 , tl ) ;
128
Functions to Encapsu late Robot M ovements
/ / Serial . p rint ( " index= " ) ; Serial . print( index ) ; Serial . print ( " , t0 = " ) ; Se rial . p rin t ( t0 ) ;
/ / Serial . p rint ( " , t l = " ) ; Serial . print( t l ) ;
}
// Serial . print( " full rotation ti!'le = " ) ; Serial . p rintln ( fu llRotationTil'le ) ;
long result = !'la p ( a ngle , 0 , 36 0 , 0 , fullRotationTil'le ) ;
return result ;
/ / rotate the robot frol'I MI N_SPEED to 100% inc reasing by SPEED_TAB LE_I NTERVAL
void calib rateRotationRate(int directio n , int angle )
{
Serial . print ( locationString [di rection ] ) ;
Seria l . println ( " calibration" ) ;
for ( int s peed = MIN_SPEED; speed <= 100 ; speed += SPE ED_TABLE_INTERVAL)
{
delay( 1000 ) ;
//blin kNul'lber ( speed/ 10) ;
Chapter 7 129
Functions to Encapsulate Robot Movements
Th e fTloveRotate fu ncti on will rot ate a robot by the gi ven angle. Neg ati ve ang l es
tu rn c ounter c l oc kwi se, positive angles turn c l ockwi se. R ot ation is ach i eved by
running th e motors in opposite d i recti on s (see "H ow Robots M ove" (pag e 5) ).
/ /Moves in the given di rection at the c u r rent speed for the given duration in Milliseconds
void tiMedMove (int direction , int d u ration )
{
Seria l . print( "HMed Move " ) ;
i f ( di rection == MOV_FORWARD ) {
Serial . p rintln ( " fo rwa rd " ) ;
MoveForward ( ) ;
}
else if(di rection == MOV_BACK)
Serial . println ( " back " ) ;
MoveBackwa rd( ) ;
}
else
Serial . println ( " ? " ) ;
MovingDelay(du ration ) ;
Moves top( ) ;
130
Functions to Encapsulate Robot Movements
}
}
The ti.l'ledMove and l'lov"i.ngDe lay fun c tions work tog ether to provi de a si mp le
wa y to instr uc t the robo t bri efly mo ve awa y from a n obstacle. Beca use !'loving
De lay can c h ec k for obsta c les wh i le taking evasive ac tion, i t can a voi d b umping
into n ew obs tacles while mo ving awa y fro m a not her. Th e checkMovel'lent
fun c tion is implemen ted in th e Look module ( see "The Look Co de" ( pag e 1 49)).
Chapter 7 131
Tutorial: Introduction to
Sensors 8
Sensor information can be used by your robot to navigate and interact with
its environment. Sensors report on the world around them; measuring light,
distance, sound, movement, direction, temperature, pressure, or location. This
chapter describes how common sensors used with two wheeled and four
wheeled platforms work.
The first half of this chapter covers the primary sensors used in the chapters
that follow: IR reflective sensors and SONAR distance sensors. These are used
to determine if an object is near the robot. Reflective sensors detect nearby
objects and are used for line following and edge detection (determining if the
robot is near the edge of the surface it is moving on, such as the edge of a
table). Distance sensors are used to determine the distance to objects up to
ten feet away from the robot. The second half of the chapter covers other types
of sensors you can add to enable the robot to respond to distance, sound,
movement, or other stimuli. You should also have a look at Appendix D, Power
Sou rces which describes a very useful aspect to sense, the robot's battery volt
age.
Hardware Discussed
QTR- JA refle cta nce sensors
Two are used for edge detection, but a third is required for line following.
Additional sensors are available from many internet shops that stock robot
parts, or direct from the manufacturer: http://www.pololu. co m/catalo g/
pro duct/958/
SONAR Dista nce Senso r
One is used to measure the distance to obstacles (Maker Shed product
code M KPXS).
133
Software
Software
The chapter contains background information on sensors that will be added
to the robot in later chapters. The reflectance sensor code is from the sketches
introduced in Chapter 6 , Testing the Robot's Basic Functions. The Ping (Sonar
distance sensor) hardware and software is covered in Chapter1 0, Autonomous
Movemen t.
Obstacle
IR
Reflects
Emitter I R beam
IR
Detector
134
Infrared Reflectance Sensors
Sensor constants determine which sensor to use: SENSE_IR_LEFT for the left
sensor, S ENSE_IR_RIGHT for the right (these constants are defined in robotDe
fines . h (see "Making the Sketch Easy to Enhance" (page 99 )). The i. rSensor
Detect function uses the sensor constant to retrieve the analog pin number
stored in the I R_S ENSOR array. If the ana logRead value is less than a predeter
mined threshold, the function returns t rue indicating that a reflection has
been detected. These functions use arrays instead of simple variables to store
pins and thresholds because arrays make it easy to extend the code to support
any number of sensors. To add a sensor, increase the NBR_S ENSORS constant
and add the sensors pin number to the list of pins in the IR_S ENSOR array.
Chapter 8 135
Infrared Reflectance Sensors
ing downwards, no reflection from the surface is detected because a dark ob
ject is blocking the reflection or the nearest surface-probably the floor-is
many inches away! This effect is used in the examples from Chapter 6 to detect
when you've placed a dark object under the sensor.
The sensors need to be calibrated to take ambient light into account. Reflec
tance sensors respond to sunlight and artificial light so a threshold is measured
with no object near the sensor. L evels above this threshold mean the light level
is above ambient, which indicates that a nearby object is reflecting the IR light
from the sensor. Ambient light calibration is done using the code shown i n
Example 8-3.
136
Sonar Distance Sensors
You may com ea cross code that perfo rm s this calculation u sing floating
point (af11b ient * 0 . 95). However, floating point requires m ore code
a nd memory tha n integer calculations.
This loads the am bient l i g ht level i n to the variable ar1b1.ent, c alcul a tes levels
for reflec tance detec tion (stored in the "i.rSensorReflect a rray) and levels for
e dge detec tion ( sto red in the "i.resens o r Edge array). The con stant "i.rReflect
Th reshold is the percentage differen ce in l i g ht to de tect a refle c ti n g obst acl e.
The con stan t -L r edge Th res hold i s the perc e nt diffe rence to detect an e dge. The
defa ult values for the se thre shol ds are 1 0% for reflection a n d 90% fo r e dge
detec tion.
Here is a n exam ple assum i n g the a mbient val ue from a nalog Rea d wa s 1 000
wi th "i.rReflectTh resho ld equal to 1 0 :
( 1000 * 9 0 ) / 1 0 0 =
90000 / 100 =
900
In t h i s exam ple, if the ambient read i n g wa s 1 000, the i rSe nso rReflect's thre sh
o l d rea di n g fo r object detection i s 900, w hich i s 1 0% below the a mbient rea d
i n g.
I ) }))
Outgoing Pulse
�
( ( ( ! < .....-
Reflected Pulse
Chapter 8 137
Sonar Distance Sensors
138
Maxbotix EZl Sonar Distance Sensor
// The ping t ravels out and back , so to find the distance of the
// object we take half of the distance travelled .
return �icroseconds / 29 / 2 ;
The pi.ngGetDi.stance fun ction return s the dista nce in i n ches a s m ea su red with
a ping sen sor on the dig i ta l pin (pi.ngPi.n) pa ssed to the fun ction. The sou nd
pul se u sed to m ea sure t he di stan ce i s tri g gered by sen din g a di g ital pu lse that
is low fo r 2 m i crosecond s a nd hi g h for 5 m i crosecon ds. The pin m ode i s
cha n g ed from ou tput t o i n put a nd the pulse I n fun cti on i s u sed t o m ea su re
the respon se from the sen sor, which a rri ves a s an i n coming pulse width. The
formu la descri bed a t the beginning of thi s secti on i s u sed to con vert t his val u e
t o the distan ce.
Outgoing Pulse
II))}
(I! ' '
Reflected Pulse
Chapter 8 139
Maxbotix EZl Sonar Distance Sensor
The version using pul se width (ezDtstancePW ) will wait for o n e seco n d before
g i ving up if n o return pulse i s detected (for example, if t he sen sor i s di scon
n ected). You can o ptionally set the m axim um ti me to wait for pu lsein; the
following example set stheti meo ut to t he duration n eeded for a pulse to travel
the m aximum di stance detectable by t he sen sor:
int value = pulse i n ( pin , HIGH, MAX_DISTANCE * 147L * 2 ) ;
// pulsein with tiMeout
You can use the analog i n put version (ezDtstanceAN), if you have a spare an alog
i n put pin, but if yo u only have digital pin s free, then use t he pulse width cod e
(ezDtstancePW) . The an alog version takes only as long as n eeded to measure
the voltag e so does no t need a timeout.
You can fin d more i nformation on thi s sen sor on the man ufa cturers web pag e:
http://www.maxb otix. com/Ultrasonic_Sensors/MB 1 0 1 O.htm
140
Sharp I R Distance Sensor
IR
Emitter
Chapter 8 141
Proximity Sensor
You can fin d lots more inform ation o n thi s sen sor h ere: h ttp://www.societyo
frobots. com/sensors_sharpirrange.sh tml .
Proximity Sensor
A P I R (Passi ve I nfrared) sensor can be used to acti vate your ro bot when it d e
tects th e presence of a nearby person, or even a do g or c at. Th e sensor ac ts
l i ke a swi tch th at sends a HIGH si g nal to an Arduino pi n when motion i s detected
(th ey work by detecti ng chang es in th e h eat radi ated from peo pl e or p ets).
Fi g ure 8-5 shows th e sen sor con nected to analog pi n 5, bu t you can use any
spare pin, such as A4 i nstead of AS.
142
Sound Sensor
To
o�:�:;• .=:::,,..:c -:,:--c=-----0-_ '"Uic.c-,-,-
0 0_0 1 ()--,
, ,....
0_0_0_0_0cc1 0
.,,,",--
'o'l() 0-0""'-
""U-
()
PQer 1 12 11 10 9 E 6 S -1 3 1 l 0
To
□□□00000
p1 ,c..._. e M 2 1 •
0e 0 0 0 0 □ □ □,
MJ M-1 e r
· ··- -- -- -- -- -- -- -- -- �..
Servo .
left
Motor
To
Battery left Right Center PIR Sensor
The following loop code will spin the robot when movement is detected. If you
wan t you r robot to do this, replace the loop fun ction in the MyRobot ske tch
from "M aking the Sketch E asy to En han ce" (page 99) wi th the code shown i n
Example 8-7.
Sound Sensor
You can use a sou n d sensor to s tart or stop your robot in response to sou n d,
for example a hand clap or whis tle. You will need a mi crophone wi th an am
plifier, for example, the BOB-09964 breakout board from SparkFun. Figure 8-6
shows the board c onnected to an alog pin 4.
Chapter 8 143
Sound Sensor
To
:::::---o-o-o-ocoiic,oiii"aio11r;ooo--o-o-oiiio,ciioT,1bif1T10lio10-o"
�:�;:: =:::i:::iii.:�-=---o
To
Servo
0 ARef nd 13 12 11 10 9
D □00000 00000□ □□
U• ed p,�
'• . .
e Ml S2 51 e
B
e M3 M◄ e M2
. · - - - - - - - - - ..
- - - - - --- - ,
7 6 5 ◄ 3 2 1 0
Lett
Motor
Right
Motor
al
O shield for arduino
�� u;� O D D □ □
J� AST 3v 5v Grd U1
� 00000
To
Battery Left Right Center
Reflectance Sensors
The code that follows is the main tab from the r1y Ro botS o u n d sketch available
in the download for this book. Noise level above a threshold will drive the robot
forward. The robot stops when the level drops below the threshold. If you need
to change the sensitivity, experiment with higher or lower values for the
threshold. Example 8- 8 shows the code for the main tab.
*********************************************************** /
144
Sound Sensor
con st int MiddleValue = 512; / /the Middle of the range of analog values
con s t int nuMbe rOfSaMples = 128 ; / / how Many readings will be taken each tiMe
con s t int th reshold=400 ; //at what level the robot will Move
int s peed = 50 ;
// Setup runs at startup and is used configure pins a nd init systeM variables
void setup ( )
{
Seria l . begin ( 9600) ;
blinkNuMbe r ( S ) ; // open po rt while flashing . Needed for Leon a rdo only
void loop( )
{
i n t level = getSoundLevel ( ) ;
i f ( level > threshold ) / / i s level More than the th reshold
{
Motor Forwa rd (MOTOR_LEFT , s peed ) ;
Motor Forwa rd (MOTOR_RIGHT , speed ) ;
} else
{
MotorStop( MOTOR_LEFT ) ;
MotorStop( MOTOR_RIGHT) ;
Chapter 8 145
Arduino Cookbook
return r u nningAverage;
See the Arduino Cookbook if you want a detailed description of how this code
works.
Arduino Cookbook
For descriptions of how to use lots of additional sensors with Arduino, see:
Arduino Cookbook by Michael Margolis (O'Reilly).
146
Modifying the Robot to
React to Edges and Lines
This chapter covers techniques that enable your robot to use sensors to gain
awareness of its environment. Using reflectance sensors, the robot will gain
the ability to follow lines or to avoid falling off the edge of the surface it is on.
Information from the sensors is abstracted so that the robot logic has a single
consistent interface and can easily be enhanced to support other sensors. The
physical mounting of the sensors varies with different platforms: see Chapter4,
Building th e Four-Wheeled M obile Platform if you have the 4WD chassis, Chap
ter 3, Building th e Two-Wh eeled M obile Platfor m if you have the 2WD chassis.
Hardware Required
• Two reflectance sensors are used for edge detection and a third is needed
for l ine following. Although you can use the stripboard mount (for the
three line following sensors) discussed in Chapter 2 to experiment with
edge detection, the robot will perform the edge detection task best with
the sensors further apart (the stripboard approach is best for line follow
ing). If the sensors are close together, the robot can have difficulty deter
mining the best angle to turn when an edge is encountered.
See Chapter 3, Building the Two-Wh eeled M obile Platform for de
tails of mounting thes e sens ors on the 2WD chassis and Chapter 4,
Building the Four-Wheeled M obile Platform for the 4WD chassis.
The prin ciples of reflectan ce sens ors are covered in "Infrared Re
flectance Sensors" (page 1 34) in Chapter 8, Tutorial: In troduction
to Sens ors.
147
S ketches Used in This Chapter
-
myRobotEdge Look
(Obstacle H RobotMotor
Library
detection)
myRobotline
��
sensor
added �
... Robot Motor
Library
148
The Look Code
T he Look Code
The code to look for a n obs ta c l e a nd ret urn t r ue if detected is i mplem ented
i n the function nam ed lookFo rObstac le. You saw thi s func tion i n the main ta b
of the sketch descri bed i n Chap ter 6, Testing the Robot's Basic Functions. Beca us e
this c ode wi ll be extended i n this a nd later cha pters to s upp ort a dditiona l
sensors, it makes sense t o extrac t t h i s code into its own tab. Th e downloa d
c ode for a ll sketches i ntrod uced from here on i n ha ve a ta b nam ed Look tha t
c onta i ns the code s hown i n Exam ple 9- 1 .
void lookBeg in ( )
{
i rSensorBegi n ( ) ; / / initialize senso r s
/ / fu nction to check if robot can continue Moving when taking evasive action
// retu rns true if robot is not blocked when Moving to avoid obstacles
/ / this ' placeholde r ' ve r sion always returns true
boolean checkMoveMent ( )
{
return t r u e ;
Chapter 9 149
Edge Detection
called with relevant sensor and this will return true if an object is detected on
that sensor. If no object is detected, the function returns 0BST_N0NE. The look
functionality can be expanded by adding code to the case statement and call
ing appropriate sensor functions, as you will see later in this chapter.
But first, let's use the existing functionality to give the robot the ability to follow
lines and detect edges.
Edge Detection
Edge detection is one of the easier behaviors to understand and program. The
robot moves until it encounters an edge; it should then change direction to
avoid moving over the edge. Edges are detected by using reflectance sensors
(see: Chapter 8, Tutorial: In troduction to Sensors). Typically, the edge is an area
that does not reflect, for example the edge of a table.
In the sketch that follows, the robot will remain within a reflective surface (for
example, a large white sheet of paper) that is bounded by a black line. Black
electrical tape (3/4 inch or wider) works well but a black line of similar width
drawn with magic marker or paint can also work as the 'edge'. To avoid dam
aging your robot, an actual table is not recommended for early experiments
until you are sure you have everything working correctly.
Figure 9 -2 shows how the robot responds to moving over an edge. In panel 1,
the sensors do not detect an edge so the robot moves forward. In panel 2, the
left sensor moves off the reflective surface so the robot stops and rotates 1 20
degrees. In panel 3, the robot completes its rotation; panel 4, shows the robot
moving forward again.
150
Edge Detection
Chapter 9 151
Edge Detection
I ll Setup runs at startup and is u sed config u r e pins and init systeM variables
void setup ( )
{
Seria l . begin ( 9600 ) ;
blinkNuMbe r ( S ) ; II open port while flashing . Needed for Leon ardo only
void loop ( )
{
I l l code for roaMing a round and avoiding obstacles
if( lookForObstacle ( OBST_FRONT_EDGE) == t r u e )
{
Serial . println ( " both sensors detected edge" ) ;
tiMedMove ( MOV_BACK , 300 ) ;
MoveRotate ( 120 ) ;
while ( lookFo rObstacle( OBST_FRONT_EDGE ) == t r ue )
MoveStop( ) ; II stop Moto rs if still ove r cliff
}
else if( lookForObstacle (OBST_LEFT_EDGE ) == t r u e )
{
Serial . println ( " left sensor detected edge" ) ;
tiMedMove ( MOV_BACK, 100 ) ;
MoveRotate ( 30 ) ;
}
else if( lookForObstacle (OBST_R IGHT_EDGE) = = true)
{
Serial . printl n ( " right sensor detected edge" ) ;
tiMedMove ( MOV_BACK, 100 ) ;
MoveRotate( - 30 ) ;
}
else
MoveSetSpeed (MIN_SPEED ) ;
Moveforwa r d ( ) ;
}
}
152
Edge Detection
The code fo r thi s sketch is derive d from the m y Ro botMove ske tch di scussed
i n C hapter 7, Controlling Sp eed and Direction . You ca n downloa d the exam ple
code, loca te m y RobotEdge, open the sketch a nd uploa d it to the robot. Or yo u
ca n de rive the ske tch yourself:
Pla ce the robot with i n the bou nde d su rfa ce a nd swi tch the power o n (the ro bot
calibra tes the sensors afte r i t i s swi tched o n so a l l the se nsors sho ul d be ove r
the reflective a rea). After a sho rt delay the ro bo t wil l move fo rwa rd unti l i t
detects a no n-reflective e dge.
The loop code checks if a n edge i s detecte d di rectly ahea d wi th bo th senso rs
(OBST_FRONT_EDGE), o r o n the left (OBST_LEFT_EDGE) or ri g ht (OBST_RI GHT_EDGE).
If the e dge wa s a hea d, the ro bot backs awa y for 0.3 secon ds, rota tes 1 20 de
g rees a nd then moves fo rwa rd a ga i n. If the e dge wa s to the si de, the robo t
turns 30 deg rees awa y from tha t si de a nd then moves fo rwa rd. Feel free to
experiment with the a ng le s to get a behaviour tha t sui ts the a rea you have
defi ne d fo r conta i ni ng you r ro bo t.
Chapter 9 153
Line Fol lowing
Line Following
L i ne following i s a cla ssic ta sk for a robot. The robot u ses sensor s to det erm ine
its positi on i n relation to a li ne and follow s t hi s li ne by movi ng to keep its
sensors centered above the lin e. Fig ure 9-3 show s a robot m ovi ng a rou nd a
tra ck ma rked with a bla ck li ne on a whi te surfa ce.
154
Line Following
�:�· ·ri
0 ,..
Righi
Drift
Fi g ure 9-5 shows t he robot to the left of the l i ne because the line is curvi n g to
the ri g ht. The left sensor detects maximum reflection (the a n a logRead value is
low). As the center sensor moves towards the e dge of the l i ne, the reflection
i ncreases (decreas i ng the a n a logRead val ue). The rig ht sensor moves towards
the li ne so its rea di ng i ncreases. The drift (the difference between t he left a n d
ri g ht) is positi ve s o the left motor s peeds u p a n d t he ri g ht motor slows down
-the robot turns to the ri g ht.
Chapter 9 155
Line Following
0 "'"'
r
�:�le r ri
Righi
Dnft
Figure 9- 6 shows the robot to the right of the line because the line is curving
to the left. The right sensor detects maximum reflection (the a n a logRead value
is low). The reading from the center sensor increases as it moves towards the
edge of the line. The left sensor moves towards the line so its reading increases.
The drift is negative so the left motor slows down and the right motor speeds
up-the robot turns to the left.
0 1000
�::1., r,
Righi
Drift .,
For the robot to successfully follow a curvy line, the movement must be re
sponsive enough to make sharp turns but not so responsive that it zigs and
zags its way along even straight lines. Tuning the software to get this just right
requires experimentation and patience. The code that follows uses the differ
ence value between the left and right sensors to adjust the differential motor
speed. The preceding figures display the relative signal levels from the sensors
and the difference value is indicated as 'Drift'. Sensitivity is controlled by map
ping the drift value to the actual motor differential speed.
156
Line Following
Example 9-3 shows the line sense code that calculates the drift value (you'll
see it again in a moment when you see the complete listing for the sketch):
The drift and desired speed are passed to the l i.n e Fo ll o w function to drive the
robot. To adjust the motor's sensitivity, drift is divided by a 'damping' factor -
the higher the factor, the less sensitive to drift. Decrease the damping if you
need to make the robot more sensitive, for example, if it is not turning fast
enough to follow sharp bends. Increase the damping if the robot is unneces
sarily zig-zagging on straight lines. The drift value is subtracted from the speed
for the left motor and added to the speed of the right motor to provide a
differential speed proportional to drift. The Arduino c o n s t r a i n function is used
to ensure the values remain within the valid range for speed (0 to 100 %).
Depending on the radius of you r bends, you may not be able to completely
eliminate the zig-zags.
int line Follow(int d rift , int s peed )
{
int leftSpeed con strain ( speed - ( d r ift / daMping ) , 0, 100 ) ;
int rightSpeed con strain ( speed + ( d r ift / daMping ) , 0 , 100 ) ;
Example 9-4. Complete listing for code in the myRobotL ine main tab
/ ******************************************************************************
MyRobotlfoe . ino
Chapter 9 157
Line Fol lowing
#include " robotDefines . h " / / these we re the global defines froM MyRobot
int speed = MIN_SPEED ; // speed in percent when Moving along a straight line
/ / / Setup runs at startup and is used config u re pins and init systeM variables
void setup ( )
{
Seria l . begin ( 9600 ) ;
blinkNuMbe r ( S ) ; // open po r t while flashing . Needed for Leon a rdo only
void loop ( )
{
int d r ift = lineSense( ) ;
linefollow( d r ift , speed ) ;
/ ****************************
Line Sensor code
**************************** /
158
Line Following
The code for this sketch is derived from the myRobotEdge sketch discussed
earlier in this chapter. You can download the example code, locate myRobot
L ine, open the sketch and upload it to the robot. Or you can derive the sketch
yourself:
1 . Open the myRobotEdge sketch in the example code and do a Save As and
name it myRobotline.
2. L ocate the defines for locations of sensors in the robotDefines tab and add
the center sensor following the defines for the left and right sensors: con st
1nt SENSE_IR_CENTER = 2 ; .
3 . Replace the main sketch code with the code listed here: Example 9-4.
4 . Compile and upload the code
Place the robot on the surface with the center sensor above the line and switch
the power on. After a short delay the robot will move forward and track the
line. The robots ability to follow the line depends on many factors:
Chapter 9 159
Seeing Sketch Data
• Robot over sensitive - if the robot follows the line but zig- zags excessively ,
increase the damping value in the line sensor code in the main tab. Try
larger values until you find a range that works. Note that you may need a
different damping value if you change the speed.
• Robot not sensitive enough - if the robot drifts off the line, decrease the
damping value in the line sensor code in the main tab. Try smaller values
until you find a range that works. Note that you may need a different
damping value if you change the speed.
I 88
t===:::::
Left Une ===:J (0-1 0:'.,
b
Center line 1-------------� (0·1 0, 680
Drift
Len Motor
Right Molor
::::===================�=::::
=================�======:::::
(· 1 013•1 0,3) 1 25
(0·1 00)
(0·1 00)
55
68
(0 ·1 024) 0
(0•1 0'4) 0
10 (0•1 0,4) 0
11 (0·1 0,4) 0
12 (0·1 0,4) 0
Here is how the line following sketch should be modified to display the sensor
value:
Add the DataDisplay tab to the sketch (the myRobotlineDisplay sketch in the
example code download ("How to Contact Us" (page xv)) has this tab added
as well as all the other code changes that follow).
160
Seeing Sketch Data
In the main sketch, add constants identifying the list of items to be displayed,
labels for each item, and the minimum and maximum values. Example 9 -5
shows the constants used to produce the display in Figure 9- 7.
cha r * labels [ ] =
{ 11 ", " Left Li.ne " , " Center Li.ne " , "Ri.ght Li.ne " ," D r i. ft " , " Left Speed " , " Ri.ght Speed " } ;
i.nt Mi.nRange [ J
{0 , 0, 0, 0, - 1023 , 0, 0} ;
i.nt MaxRange [ J
{0 , 1023 , 102 3 , 1023 , 1023 , 100 , 100} ;
You can then call the send Data function to send the values you want to display.
Example 9 -7 shows the l i.neSense ( ) function updated to send sensor data.
Chapter 9 161
Seeing Sketch Data
return d r Ht ;
162
Autonomous Movement
This ch apter descri b es how to use a distanc e sens or to en able the rob ot to see
a n d av oi d obstacles as i t m oves a rou nd. The fi rst sketch, nam ed l"lyRobotWan
der, drives the rob ot forward, and if i t detec t s an ob stacle, it stops and rotates
th e rob ot to try and fin d a clear path to m ov e forward. Anoth er sketch, n amed
l"lyRobotScan, adds a serv o that can rotate the sens or s o the rob ot can look left
an d ri g ht with out h avi ng to twist itself around.
Hardware Required
• Ping distance sen sor from Parall ax; see "S onar Distance S ens ors" ( pag e
1 37) in Cha pter 8, Tutorial: Introduction to Sen sors.
• Servo requi red for myR ob otScan; see "S on ar Dist ance Sensors" ( page 1 37)
in Chapter 8, Tutorial: Introduction to Sensors.
C onne ct th e Ping sensor an d servo the ri g h t way a round; the black wires
(g round) go n earest the pin mark ed -, th e whi te (or li ghter col or) si g n al wire
g oes nearest the pin m arke d S (Fi g ure 1 0- 1 ).
-
To
Distance
0
D1qpal i 0 lCi,!_tal I
Sensor 00000000 00000000
AA�d 13 12 11 10 9 8 7 6 5 1 3 2 1 A
□ □ □ 0 0Ml 0S2 0,1 0• 0 0 0 0 0 □ □ □1
To :;; - +5 O Used p,ns�
·- - ·-· • ·---·- .
· · · - - •- - - - - -• �M3 Mi e M2
(0lC
0
Servo '•
2 servos �
Figure 10-1. Ping sensor and servo plug into pins on the motor shield
163
Sketches Used in This Chapter
The Distance tab's code is not listed in this chapter, but it is included in
the examp le code (see "How to Contact Us" (page xv) for information
on downloading the exam ple code).
Fig ure 1 0-2 sh ows the m odul es used i n thi s cha pter.
myRobotScan RobotMotor
Library
164
Mounting a Ping Distance Sensor
Chapter 10 165
Mounting a Ping Distance Sensor
Figure 10-4. Parallax Ping Servo Bracket Figure 10-5. Parallax servo bracket parts
If you prefer to make a bracket, it's easy to do, as the next section explains.
.84"
(21 .3mm) .74"
( 1 8.8mm)
0.1" i
(2.54mm) � !◄
Figure 10-7 shows the a small block of wood cut and drilled.
166
Mount i ng a Ping Distance Sensor
Figure 10-7. Ping sensor with homemade wood mount. Figure 10-8. Rear view of mount; note nuts used as
not fully assembled spacers between PCB and moun t
Fig u re 1 0-9 and Figure 1 0- 1 0 show the mount attached to the robot.
Figure 10-10. Feel free to make your mount in a different size or shape
168
Mount i ng a Ping Distance Sensor
170
Letting the Robot Wander
, , )))
((( I <
3 4 5
Figure 10-13. Ping Sensor fixed in place to look for obstacles ahead
The code to p rovi de this beha viour is i n the sketch named My robotWande r.
Example 1 0-1 shows the main m yRobo tWa nder tab for this sketch.
// Setup runs at startup and is used configure pins a nd init systeM variables
void setup ( )
lookBegin ( ) ;
MOVeBegi n ( ) ;
Chapter 10 171
Letting the Robot Wander
void loop ( )
{
MoveForwa rd ( ) ;
roaM ( ) ; I I look around
This s i mply i ni ti al izes the 'Look' modu le ("Th e Look Code" (pag e 1 49 )) and
'M ove' modu l e ("C ore M ovem ent C ode" (pag e 1 24)) and then cal l s a functi on
named roal'l th at d oes all th e h ard w ork of l ooki ng for obstacl es and moving
to avoi d th em. The roal'l functi on is a dd ed into code i n the Look tab;
Example 1 0-2 replaces th e enti rety of the Look tab code tha t you saw in earl i er
examples.
void lookBegin ( )
{
i rSensorBegin ( ) ; I I initialize senso r s
172
Letting the Robot Wander
}
H( sal'lples > 0 )
distance = cul'le I sal'lple s ;
else
distance = 0;
}
return is Clea r ;
Chapter 10 173
Letting the Robot Wander
voi.d roar1( )
{
i.nt di.sta nce = lookAt ( lookAngles [ DIR_CENTER ] ) ;
i.f( di.stance = = 0 )
{
l'lOVeStop( ) ;
Seri.al . p ri.ntln ( " No front sensor " ) ;
ret u r n ; / / n o sensor
}
else i.f(di.stance <= MIN_DISTANCE)
{
l'lOVeStop( ) ;
//Seri.al . pri.nt ( " Scanni.ng : " ) ;
i.nt leftDi.stance = lookAt( lookAngles [ DIR_LEFT] ) ;
i.f( leftDi.stance > CLEAR_DI STANCE) {
/ / Seri.al . pri.nt ( " r1ovi.ng left : " ) ;
r1oveRotate( - 90 ) ;
}
else {
delay ( 500 ) ;
i. n t ri.gh tDi.stance = lookAt (lookAngles [ D I R_RIGHT] ) ;
i.f( ri.ghtDi.stance > CLEAR_D ISTANCE ) {
// Seri.al . p ri.ntln ( " r1ovi.ng ri.gh t : " ) ;
r1oveRotate ( 90 ) ;
else {
/ / Seri.al . p ri.nt ( " no clearence : " ) ;
di.stance = r1ax( leftDi.stance , ri.ghtDi.stance ) ;
i. f ( d i.stance < CLEAR_DI STANCE/2 ) {
ti.r1edMove( MDV_BAC K , 1000 ) ; / / back up for one second
r1oveRotate( - 180) ; // t u r n around
}
else {
i.f( leftDi.stance > ri.ghtDi.sta nce )
r1oveRotate ( - 90 ) ;
else
r1oveRotate(90 ) ;
}
}
174
Letting the Robot Wander
The roal'l fu nction uses i nfor mat i on reported by the distance se ns or to detect
obstacles. The distance sens or code i s des cribed in "S onar Distance Sens ors"
(page 1 37), the sketches i n this ch apter contai n the code i n a new tab name d
Distance.
The checkMovel'lent fu nction i ntrodu ced i n the previ ous chapter i s enhanced
here to check fo r and return false if there are obstacles in front when the robot
is m ovi ng forward. checkMovel'lent is cal l e d when the robot is taki ng evas i ve
action dur i ng a t i med move. You can add addi ti onal checks i nto thi s fu nction
if needed. For example, if you add sens ors to detect an e dge to the rear of the
robot and added your own code that returne d true when this sens or detecte d
a n e dge, the l og i c shown i n Example 1 0-3 would prevent the rob ot from g oi ng
over an e dge when b acking up to avoi d an obstacle i n front.
Chapter 10 175
Letting the Robot Wander
}
}
return i.s Clea r ;
I n thi s fragm ent, i f the robot is m oving backward a call i s m ade t o lookFo rOb
stacle (wi th a new case you need to add for a rear edg e sensor) th at ch ecks if
an edg e is detected at th at back of th e robot.
The rest of th e L ook code is si milar to th e code descri bed i n C hapter9, Modifying
the Robot to React to Edges and Lines. The lookForObstac le fun cti on has an
addi ti on al case fo r detecting an ob stacle in fron t (OBST_FRONT). This case calls
a n ew functi on nam ed lookAt that i s given the ang le to look tow ards, and
returns th e distance of th e nearest obj ect detected at that angle. That di stance
i s com pared to a mi ni m um allowable di stance and lookFo rObstac le returns
true if the robot is any closer (in oth er words, i t h as detected an obstacle).
The lookAt fun cti on (repeated in Ex am ple 1 0-4 from the previ ous listi ng ) ro
tates the robot to the desired angle usi ng th e r,oveRotate comm and descri bed
in Ch apter 7, Controlling Speed and Direction.
176
Letting t h e Robot Wander
Chapter 10 177
Adding Scanning
3 4 5
The sketch logic is the same, but the Look module has code added to command
a servo to rotate left and right for brief periods. This allows the sensor to look
to see if it can detect an obstacle (see Figure 10- 1 5). If your distance sensor is
not centered, you can add a line in setu p ( ) that will center the servo.
Example 10-6 shows the complete setup function with the servo centering line
added.
lookBegi.n ( ) ;
MoveBegi.n ( ) ;
178
Adding Scann i ng
The call to softSe rvoWri te cen ters the servo an d wai ts for two sec on ds. If your
sen sor i s n ot centere d, follow these steps:
IL JL JL
1 .2ms 1 .5ms 1 .Bms
The servo angle i s c on trolled by a djusting the pulse wi dth on the Ard ui n o pi n
c on n e c te d to the servo. 1 .S m s pul se s wi ll center the servo, a n d i n c rea sing or
dec rea si ng the pulse wi dth will turn the servo one di re c ti on or the other.
The exact relationship between pulse width and servo angle varies
across different servo products. Ifyour servo turns right when it should
turn left, swap the righ t and left servo angles in the servoAng le s array:
Chapter 10 179
Adding Scanning
Arduino has a S ervo li bra ry tha t can control up to 1 2 servos, however this is
not used in this s ketc h for two reasons. The S ervo li brary ena bles you to send
an angle to t he servo and carry on exec uti ng sketch cod e whi le t he servo is
being m oved in the background, but yo ur cod e must wai t un til t he ser vo i s
faci ng the d esired d i rec tion befo re req uesti ng a reading from t h e dista nce
sensor. However, the mai n reason n ot to use the S ervo li brary is becaus e i t
req u i res exclusi ve us e of on e of t he Ard u i n o chi p's hardware tim ers (ti m er 1 )
and tim ers a re i n s hort s upply on a sta ndard Ard uino chi p (see Appendix F,
Arduino Pin an d Tim er Us age ).
The cod e to con trol t he s ervo g oes in a ta b named Softservo (see
Exa m pl e 1 0-7).
i.nt servoPi.n ;
The softSe rvoAttach func tion stores the pin num bertha t the servo i s a ttached
to. The softServoWri. te func tion con verts the d esired angle i nto a pulse wid t h
180
Adding Scan n i ng
The Look code is si m i l a r to the code descri bed at the beg i n n i ng of th i s cha pter,
but here the lookAt fu ncti o n ca l l s softSe rvoW ri. te to rotate the servo i n stead
of rotati n g the entire robot. Exa mple 1 0-8 shows the Look tab used in the
l'lyRobotScan s ketch.
II se rvo defines
con st int sweepSe rvoPin = 9 ; II pin connected to se rvo
con st int servoDelay = 500; II tiMe in MS for servo to Move
con s t int MIN_DI5TANC E = 8 ; II robot stops when object is nearer (in inche s )
con st i n t CLEAR_DISTANC E = 24; II d istance in inches conside red att racive to Move
con s t int MAX_DISTANC E = 150; II the MaxiMUM range of the dista nce sensor
void lookBegin ( )
{
i rSensorBegi n ( ) ; II initia lize senso r s
softServoAttach ( sweepServoPin ) ; I ll attaches t h e servo p i n to t h e servo object
Chapter 10 181
Adding Scanning
}
H ( saMples > 0 )
distance = cuMe / saMple s ;
else
distance = 0;
}
return isClea r ;
182
Adding Scann i ng
else {
if( leftDistance > rightDistance )
l'loveRotate ( - 90) ;
else
l'loveRotate(90 ) ;
}
}
}
}
Chapter 10 183
Add i ng Scanning
184
Remote Control
Hardware Required
• The TV remote control sketch requires an infrared decoder module.
TSOP4 838 (or the equivalent PNA4602 ) modules (Figure 1 1-1 ) have power
and signal pins oriented to enable them to plug directly into the socket
on the motor shield.
You will also need an infrared remote control-almost any controller from
a TV or DVD player will do.
185
Sketches Used in This Chapter
Look
myRobotWanderRemot same as SoftServo
(no Timer)
RobotMotor
myRobotScan library
H ere are the commands u sed i n the remote c ontrol exam ple:
con st cha r MOVE_FORWARD = ' f ' ; II Plove fo rwa rd
'b'
const cha r MOVE_BACK ; II P1ove backward
'C'
con st cha r PIVOT_CCW ; II rotate 90 deg rees CCW
'c'
con st cha r PIVOT_CW ; II rotate 90 deg rees CW
'p';
const cha r PIVOT II rotation a ngle (Plinus rotates CCW)
'h';
const cha r HALT II stop PIOVlng
186
Design of the Remote Control Code
Example 11-1. Remote tab code fo r simple serial remote con trol
II robot reMote coMMands
II T hi.s ve rsion i.s for seri.al coMMands
voi.d reMoteServi.ce ( )
{
i.f( Seri.al . avai.lable ( )
{
i.nt cMd = Seri.al . read ( ) ;
p roces sCoMMand ( cMd ) ;
}
}
Chapter 11 187
Design of the Remote Control Code
This cod e adds a function na med reMoteServi.ce tha t is cal l ed from the mai n
sketch to check i f any remote co mmands ha ve been recei ved. The reMoteSer
vi.ce function will be exand ed la ter in this chapter to s upport oth er remo te
con trol i nputs.
You ma y ha ve noti ced tha t th ere a re two fun ctions nam ed p rocessCoMMand.
The one tha t takes a si n g l e pa ra meter tests if a s econd para meter is requi red
(as in the cas e of the PIVOT com mand) and if so g ets this using the S erial Strea m
parse I n t function.
Exa mpl e 1 1 -2 s hows the mai n sketch cod e from the exam ple, my Robo tS eria l
Remote tha t responds to the s eria l co mmands.
188
Design of the Remote Control Code
II Setup runs at startup and is used configure pins a nd init systeM variables
void setup ( )
{
Seria1 . begi n ( 9600 ) ;
whHe( ! Serial ) ; II only needed for leo n ardo
MOVeBegt n ( ) ;
MoveSetSpeed( MIN_SPEED + 1 0 ) II Run at 10% above MtntMUM s peed
}
void loop( )
II fu nction to check if robot can continue Moving when taking evasive action
II retu rns true if robot ts not blocked when Moving to avoid obstacles
II this ' placeholder ' ve r sion always retu rns true
boolean checkMoveMent ( )
{
return t r u e ;
If you h ave a wireless device th at passes ser i al data such as a Bluetoo th module,
you can wirele ssly con trol th e robot by con n ec ti ng th e serial outpu t of th e
adapter to th e Arduino seri al input an d wi ring up th e power leads. If you a re
using a Leonardo, note tha t th e TX/RX pins ( digi tal 1 an d O) are accessed
through Se ri.a l1 rather th an Se ri.al, so mo dify you r cod e accordingly (you'll
n eed to replac e all i n stances of S erial with Seri al 1 in all th e tab s of your sketch).
Chapter 11 189
Controlling the Robot with a TV Type IR Remote
� 0
�
U1 c_u.tal 1,u
00000000 00000000
�Re f _gn d 1 3 12 1 1 1 0 9 8
01aital I,U
6 5 1 3 2 1 0
�
�
(0XCJ □ □ □ 0 0Mt 520 0S1 0• 0• 0MJ 0M1 0e 0M2 □ □ □
S OUsed pms -
-� - - •- - - - - - �
'• •· - - - - - - - - ·
,
2 servos
2 s tepper 1!!!!!!!!!!11
4 de � o t or
0
v1.2
Left
Motor
Right
Motor
To
Battery
190
Contro l l i ng the Robot with a TV Type I R Remote
If the receiver module does not plug securely into the socket, use a long-nose
pliers to twist the ends of each of the three leads 90 degrees, as shown in
Figure 1 1 -5.
Figure 11-5. /R Receiver Module with leads twisted to for better fit into socket
Chapter 11 191
Contro l l i ng the Robot with a TV Type I R Re mote
If you need h e l p i nsta l l i n g a l i bra ry, see " I n sta l l i n g Thi rd-Pa rty L i b ra ries" (page
83).
You don't need to u n dersta nd how the l i brary works i n order to use it, but if
you a re curious, the followi n g is an ove rview of h ow the l i brary works.
The I R r er1ote l i brary u ses an "i.r recv object to decode the pu lses fro m the IR
Receiver.
decode_results results ;
192
Controlling the Robot with a TV Type IR Remote
con st char P IVOT ' p ' ; // rotation angle (Minus rotates CCW)
con st char HALT ' h ' ; / / stop
void reMoteService ( )
{
if ( i r recv . decode ( & results ) )
{
if ( results . decode_type ! = UNKNOWN )
{
/ /Serial . println ( results . value ) ; / / uncoMMent to see r aw result
conve rti rToCoMMa n d ( results . value ) ;
}
i rrecv . resuMe ( ) ; / / Receive the next value
}
/ / additional s u pport for serial coMMands
i f ( Serial . available ( ) )
{
int cMd = Serial . read ( ) ;
p roces sCoMMan d ( cMd ) ;
{
switc h ( value )
{
case IR_MOVE_LEFT processCoMMa nd( MOVE_LEFT ) ; b reak;
case IR_MOVE_RIGHT processCoMMa nd( MOVE_RIGHT) ; break;
case IR_MOVE_FORWARD processCoMMand( MOVE_FORWARD) ; b reak;
case IR_MOVE_BACK processCoMMand( MOVE_BACK) ; break;
case IR_PIVOT_CCW processCoMMand ( PIVOT_CCW ) ; break;
Chapter 11 193
Controlling the Robot with a TV Type IR Remote
194
Controlling the Robot with a TV Type IR Remote
To u se this cod e with you r rem ote, you need to repl ace th e I R comm ands with
th e o nes your remote controller sends. Fig u re 1 1 -6 shows a typical co ntroller
with a sugg est ed key assig nm ent bu t you can ch oos e any k eys you want.
Chapter 11 195
Controlling the Robot with a TV Type IR Remote
*/
#include < I R reMote . h > / / I R reMote cont rol lib r a r y
long i r KeyCodes [ KEYCOUNT] ; // this will store r aw codes for all keys
char * reMoteKeyNaMe s [ KEYCOUNT] =
{ " Forward " , " Back 1 1 , 11 Left 11 , " Ri g ht " , " Pi.votCW " , " Pi.votCCW 1 , 11 Ha lt " } ;
/ / not used : Slowe r , Faster
void setup ( )
{
Seria l . begin ( 9600 ) ;
while ( ! Se r ial ) ; / / only needed fo r leonardo
void loop( )
{
long key = geti r Keycode(TIMEOUT ) ;
if( key ! = NO_KEY )
{
int index = findKey (key ) ;
if( index ! = NO_KEY )
{
Seria l . p rintln ( reMoteKeyNaMe s [ index ] ) ;
}
}
196
Controlling the Robot with a TV Type IR Remote
}
else conti.nue ;
}
Seri.a l . p ri.ntln( " Done\n " ) ;
flushKeys ( ) ;
Chapter 11 197
Controlling the Robot with a TV Type IR Remote
i. rrecv . resuMe ( ) ;
results . value = · 1 ;
/ / retu rns the i.ndex for the gi.ven key code i. f found
// retu rns NO_KEY i.f code i.s not found
i.nt fi.ndKey( long code )
{
fo r ( i.nt i. = 0; i. < K EYCOUNT ; i.++
{
i.f(i.rKeyCodes [ i. J == cod e )
ret u r n i. ;
}
return NO_KEY;
voi.d pri.ntConstan ts ( )
{
i.nt i. = 0 ;
Seri.al . pri.ntln ( " / / I R reMote keycodes : " ) ;
Seri.al . pri.nt( " const long IR_MOVE_FORWARD = " ) ; Seri.al . p ri.nt ( i. r KeyCode s [ i.++ ] ) ;
Seri.al . pri.ntl n ( " ; " ) ;
Seri.al . pri.nt( " con s t long IR_MOVE_BACK " ) ; Seri.al . p ri.nt (i. rKeyCodes [ i.++ J ) ;
Seri.al . pri.ntln ( " ; " ) ;
Seri.al . pri.nt( " const long IR_MOVE_LEFT It
) ; Seri.al . p ri.nt(i. rKeyCodes [ i.++ J ) ;
Seri.al . pri.ntl n ( ) ; Seri.a l . p ri.ntln( ' Copy the a bove li.nes to the ReMote tab' ) ;
}
198
Contro l l i ng the Robot with a TV Type l R Remote
********** ********************************************************************/
II Setu p runs at startup and is used configure pins a nd init systeM variables
void setup ( )
{
Seria l . begin ( 9600 ) ;
blinkNuMbe r ( S ) ; II open po rt while flashing . Needed for Leonardo only
lookBegi n ( ) ;
MOVeBegi n ( ) ;
reMoteBegi n ( i rReceivePi n ) ; Ill added ReMote tab
void loop( )
{
reMoteService ( ) ;
Chapter 11 199
Enhancing Your Robot A
Planning
T hink Before You Code
It helps to think about you r project and be clear on what you want it to achieve
before you start coding. Tinkering around without a plan is a good way to learn
and to have fun, but it can make a large project too cumbersome to manage.
201
Implementing a Complex Project
Simpl ify
Spending time simplifying code will be repaid in reduced debug time. Complex
code can be difficult to debug or enhance, particularly when you come back
to it after a while. L ooking at each completed function with an eye to seeing
if there is a simpler way of achieving the functionality can result in cleaner code
that is easier to maintain.
202
I m plementing a Complex Project
Experiment
If what you have tried isn't working, try someth ing new. Softwa re problems
may actually be a hardware issue (and vice versa).
Be Tenacious
Interesting projects usually come with difficult problems-overcoming these
is part of the reward for a job well done.
Have Fun
Isn't that why you started this project in the first place?
Appendix A 203
Using Other H ardware with
Your Robot B
You may want to add more capability to you r robot or perhaps substitute dif
ferent hardware than the items covered in the text. This chapter describes how
to use some common alternative components.
205
Alternative Motor Contro llers
These fu nctions convert req u ests to set the motor s peed i nto servo a n g les that
a re written to the continuous rotati on servos. The conve rs ion is performed
using the Ard u i no m a p fu nction.
This code uses the Servo library. Ifyou wan t to build the infrared remote
control project with con tinuous rotation servos, you will need to ensure
that the IRref'lo te library is configured to use a timer other than Timer
1) because the Servo library requires Timer 1. See "Modifying a Library
to Change Timer Allocation" (page 236) for timer usage and details on
how to configure timers for the IRref'lo te library.
con st i n t diffe rential = 0 ; / / % faster left Motor turns coMpa red to right
// tables hold ttMe tn MS to rotate robot 360 deg rees at v a r ious s peeds
// this enables conversion of rotation angle into ttMed Moto r MoveMent
// The s peed s a re percent of Max s peed
// Note : low cost Motors do not have enough torque at low s peeds so
// the robot will not Move below this value
// I nte r polation t s used to get a ttMe fo r any speed froM MIN_SPEED to 100%
206
Alternative Motor Controllers
Appendix B 207
Alternative Motor Contro l lers
con st int MAX_ANGLE 60; II nuMber of degrees that Motor d r iven at Max s peed
con st int se rvoPi n s [ 2 ] {7 , 8 } ; II digital pins con nected to se rvos : ( left , right )
int Moto r5peed [ 2 ] = { 0 , 0 } ; II left and right Motor speeds stored here ( 0 - 100%)
Appendix B 209
Debugging Your Robot
211
Identify the Symptoms and Localize the problem
II ArduinoOataDisplay --
Ardulno Data (COM7)
(0 1 023)
88
680
Right Line ,---� (0--1 0:3) 1 44
Drift ,. , o:J--1 o:? 1 25
Distance <o-1 44) 24
(0 1 024) 0
(0--1 024) 0
(0-1 0,4) 0
(0·1 0,4) 0
10 (0--1 024) 0
11 (0·1 0'4) 0
12 (0-1 024) 0
Figu re C- 1 depicts the an alo gRead values from left, cen te r and right and se n
sors used in lin e detection. The grey numbers i n parentheses on the righ t in
d i c ate the possi bl e ran ge of values, the following number i s the n u meric value
sen t from Ardui no.
The figure shows the values when the robot i s strayi n g sl ightly to the righ t of
a d ar k li ne it is t ryi n g to follow (th e values incre ase when the sensor is over the
l i ne). The Position value goes positive when straying right and negative when
left. The Posi ti on value i s u sed in the line followi n g sketch to adj u st the robot
d i rection so it stays on the l ine. The Distance val ue is in inches and is obtai ned
fro m the pi n g d i stance sen sor.
The Processi n g sketch expects d ata in the following format; field s are separated
by c om mas:
For example, sen d i n g " Data , 2 , 680\ n " will d i spl ay a bar w i th a value of 680 o n
t he second li ne.
You can send l abels for each li ne by sen d i n g a strin g such as: " Labe l , 2 , Center
L lne\ n " , which will tag the second row with the label "Center Line''.
The d at a ran ge c an be sent usi n g a stri n g such as " Range , 5 , 0 , 144\ n " which
wi l l set the ran ge of the fifth li ne from O to 1 44.
212
Identify the Symptoms and Local ize the problem
The ea sies t way to sen d thi s da ta is to a dd the Da ta Di splay ta b to you r ske tch
a nd call the functi ons to form a t a n d sen d the da ta:
• sendDat a ( row , value) ; sends the specified value for di splay on the g i ven
row
• send Label ( row , label ) ; sen ds the specified label for di spla y on th e g i ven
row
sendRange( row , mn1.1'1Ul'1 , 1'1axi.1'1u1'1 ) ; se nds the m i n i m u m a nd ma ximum
values for the specified row
The sketch named l"lyRobotDebug c ontain s the DataDi splay tab and provi de s
a n exa m ple of how to send da ta to the Proce ssi ng. E xa m ple C-1 sh ow s the
main sketch c ode.
***********************************************************/
#include " robotDefines . h " // global defines
cha r * label s [ ) = { " " , " Left Line" , " Center Line " , "Right Line" , " Drift " , " Distance " } ;
int Mtn Range [ J = { 0 , 0, 0, 0 , - 1023 , 0 };
int MaxRange [ ) = { 0 , 1023 , 1023 , 1023 , 1023 , 144} ;
void loop( )
lineSens e ( ) ;
int distance = pingGetDis ta nce ( pingPi n ) ;
sendData ( DATA_DI STANC E , distance ) ; / / send distance
Appendix C 213
I dentify the Symptoms and Loca l ize the problem
/ * * **************************
Line Sensor code
**************************** /
/ / defines for locations of sensors
canst i n t S ENSE_L I NE_LEFT = 0;
canst i n t SENSE_LINE_RIGHT = 1;
canst i n t S ENSE_LINE_CENTER = 2;
return d rift ;
214
Identify the Symptoms and Local ize the problem
The A rdui n o code tha t sen ds the da ta is in the ta b named DataDi.sp lay
(Exam ple C-2), you ca n co py the code into any sketch you wan t to debug, or
yo u can sim ply a dd the ta b to th e sketch.
sendString ( " Range" ) ; sendValue ( row) ; sendValue ( Min ) ; sendValue( Max ) ; Serial . p rtntln ( ) ;
Appendix C 215
I dentify the Symptoms and Loca l ize the problem
int windowWidt h ;
i n t windowHeight;
int g ra phHeight ;
int rectCente r ;
int rectleft ;
int rectRig h t ;
int topMa rgin ;
int bottoMMa rgin;
int leftMa rgin = 50;
int rightMa rgin = 80;
int textHeight ;
float lastMsgTiMe ;
float displayRefreshinte rval = 20; // Min tiMe between screen d raws
void setu p ( ) {
String os=SysteM . getProperty( " os . naMe " ) ;
216
Identify the Symptoms and Local ize the problem
p ri.ntln( os ) ;
i.ni.t(Ol'll'IS( ) ;
fontA = c reateFont ( "Ari.al . nomal " , fontSi.ze) ;
textFont ( fontA) ;
textHei.ght = ( i. n t ) textAscent ( ) ;
for ( i.nt i. = 0 ; i. < = MaxNuMberOfRows ; i.++)
labelli.st . add ( I ntege r . toStri.ng ( i. ) ) ;
adj ustSi.ze ( ) ;
d rawG r i.d ( ) ;
voi.d ad j u stSi.ze ( )
li.ne( rectRi.g h t , topMargi.n + textHei.g h t , rectRi.ght , yPo s ( MaxNuMbe rOfRows )+ 2 ) ; / / ri.ght li.ne
li.ne( rectCenter , topMa rgi.n+textHei.g h t , rectCenter , yPos( MaxNuMbe rOfRows ) + 2 ) ; / / cente r li.ne
Appendix C 217
I dentify the Symptoms and Loca l ize the problem
}
else {
int width=int ( Ma p ( values [ rowlndex ] , rangeMin [ rowl ndex] , rangeMax [ rowl ndex ] , 0 , g raphWidth ) ) ;
rect ( rectleft , yPos( rowl ndex ) - fontSiz e , width , fontSiz e ) ; / / d raw the value
}
fill ( 0 ) ;
text(value s [ rowlndex ] ,
rectRig ht + ( i n t ) textWidth ( " ( - 1000·1000) " ) , yPos ( rowlndex ) ) ; / / print the value
void processMessages ( ) {
while ( true ) {
String Mes sage = coMMsGetMes sage ( ) ;
i f ( Message . length ( ) > 0 )
{
i n t row = 0 ;
String [ ] data = Message . split( " , " ) ; / / Split the CSV Message
if ( data [0 ] . equals ( " Data " ) ) { / / check for data header
row = I ntege r . parselnt( data [ l ] ) ;
values [ row] = Intege r . parselnt( data [ 2 ] ) ;
checkRefresh ( ) ;
else
println ( Message)
218
Identify the Symptoms and Local ize the problem
else
brea k ; / / finish p roces sing when the Message length is 0
void checkRefresh( )
{
if ( lastMsgTiMe < 1 )
lastMsgTiMe = Millis( ) ; / / update the tiMe i f i t was reset b y t h e last dis play refresh
void d r aw( ) {
processMessages ( ) ;
i f ( Millis( ) - lastMsgTiMe > displayRefreshinterval)
{
background ( 255 ) ;
d rawGrid ( ) ;
for ( int i=1 ; i <= MaxNuMberOfRow s ; i++ )
{
d rawBa r ( i ) ;
}
lastMsgHMe = 0 ;
/ ******************************
code for Serial po rt
***************************** /
void initCoMMs ( ) {
String portNaMe = Seria l . list( ) [ po rt!ndex ] ;
p rintln ( Serial . list( ) ) ;
p rintln ( " Connecting to · > " + portNaMe ) ;
MyPort = new Seria l ( this , por tNaMe , 9600 ) ;
String COMMSPortString ( ) {
return " ( " + Serial . li st ( ) [port! ndex] + " ) "
String coMMsGetMessage( )
Appendix C 219
I dentify the Symptoms and Localize the problem
/ / print (Message ) ;
return Message;
}
}
catch ( Exception e ) {
e . printStackTrace ( ) ; / / Display whatever e r ro r we received
}
}
return 11 1 1
;
Thi s sketch tal k s to Ardui no using the serial po rt a n d you need to en sure t hat
the Proce ssing sketch is using the same port t hat is con nected to your robot.
The port Ardui no uses i s dis playe d o n i n the A rduino I D E. You set t he Proce ssing
port by changi n g the value of the vari able portl ndex. When starti ng the Pro
cessing sketch, yo u will see a list of t he ports on your com puter. po rtl ndex i s
the position o f the Ard uino port i n thi s l ist, but note t hat the i ndex sta rts from
0, so t he default va lue of 1 for po rtlndex is for t he second port i n the li st.
A robot tethered via USB i s not very con venient w hen you want to see what
the robot i s doing whi le moving. Addi n g a wi reless serial de vi ce such a s Blue
toot h or XBee can be a big hel p when debuggi n g or tun i n g your robot. If you
a re usi n g a Leonardo, note that the TX/ RX pi ns (di gital 1 a nd O) a re a ccessed
through Seri.a l1 ra ther tha n Seri.al, so mo dify your code a ccordingly (you'll
need to re pla ce a l l insta n ces of Serial with Serial l in a l l the ta bs of your sket ch).
A stan da rd boa rd like the Uno uses t he same Se ri.al obje ct as USB a n d a l
though yo u don't need to modify the exam ple code, yo u w i l l need to discon
nect the wi rele ss de vi ce from the pin s when uploading code. T his is beca use
the wireless device use s the same pi ns (digita l 1 a n d O) a s USB.
221
Monitoring Battery Voltage
R1
= 0 . 109
Therefore the voltage on the terminal will be the battery voltage times
0. 109. For example, 1 0 volts at the battery will be dropped tojust under
the 1. 1 volt range of the in ternal reference.
The resi stors can be atta che d to the ba ttery term inal s as shown i n Fig ure D-2,
but a more permanent solu tio n i s to solder the re si stors to the shield a s shown
i n Fig ure D-3 a nd Fig ure D-4.
222
Monitori ng Battery Voltage
To
Di:�::: .:::::::i::'.iii.&A--;:::::----__iii1oi<1<1(;fl717.o,----ij"u110ii11aai()'li7()u-'
o 0 0 0 () () ) 0 0 0 0 0 0 00
□ □ □ 0e 0Ml 0,2 0Si 0e oe oM3 oMi oe □ □ cr o
SA•f q n d 13 12 11 10 9 8 7 6 5 < l ? 1 �
To Used plns �
Servo - -. - - - - -. - -. .
. . .. - - . - .
Left
Motors
Right
Motors
+5
Gnd
To
Battery
To
Di:�•::: .:::::::i:s.;::..;-.:--:;::::-------1ii1iii<1<
□
1 ;rlll;------ ici
, ii
llai71
o 0 () () i7D------
00 00 0 0 0 0 0 () () 0 0
0
�ef qnd 1 3 12 11 10 9 8 7 6 5 "I 3 i 1- A
To lsed pins -
□□□ 00000 0000
e M l S2 Si e e MJ M• e M
□□□□
Servo 1· · - - - - - - - - - •
0
'• · · - - - - - - - - �
Left
Motors
Right
Motors
+5
Gnd
power 0
IDBI
O D DO
R T J\1 5v ,n
0 0 0 0
To
Battery
Figure D-3. Voltage Divider Resistors soldered to Vin and Gnd pins
Appendix D 223
Monitoring Battery Voltage
Figure D-4. Voltage Divider Resistors soldered to Vin and Gnd pins
/******************************************************************
* LED starts flashing when volage d rops below warning level
* Mark space ratio increses froM 10% to 50% as voltage decreses f roM wa r ning to c r itical
* robot shuts down when battery below critical a nd led flashes SOS
*
* LED Mar k space ratio changes froM 10% to 90% as voltage inc reases to full
***************************************************************** /
224
Monitori ng Battery Voltage
con st int batte ryFull 1500 * 5 ; / / th reshold for battery is low wa rning
con st int batte ryWa rning 1 100 * 5; / / th reshold for battery is low warning
con st int batteryCritical= 1000 * 5; / / threshold to shut down robot
}
else
{
delay( S000 ) ;
}
}
else if (MV < batteryWa rning )
}
delay( 1000 ) ;
Serial . println ( ) ;
int value = 0 ;
fo r ( int i=0; i < 8 ; i++) {
value = value + analogRead ( pin ) ;
}
value = value I 8 ; II get the average of 8 readings
int MV = Map( value , 0 , 1023 , 0 , INTERNAL_REF ERENCE_MV I DIVISOR ) ;
return Mv ;
226
Monitoring Battery Voltage
fla s h ( 60 , pi.n ) ;
for ( i.nt i.=0; i. < 3 ; i.++ )
fla s h ( 20 , pi.n ) ;
There are two versions of the batte ryBegi.n function. Use the one with three
parameters if you have wired up the trickle charger circuit. The three param
eters passed to the function are: the pin that the voltage divider is connected
to, the L ED pin, and the pin that detects the charger plug. Here is the function:
batteryBeg i. n ( alog BatteryPi.n , ledPi. n , ch argerDetectPi.n)
If you have not wired the robot to use a charger, then call batte ryBeg i. n with
two parameters: the pin that the voltage divider is connected to and the L ED
pin:
batte ryBeg i. n ( a logBatteryPi.n , ledPi. n )
The checking is done in the batteryCheck function. This gets the battery level
in millivolts by calling batteryMv and compares this to the warning and critical
thresholds. The L ED is flashed when the level drops below the warning level
with a flash ratio (blink on time to off time) that changes as the voltage drops.
If the voltage drops below the critical level, the robot movement is stopped,
and the L ED flashes a distress signal (SOS in morse code) every 5 seconds. When
this happens, the batteries must be replaced or recharged before the robot
will reactivate.
The l'lyrobotBa tteryMoni.to r example sketch (Example D-2) in the download
shows how to use the battery monitor function.
Appendix D 227
Monitoring Battery Voltage
lookBegi n ( ) ;
MOVeBegin ( ) ;
llbatteryBegin( alogBatteryPin , ledPin ) ;
batte ryBegin ( alogBatteryPin , ledPin , cha rgerDetectedPin) ;
void loop( )
{
I I roaM( ) ;
batte ryCheck ( ) ;
228
Trickle Charging
Trickle Charging
The build chapters i n the begi nni ng of the book de scribed a simple trickle
cha rger that you ca n u se to recha rge NiMH batterie s. Thi s section de scribes
how to use the cha rger a s well a s some i m porta nt poi nt s to ensu re that yo u
d on't damage your batteries.
Trickle cha rg i ng i s a method of rechargi ng N i M H batte ries that provi de s a slow
but stea dy charg i ng cu rrent which shou l d fu lly recharge 5 AA cel ls i n a ro u nd
1 4 to 1 6 ho urs. The cha rger ha s been de signe d for cells with a rated capacity
of 2000 to 2500 mAh (mi l liam pere hou rs). Cells with a higher rating can be
u se d but the y will requ i re a longer cha rg i ng peri o d.
The batterie s sta rt charg i ng when a DC power su ppl y i s plugged i nto the
cha rging socket a nd the power switch i s tu rned on. The cha rging circuit i s
d e signe d fo r u se with a 1 2 volt sup pl y with a 2.1 mm plug ( po sitive o n the
center co nnector) . Cells with the sugge ste d rati ng sho ul d ha ndle the trickle
cha rge cu rrent fo r long periods, however it is good practice to kee p you r cha rge
se ssion to 24 hou rs or l e ss, pa rticula rly if yo ur DC su pply cou ld be deliveri ng a
little m ore than the recom mended 1 2 volt s.
Appendix D 229
Programming Constructs
The code in this book takes advantage of a number of Arduino functions that
are summarized in this appendix. See the on line Arduino reference for each
function if you want more detail.
Digital 1/0
plnMode ( pln , Mode ) ;
Configures a digital pin to read (input) or write (output) a digital value; see
http://arduino.cc/en/Reference/PinMode
dlgltalRead ( pln ) ;
Reads a digital value (HIGH or LOW ) on a pin set for input; see http://ardu
ino. cc/en/Reference/Digita/Read
dlgltalWrlte ( pln , value ) ;
Writes the digital value (HIGH or LOW ) to a pin set for output; see http://
arduino.cc/en/Reference/Digita/Write
pulseln ( pln , pulseType , tlMeout ) ;
Returns the pulse width in microseconds of a changing digital signal on
the given pin. pu lseType (either H IGH or LOW ) determines if duration is
for a high or low pulse. tlMout is an optional value indicating how long to
wait for a pulse (the default is one second); see http://arduino.cc/en/Refer
ence/Pu/seln
231
Analog 1/0
Analog 1/0
analogRead ( pln ) ;
R ea ds a val u e from th e specifi ed a na log pi n. Th e val u e ra ng es from O to
1 023 for volta g es tha t ra ng e from 0 to th e reference voltag e (S volts by
defa ult, b u t ca n be ch ang ed by u si ng a nal ogReference; see http://ardui
no. cclen!Reference/An alo gRe ad
a nalogReference( type ) ;
C onfig u res th e referenc e volta g e used fo r a na log i nput. Thi s i s u sed i n th e
ba ttery m oni tor code di scu ssed i n Appendix D, Power Source s; see http://
arduino.ccle n/Referen ce/An alogReference
Math functions
l'li.n ( x , y ) ;
R eturns th e smaller of two num bers; see http://arduino. cc/en/
Reference/Min
l'lax( x , y ) ;
R eturns th e l arg er of two num bers; see http://arduino. cc!en!Referen ce/Max
constraln ( x , lower , upper ) ;
C onstra i ns th e valu e of x to b e b etween th e lower a nd upper range; see
http:/!arduino.ccle n!Refere nce!Constrain
See http://arduino.cc!en!Reference!M ap
232
Other Fu nctions and Constructs
a r ray
An array i s a collecti on of va riables accesse d using a n index num ber. The
fi rst element of a n Ardui no a rray is accessed usi ng a n i n dex of 0. An array
can be i nitia lized when it is decla red by placi ng values in curly brackets.
The follow i ng decla res an array na med l'loto rSpeed with two elements that
will store the speed for the left a n d right mot ors a nd i nitia lize the speed
va lues to O:
con st int NUMB ER_OF_MOTORS = 2 ;
int MotorSpeed[NUMBER_OF_MOTORS] = { 0 , 0 } ; / / Moto r s peed stored here ( 0 - 100%)
see: http://arduino.cc/en/Reference/Array
#include " header . h "
Th is ma kes functi ons a nd va ria bles declared i n the specified file ava i lable
to your s ketch. See http://arduino.cc/en!Reference!lnc/ude
Append i x E 233
Arduino Pin and Timer
Usage F
The tables in this section show the pin and timer resources used by the projects
in this book. You can use the same pin assignments for the Leonardo boards
or the standard ATmega328 boards such as the Uno. However, there are subtle
low level differences between these boards, so if you are adding capabilities
that use additional pins or resources beyond those described in this book, then
check the documentation on pin and resource usage for your board.
235
Handl ing Resource Conflicts
the Ardui no S ervo library, one or both of th es e librari es will m alfu nction. Th e
solution is to eit her reassi g n one of the librari es to us e a different tim er, or to
fi nd an alternative way to p erform one of the functions without a tim er. Both
of th ese ap pro ach es will be d iscuss ed i n this appendix.
Th efi rst co defrag m ent determ i nes th e tim er to be used with a Leo nardo bo ard
(th e Ardui no bui ld process w i l l use the code in this frag m ent if t h e chip is an
ATl'lega32U4). Th e uncomm ented li ne contai ns: #defi.ne IR_USE_TIMER4_HS
whi ch results in th e library usi ng Ti m er 4. However, Ti m er 4 is also used to
control one of th e motors i n th e 4WD robot. If you h ave th e 4WD robot and
w ant to us e th e i nfrared remote control library, you need to fi nd a free tim er
to use. Yo u can't easily ch ang e th e motor li brary because th e pin fo r Ti m er 4 is
h ard wi red to th e moto r control ler chip. But you can ch ang e th e remote tim er
by com m enti ng out th e l i ne fo r Ti m er 4 and uncomm enti ng a line th at enables
a free ti m er. Th e Leonardo h as 5 timers but as shown i n Table F-2, only Ti m er
1 is avail able. Th e code to dis able Ti m er 4 and enable Ti m er 1 is as follows:
// Leonardo o r Teensy 2 . 0
#elif defined (_AVR_ATMega32U4_)
#define IR_USE_TIMERl // tx = pin 14
// #define IR_US E_TIMER3 // tx = pin 9
// #define IR_US E_TIMER4_HS / / tx = pin 10
Usi ng your text edi tor to m ake and s ave th at ch ang e i n i. rRel'lotelnt . h will
eli m i nate th e conflict by usi ng Ti m er 1 i nstead of Tim er 4.
If your 4WD robot uses an Ardui no Uno, then th e ch ang e is to remove th e / /
com m ent ch aracters before th e I R_USE_ TIMER! l i ne and add th e com m ent
ch aracters before I R_US E_TIMERZ
236
Pin and Timer Tables
Appendix F 237
P i n a n d T i mer Tables
238