Encoder Front Page
SRS Home | Front Page | Monthly Issue | Index
Search WWW Search seattlerobotics.org

First Steps: Sensing Objects with Pyroelectric Detector

Doug Leppard (DLeppard@CCCI.Org )
Benjamin Leppard (Benjamin@Leppard.Com)

Author’s note:

This is the ninth  in a series of articles outlining the steps I have taken to build my robot. These articles are focused on a robot, named HC12 after its MCU, that may compete in the Fire Fighting contest, be able to roam around the house, but mostly be a fun learning tool. The robot uses a  68HC912B32 processor, so these articles will be about interfacing to the B32 various mechanical devices and sensors using SBasic as the programming language.

Previous articles:

"Setting the Stage for Building a Robot," we set goals for the robot and did research. From the goals and research we will make fundamental decisions on what our robot will be like.

"Choosing the CPU, Language and Basic Shape," using our goals we choose the microprocessor, language and fundamental shape of the robot.

"Motorola’s S-Record" looking at the S-Record format that Motorola uses to load data and programs.

"Booting up the 68HC912B32 for the first time" described in detail how to boot the B32 up and run a program.

"State of the Union" gives an overview of what state the robot was in August 1999.

"Multiplexing Five Sonar Modules" tells why we wired five Polaroid sonar transducers and how to go about doing so.

"Drivers for Sonar & Mapping" shows the software to drive the sonar units, and how it can map a room when tied to a PC.

"Using B32's Interrupts IRQ and XIRQ" using the B32 interrupts to count the robots wheel encoders.

"Telemetry, using a radio modem"  using a radio modem to connect the robot to the PC.

The Heat Is On

As I was building my robot one, the thing I had to have (along with all the other things I had to have) was the pyro heat sensor.  This is a really cool sensor that detects heat, not light.  The pyro sensor detects two sources of heat that are important to my robot project, candles and people.  It ignores most other sources, like windows with sunlight coming through and electric lights.

There are two main heat sensors that the robot hobbyist use, the Hamamatsu UVTron Flame Detector and the Eltec 442-3 Pyroelectric Detector.  Both sensors are supplied by Acroname and other robot suppliers.  The Hamamatsu, which I do own but haven't mounted it yet, is the more sensitive detector.    The robot only needs to go by a open door and a candle can be detected.  But the Hamamatsu is not directional like the Pyroelectric, so it was a higher priority to me to have the pyro sensor.  I wanted this sensor because I just don't want to know that there is a flame, but also if there is a person in the room, and what direction they are located.

I recently built a routine for my robot, using the pyro sensor, where it scans the room and detects all the people in the room.   The pyro sensor tells a person is there and the the sonar unit it tells which person is the closet, then the robot goes to that person.  It a really cool thing to show off.

Pyroelectric Detector

The  Pyroelectric sensor is actually very easy to set up.  Below are the pictures of it mounted on the robot.

robotsidelarge.jpg (68931 bytes)

The Pyroelectric sensor is the white circle between the sonar eyes.  It is mounted in the head which is on the dual servos so it can scan the room for people and candles.  The pyro sensor, in conjunction with the sonar units provide good information to the robot's MCU.   Once a heat signature is spotted, then a ping is sent out from the sonar units and we know a person/candle is so many feet away.

An extra feature of the arrangement of sonars and pyro sensor, that it gives the robot a face to give it a little more personality.

robot_pod_inside.jpg (47225 bytes)

Picture of the robot sensor pod (head).  The pyro sensor is mounted between the left and right sonar "eyes." 

See the specifications of the Eltec 442-3 Pyroelectric DetectorIt is an analog device, and it gives a voltage out according to its readings.  To read the pyro sensor, all you have to do is hook up to your analog to digital converter.

The pyro sensor works by using two built-in parallel sensors and detecting the difference of reading between them.  When one sensor detects a heat signature and the other doesn't, a voltage comparitor built into the chip gives a voltage difference.  If both of the sensors are looking at the heat source, the readings would be the same and you would not get a reading from the pyro sensor.  Therefore, the heat source needs to move in front of the pyro sensor to be detected.  I do this by scanning the object horizontally with the sensor pod (head) of the robot.

Wiring up the pyro sensor

R1-442-3p.gif (1307 bytes) The V+ I hooked up to the 5v MCU supply.  Inside the sensor pod I put a capacitor across the V+ and Ground to keep voltage spikes from the sensor to more consistent readings.  I used a 50mfd capacitor, value is not critical, just one I had laying around.

Pin 2, the output, went into the B32 A to D port, which then would give a reading a digital reading.  A reading of about 128 is read when nothing was detected.  Pin 3, the 2.5 reference, was not used.

Note the sensor should have the tab mounted pointing horizontally.  Use the sensor kit that you can get from Acroname or others.


To understand reading the A to D ports on the 68HC12, read Kevin Ross article "The 68HC12 Analog to Digital Module."  Kevin, as always, goes a great job showing how the A to D ports work.  So I won't even try to explain it.  Instead I will show you my implementation of his work.

All my basic routines are in libraries, the library for this is RAtoD.lib:

Read_AD will read the ports then send back data according to what bit you want.   There is a predefined constant heat_sensor that is the bit the heat sensor is hooked to. Read_AD will allow the reading of all eight input A to D ports, not just the heat sensor.

Heat_stable is a routine called to wait for the sensors to stabilize before taking a reading.  If the sensors have just powered up or have been looking at a heat source, they need to stabilize for a second or two before readings are taken.

For routines that are called below but are not shown here, go to Egroups.com in the SRS area.  The routines are under files, Sbasic and Doug Leppard.  Note that I use temporary variables over a lot to save RAM.   Variables called temp_lib* are only used in library functions and not in the main Sbasic files so that variables will not be accidentally used twice.  You really should use unique names but with only 1kb of RAM. I watch my use of variables closely.

'A/D library

Read_AD: 'use usr(read_AD,X) where X is port number, returns value
    'Multiscan mode, reads all the ports and stores the results
    ' Scan all 8 channels once then stop. The results are
    ' stored in ADR0-ADR7

    ' Set atdctl5 for S8CM and MULT
    pokeb atdctl5, %01010000

    ' Wait for scan to be completed
    do loop while (peek(atdstat) AND $8000) = 0
read_ad2:    'gosub here if you do not want to do a scan but read
    temp_lib=peekb(adr0h + lshft(pick(0)))    'pick(0) has port number
    if debug_on=true
        gosub AD_status,temp_lib,temp_lib2     'pick(0)    'tell of status
drop 1
return temp_lib    'holds value

heat_stable:    'run this to make sure heat sensor has stablized
    wait_lib=intcnt    'timer counter
        temp_lib4=usr(read_AD,heat_sensor)     'look with heat sensor
        if temp_lib5<10    'wait until we have at least 9 readings that are within 118 to 138
        if usr(compare_intcnt,wait_lib)>5000     'don't go longer than 5 seconds
        gosub delay,50
    loop until temp_lib3>9

That is all that is needed to get readings from the pyro sensor.

Finding candles and people

When I was doing my Fire Fighting practice with a candle I used a simple algorithm was basically detected if the reading was 30 different from the base reading, which was usually 128, then something was detected.  This didn't always work.  Also, with every detection you would get two readings, one going high while the scan approached the person and second going low as you left the person.  I didn't always get the most accurate readings this way.

I went upstairs and had a discussion with my son Benjamin who helps me by bouncing off ideas.  I do all the building and almost all the programming of the robot, but Benjamin is the person to help me think through things and get new ideas.  When I showed Benjamin the data he said use a differential of the two readings, the rising and falling readings.  I did this and it gave me a much better detection of objects.

I sent the output of the pyro sensor to a file and put that into an Excel file (CAPTURE heat sensor.xls) and graphed the results.  I ran the readings six times, three with just me and three with Benjamin sitting on the couch and me sitting on the floor.  The readings were surprisingly consistent each time.

The graph below has two lines.  The upper line is the actual readings of the sensor.  The numbers on the X axis is the reading number and since each reading I moved the sensor two degrees you would multiply by two to get the angle.  The Y axis is the reading from the port, which the high reading was 186 and the low was 71.  The first high/low was me sitting on the floor with the sensor scanning directly across my face and the second high/low was Benjamin sitting on the couch more covered with less warm skin showing.  As you can see the pyro first gave a high on each of us then a low as it went away,  The mid-point of the high/low was when both sensors of the pyro were pointing directly at us and cancelled each other out.

Per Benjamin's suggesting, I ran another graph of the difference of the two readings.   I found if I checked 14 degrees apart (7 readings different) I would get the highest differential.  See the lower graph and how it peaks when reached the lower point on the upper graph.  By comparing past readings to current readings it is now even more obvious where the objects are.

In my program I used a heat differential of 50 to say an object was detected.  Also once an object is found I would back it up a few degrees (usually 7) to say that is where center point is.

pyro.jpg (32048 bytes)
Reading the above graph:  The upper line is the actual readings of the pyro sensor.  Where it goes high it is first moving towards the heat source.  Where it goes low, it is moving away from the heat source.   The lower line is the difference of the two readings taken 14 degrees apart.  If there is no heat source the difference is around 0.  Readings are saved and compared 14 degrees apart.  For example, with the upper line if X1 is at reading 37 (74 degrees) and X2 is at reading 44 (88 degrees) with  Y1=186 and Y2=71 then the difference is 115 which is seen on the lower line.

Using pyro sensor in a main program

The routine below is part of a bigger program that scans the room finds the closest person and then the robot moves to him.  This will show you how I implemented what I discussed above.

declare angle_count
declare heat_dif(8)    'keep heat readings 8 readings back
declare closest_angle        'angle that closest person is at
declare closest_distance    'distance of closest person

scan_room:    'scan the room and save distances to objects found in array
    'note when a heat reading is compared to a heat reading 7 readings
    '(14 degrees) back. If this reading drops by 50+ then it must have
    'been a person.
    gosub servo_on
    temp=usr(moveservo,-90,hservo)    'point servo far left
    temp=usr(moveservo,-30,vservo)    'point sensor down so it is not looking at any heat source
    gosub heat_stable    'make sure sensor has stablized
    temp=usr(moveservo,8,vservo)    'tilt up to spot people easier
    gosub delay,temp        'note moveservo returns estimated time to move servo, temp has delay amount in milli-seconds
    ok=false        'ok will say that a person has been spotted
    do             'preload array, put in what an average would be to start comparison
    loop until angle_count>7
    temp2=0    'total number people found
    closest_distance=5000    'set high so next will be selected
        if temp<50    'at at least 50ms or longer if servo needs it, moving 2 degrees about every 50ms
        gosub delay,temp
        heat_dif(angle_count)=usr(read_AD,heat_sensor)     'look with heat sensor
        temp3=angle_count+1    'find which previous reading to look at
        if temp3>7    'if greater has gone around corner
        temp3=heat_dif(temp3)-heat_dif(angle_count)     'find difference
        if temp3>50
            if ok=false     'note if there is still a readinf difference of 50 it must still be same person
                temp2=temp2+1     'person count
                ok=true             'have found person
                temp4=usr(read_sonar,left_eye)/303     'find distance of person just found
                if closest_distance>temp4
                    closest_distance=temp4     'new closest person
                    closest_angle=angle-7     'angle that closest person is at
            ok=false     'no longer spotted peson, so next reading will be another person
        angle_count=angle_count+1     'incriment count for the stored array
        if angle_count>7
    loop until angle>90

In conclusion

The pyroelectric sensor is a great addition for your robot, a definite must.  For what it does it is cheap and is easy to interface to the MCU with analog to digital ports.