something. Not complex, but in my
demonstrations kids will find plenty of things
to put in its way!
There isn’t much to the Avoid FSM. It
looks at an IR proximity detector and “does
something” if it sees anything. The
movements are simple: “turn left,” “turn
right,” and “back away to the right” for
some set time.
The Edge Detection FSM is more
elaborate. If it sees the table edge, it will
back up and turn about 90 degrees or so
away before being happy.
How To Code
Figure 3. Avoid FSM.
two motors. Let’s say we want to have three behaviors
operating at different priority levels:
• Wander (so we look curious)
To this, we need to add a routine to feed the motors
and time what they are doing so that we can go forward,
reverse, and turn.
Let’s look at our top level FSM (Figure 1) to see how
things are organized. I’ll admit this doesn’t look too
impressive, but let’s expand our scope and look at the FSMs
for each of these “behaviors.” Figure 2, Figure 3, and
Figure 4 show the state machine breakdown of each of the
The Wander FSM is really simple; just pick a direction
and go that way – typically straight ahead until it “sees”
Figure 4. Edge detection FSM.
The code is remarkably simple to handle
multiple FSMs. To work with several
behaviors, the key is to assign each of them a priority. If
they don’t each have distinct priorities, it will not be
possible to determine which one will be active and have
control of the motors. I supplied my behaviors in their
respective priorities: Wander is the lowest and Edge Detect
is the highest.
To make this robot, I used the venerable Microchip
PIC16F84 microcontroller. I had a few lying around when I
went scrounging. These days, there are a LOT of micros
with more capability, but this project was simple. I used
the PIC and a 754419 one Amp H-bridge to drive the
motors. My sensors were an IRPD board that I developed
a long time ago that gives indications of left/right/center
as outputs, and finally a Sharp GP2Y0D340K fixed
distance IR detector to look down and a bit forward at
the table. The source code and comments in the Init()
function show where things are connected. This is a very
I used the CCS PCM compiler for mid-range PICs to
write this program. It is simple and does a nice job of
abstracting the hardware interface for those new to
programming by supplying good hardware setup
functions that take away some of the guesswork folks
run up against when writing embedded programs.
Listing 1 shows how I assigned priorities and how I
implemented my motor control system as an Interrupt
Service Routine (ISR).
The interrupt is designed to fire every 32 µs and
to count down 16 before starting again. This
simulates a 2 kHz PWM to the motors that has 16
settings. This is plenty for the speeds Slow, Medium,
and Fast. The behaviors set the sleft and sright values
used by the motor PWM interrupt service routine.
Those routines that set the motor direction and
duration use a primitive timing that simply decrements
the dur variable. The PIC16F84 is running at 4 MHz
since the PIC has a four-stage instruction pipeline this
means that the effective clock speed is only 1 MHz —
14 SERVO 12.2010