Professional Documents
Culture Documents
http://www.instructables.com/id/Motion-Tracker-with-PIR-Arduino-and-a-Servo/
This is my motion tracking head using four PIRs (Passive InfraRed Sensors), an Arduino Uno
board and a servo.
It is a simple way to give the impression that the head (birdy) is actually following movement.
It is a very easy project to build but a little time consuming to make the wiring harness that
connects the PIRs to the Arduino. I simply wire the PIRs positive and negative wires together
and power them directly off the Arduino 5 volt circuit, plug the signal wires into the Arduino
digital ports 3,4,5 and 6, plug the servo also into the 5 volt and ground ports and it's signal into
the 9 port and run my program which is also fairly simple.
The program cycles through each PIR input via an array and if the PIR goes HIGH then moves
the servo to that PIR's corresponding servo position. I had to add another array to track each PIR
and only allow it to be used once per HIGH state or else it sometimes would jump between
adjacent PIR servo positions - a definitely birdlike movement but not too desirable.
This would be a great Halloween mechanism to track movement with a head.
This is the first project I ever used with an Arduino board and I was surprised how easy it is to
use. It took only minutes to install the software and run the LED Blink program. Hope to use it
for more projects in the future.
The PIRs should have the shortest delay time possible. The minimum delay on this particular
PIR is 2.5 seconds which is how long you would have to wait for the PIR to go LOW before it
can detect new movement. Some more expensive PIRs probably are faster but 2.5 seconds is ok.
Longer time PIRs makes for a more frustrating performance.
More PIRs would also make for a more realisitic movement of the head. Also, one could slow
down movement between PIR positions for more realistic movement by incorporating a delay
subroutine but I like the faster movement myself. With more PIRs is wouldn't be quite so jerky
though.
As per the crudely drawn schematic, solder all the positive PIR wire ends together, solder all the
negative wire ends together. These will be connected to the Arduino 5 volt and grnd ports.
The servo is sitting under the bird mounted in a cardboard tea container. It has 3 wires also, a
positive, negative and signal wire.
The program does two other things. If the a PIR is HIGH and the servo is already at that PIRs
corresponding position, dont move it.
Also, I use another array to track if the PIR has been used since it went HIGH. I only allow it to
be used once for each HIGH state. If you don't do that you get added movement between
adjacent PIRs that is not necessary.
I just turn on the LED whenever a PIR is HIGH so I can tell by looking at the Arduino if there is
some activity in the PIRs.
#include <Servo.h>
// author: jim demello feb 2014 //
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}; // has pir been on used before going low
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
// servo1.write(90); // put servo at center to begin
}
////////////////////////////
//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); //the led visualizes the sensors output pin state
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]);
Serial.println(j);
delay(50);
curPosPir = pirPin; // keep current PIR
pirPrevUsed[j] = 1;
}
pirPrevLow[j] = 0; // pir is now not low
}
}
else {
digitalWrite(ledPin, LOW); //the led visualizes the sensors output pin state
pirPrevLow[j] = 1; // pir is now low
pirPrevUsed[j] = 0;
}
} // end j number of pirs loop
}// end infinite loop