Pyroelectric Sensor:

 

This design was provided by Greg Blount please email him with any comments or questions:

I started this project because I thought it would be neat to build a sensor that would allow me to build a robot that would chase our Chihuahua. I saw Henry Chea's implementation of a pyroelectric sensor and thought he had done a great job but was a little set back by the price of the sensor from Eltec. In searching for additional information on pyroelectric sensors I stumbled across the sensor from Glolab and couldn't resist buying one, as the price was just one-tenth the price of the Eltec sensor. I initially thought, out of ignorance, that the sensor I found would work in the circuit Henry Chea used but much to my dismay it would not. I am not an electrical engineer so I asked Glolab for some badly needed assistance. A gentleman by the name of Frank Montegari was extremely helpful when I told him that I needed a circuit that would bring the 20mV output of the sensor up to a more useful level of around 2.5V. I combined the circuit Frank designed, which is the opamp half, and the circuit Henry Chea used on his Eltec sensor to come up with a circuit, which does indeed work with the RCX.

The graph shows the sensor reading logged with no delay between log points. The sensor hovers at around 44.5 when no motion is detected and will spike high then low when motion is detected, the reading will reverse, low then high, when the direction of motion is reversed. The graph shows my hand passing six inches in front of the sensor, left to right then reversing the direction twice. Currently I must drive the RCX with 9 volts or the sensor will not work correctly.

The next graph shows the sensor output when the RCX is powered by 7.2 volts. Substituting the diodes, as Mike Gasperi suggested, with the 1n270's may solve this problem but I haven't had a chance to try them yet. I would enjoy hearing of any enhancements you might make to this circuit.

After prototyping the circuit I wanted to design a package which would be completely enclosed and durable enough to withstand an attack by an aggravated Chihuahua. I discovered that the sensor lens would fit nicely inside a 35mm film container lid with only moderate trimming. The container has enough room for the rest of the components also. I initially tried to put all of the components onto a single board, they fit but it was difficult to work with such limited space. Dividing the components between two boards yielded a workable solution on two fronts, the soldering was much easier and the sensor needed to be centered and located a set distance behind the lens. The distance from the sensor to the lens is controlled by a coil of paper cut to the correct width. Figure "pyro2.jpg" shows the coil inserted into the film container while figure "pyro3.jpg" shows the paper coil, lens, modified lid and the two boards. The board on the right in figure "pyro3.jpg" has the pyroelectric sensor mounted in the center of it. The paper coil simply locates this board behind the lens. To make the boards round I mounted them on a Dremel tool and turned them down with a file, creates a lot of dust but works well. The rest is simply laying out the components and soldering. See figures "pyro4.jpg" and "pyro5.jpg" for close-ups of the boards.

The current sensor's output is rather tricky to write code for. The signal ,when excited, will peak high then low and if you do not move the heat source the signal will eventually return to nominal. However any movement will cause the signal to cycle again. I took the approach of checking the signal, after the initial excitation, where the frequency of the signal says it should be. This approach tends to filter out the effects of the signal oscillation. The included program code drives a mobile, differential drive robot that carries the sensor looking forward. In the sample code, pyro.nqc, the task "peektime" records the amount of time between signal peaks. The last line in this task filters out large timer readings. The task "locker" determines the direction the heat source is moving and, by checking the variable peaktime, can determine if the heat source is still exciting the sensor or not. The subroutine "hunt" is called if no excitation occurs, so if the sensor sees no heat or movement the robot will just spin until it sees a heat source. The sensitivity of the program can be increased by decreasing the variable hyst, doing so will increase the number of false readings also. This is my first attempt at coding for this sensor so it is rough but functional enough to find you or your Chihuahua as the case may be. I feel that the circuit could be enhanced and the code rewritten to accommodate this relatively inexpensive sensor to yield a very enjoyable project.

Pyro.nqc
int freq=3;                 //freq is sensor cycle time or frequency, 
int hyst=44;                //hyst is amount signal varies when excited, lower 
int peaktime=freq,begin,ptemp,dir,lock=0,bumper=0;

task peektime()             //is signal cycling high to low
{
 while(true)
  {
   if (SENSOR_3>45+hyst||SENSOR_3<45-hyst) {begin=Timer(0);}
   ptemp=Timer(0)-begin;
   if (ptemp<freq*2){peaktime=ptemp;}
  }
} 

task locker()              //yes i see something and it came from that way
{
   while (true)
    {
      if (SENSOR_3<45+hyst)
        {while(peaktime<freq){lock=1;dir=1;}}
        lock=0;
      if (SENSOR_3>45-hyst)
        {while(peaktime<freq){lock=1;dir=0;}}
        lock=0;
    }
}

sub hunt()
{
   while (bumper==0)
   {
   if (lock==0&&dir==1){OnFwd(OUT_A);OnRev(OUT_C);}   //Sensor orientation dependent     
   if (lock==0&&dir==0){OnFwd(OUT_C);OnRev(OUT_A);}   //reverse these two as needed
   if (lock==1){Off(OUT_C+OUT_A);PlaySound(0);break;}
   }
}            

task bump()
{
  while (true)
  {
    if (SENSOR_2 < 100)
     {      
       bumper=1;
       OnRev(OUT_A+OUT_C);Wait(75);PlaySound(0);
                                   
       if (Random(1)==1){OnFwd(OUT_A);}
        else {OnFwd(OUT_C);}
        Wait(75);OnFwd(OUT_A+OUT_C);
        bumper=0;
     }    
   }
} 
 
task main()
{
  SetSensor(SENSOR_3,SENSOR_LIGHT);

  SetSensorType(SENSOR_2, SENSOR_TYPE_LIGHT); 
  SetSensorMode(SENSOR_2, SENSOR_MODE_RAW); 

start peektime;  
start locker;
start bump;
OnFwd(OUT_A+OUT_C);
 while (1)
 {while(bumper==0)
  {if (lock==1){OnFwd(OUT_A+OUT_C);}
   else {Off(OUT_A+OUT_C);hunt();}}
 }
}

Click Here to Return to the Main Page