Motion Tracking Head Using 4 PIRs, Servo and Arduino Uno

Posted on 05/03/2014 by demej00
Modified on: 13/09/2018
Project
Press to mark as completed
Introduction
This is an automatic import from our previous community platform. Some things can look imperfect.

If you are the original author, please access your User Control Panel and update it.

Updated: Mar 31,2014 - modified program to use PIR only once per HIGH state. I wanted to make a motion tracker originally using sound sensors but that was too much work and I thought using PIRs would be just like programming on and off switches, simpler. This works pretty fair considering it's utter simplicity, not rocket science. I used 4 PIRs (actually 5 but one wiring harness shorted and I was too lazy to fix it), a servo to turn the head (bird), and an arduino uno to do the heavy number crunching ...


Motion Tracking Head Using 4 PIRs, Servo and Arduino Uno

Updated: Mar 31,2014 - modified program to use PIR only once per HIGH state.

I wanted to make a motion tracker originally using sound sensors but that was too much work and I thought using PIRs would be just like programming on and off switches, simpler. This works pretty fair considering it's utter simplicity, not rocket science. I used 4 PIRs (actually 5 but one wiring harness shorted and I was too lazy to fix it), a servo to turn the head (bird), and an arduino uno to do the heavy number crunching (45 lines of code, see below).

I hate to program, too frustrating but I finally broke down and got an Arduino, man what a cinch. The last chip I played with I had to download Java, and Keil Uvision, and a bunch of other stuff and it took me two or three days just to set up the environment. The Arduino I had everything installed and running the Blink program in minutes. Where was Arduino when I was young?

The tracker works well if you are walking normally past the PIR sensors, if you move slowly it gets a little confused sometimes between two adjacent sensors but ends up shaking its head quickly which is definitely bird like. My algorithm couldn't be simpler, cycle through the PIRs and place the servo where a PIR has just gone HIGH. Suppose it could be made more complex, but what for? NOTE: modified on Mar 31,2014 to address this problem by allowing PIR to be used only once after it goes HIGH so that it doesnt jump back and forth between adjacent positions. Works quite nicely now even with 2.5 second response time.

The PIRs have an on cycle time of about 2.5 seconds at its fastest so if one found some quicker PIRs or wanted to play with the hardware then the tracker would have quicker response time but its pretty good as is. Don't use any slower PIRs or it will just sit there longer before responding. Ideally if the PIR would go HIGH at movement and then immediately go LOW even if there was continued movement then response time would be quicker too, I think, not sure how it would behave frankly.

Used 9mm EPP to hold the PIRs, a tea container to support the servo.

After I had begun building I did see a video where someone did something similar (nothing new under the sun) but his algorithm sounded too complex and frankly I feel mine works better.

Here is a closeup of the Uno board. I just wired all the PIRs in parallel and ran them off the 5v from the Uno, plugged the PIR out wires into 3,4,5,6,7 sockets and servo into 9.

Close up shot of the board:

 

 

Here is the code: 

#include <Servo.h>

// author: jim demello feb 2014 //

// modified: Mar 31,2014 - added array to allow PIR to be used only once per HIGH state so it doesnt jump back

//                                    and forth between adjacent PIR servo positions.

boolean pirStatus;

Servo servo1; 

int servangle = 0; // servo angle variable

int pirNo[] = {3,4,5,6,7};          // pir pin numbers

int pirPrevLow[] = {1,1,1,1,1};     // previously low flag set to true

int pirPrevUsed[] = {0,0,0,0,0};   // track if PIR has been used after going HIGH

int pirPos[] = {10,60,100,140,170}; // positions for servo (0-180)

int curPosPir = 0;

int pirPin = 3;   

int ledPin = 13;

 

void setup(){

  Serial.begin(9600);

  servo1.attach(9); 

  for(int i=0;i<4;i++){

  pinMode(pirNo[i], INPUT);

   }

  pinMode(ledPin, OUTPUT);

  delay(10000); // calibrate for about 10 seconds

   }

////////////////////////////

//Main LOOP 

//////////////////

void loop(){

  for(int j=0;j<4;j++){ // for each PIR

     pirPin=pirNo[j];

     pirStatus = digitalRead(pirPin);

     if (pirStatus == HIGH) {

          digitalWrite(ledPin, HIGH);   // turn on led for kicks and to show PIRs are HIGH

          if(pirPrevLow[j])    {  

                if (curPosPir != pirPin && pirPrevUsed[j] == 0) { // if high PIR is different than current position PIR then move to new position

                   servo1.write(pirPos[j]);

                   curPosPir = pirPin; // keep current PIR 

                   pirPrevUsed[j] == 1;

                }

          pirPrevLow[j] = 0; // pir is now not low

          }

      } 

      else {

              digitalWrite(ledPin, LOW);  // turn off the led

              pirPrevLow[j] = 1;   // pir is now low

              pirPrevUsed[j] == 0;

      }

    } // end j number of pirs loop

  }// end infinite loop

 

Suppose I will post this over at the doilie makers website (instructables.com) too.

Head follows movement based on 4 PIR sensors

  • Actuators / output devices: single servo
  • Control method: PIR controlled servo via Arduino
  • CPU: arduino uno
  • Power source: 11.1 3S lipo
  • Programming language: Arduinos C
  • Sensors / input devices: PIR sensor
  • Target environment: maybe Halloween
LikedLike this to see more

Spread the word

Flag this post

Thanks for helping to keep our community civil!


Notify staff privately
It's Spam
This post is an advertisement, or vandalism. It is not useful or relevant to the current topic.

You flagged this as spam. Undo flag.Flag Post