Animal motion detection : an Arduino project for photography

Hungry (angry?) pigeon
A real angry bird.

I'm going to talk to you about a simple, yet fun project I did last year : an animal detection device that could control my DSLR and take pictures.

I thought that it would be a fairly simple thing to do with Arduino and a motion sensor. I chose to use an IR sensor because they are very cheap and efficient, and bought the PIR sensor from parallax. It just has a single bit output, so it's super simple to use with an Arduino. It is very sensitive and fits well this application. The only bad thing about it is that it has an incorporated LED that turns red every time a motion is detected, which is probably useful for most use cases, but not in my situation 😀 I just cut the circuit track leading to the LED so it wouldn't turn red anymore.

Motion detection on Arduino
The motion sensor and its 3 pins : The one bit output, VCC, and GND.

Once we have the information about whether  a living thing is in front of the sensor or not, we need to control the camera to trigger it. This part really depends on what kind of camera you own, if it can accept a remote control or not. If it doesn't, one way to trigger it is to use a servo motor to press the shutter button (with the Arduino Servo library), but the problem might be the noise it generates when moving, which could scare the animals. My DSLR ( a  Canon 550D) has a jack input for remote control which makes it really easy to command. What you will need is a standard 2.5mm stereo male jack, some wires and that's it!

Canon Remote Controller Wiring (2.5mm mini-plug and N3 plug)

You just need to solder the 3 wires to the jack connector. One for the ground, one for the focus command, and one for the trigger command. To focus, just put the focus contact to the ground; and it works the same way to take a picture.

So how to control the camera with an Arduino?

We will use two digital ports of the Arduino to control trigger and focus of the camera. When these outputs will be set LOW, they will fire the action they are supposed to create (focus or trigger). When set HIGH, nothing will happen. To protect the camera, you should put a resistor between the outputs and the camera (I used 2.2K resistor) just to make sure no current goes into the DSLR.

The final schematics look like this:

The very simple schematics of the breadboard circuit. The LED is simply there to control if everything is working (on when something is detected). You can click for the full size image.
The very simple schematics of the breadboard circuit. The LED is simply there to control if everything is working (on when something is detected). You can click for the full size image.
Motion detection on Arduino
The real life schematics 🙂

The program will be pretty simple too : if something is detected, take a picture and turn on the control LED 🙂

Here it is:


#include <Camera.h> // The Camera library makes it easier to control a DSLR

/********PINS*********/

int PIR_Pin = 3; //the digital pin connected to the PIR sensor's output
int LED_Pin = 2;
int focusPin=6;
int shutterPin=7;

/********VARIABLES****/

int idletime =0; // The time since last picture
int lastshot=0; // The millis() when the last picture was taken
int burstInterval=5000; //The time between pictures when motion is on
int calibrationTime = 30; // The sensor calibration time (so we don't get false positives when we start the Arduino up)
long unsigned int lowIn;//the time when the sensor outputs a low impulse
long unsigned int pause = 2000;// The time necessary for the motion to be gone after the sensor has gone to a LOW state
boolean lockLow = true; // goes to false when a motion is detected
boolean takeLowTime;
boolean burst=false;// burst mode indicator
Camera* eos; // a pointer to our DSLR

void setup()
{
 eos =new Camera(focusPin,shutterPin);
 Serial.begin(9600);
 pinMode(PIR_Pin, INPUT);
 pinMode(LED_Pin, OUTPUT);
 digitalWrite(PIR_Pin, LOW);

 //Sensor calibration
 Serial.print("Calibrating sensor ");
 for(int i = 0; i < calibrationTime; i++){
 Serial.print(".");
 delay(1000);
 }
 Serial.println("SENSOR READY");
 delay(50);
}

void loop()
{

 if(digitalRead(PIR_Pin) == HIGH){ //If a motion is detected
 if(idletime>30000){ // If the camera is in sleep mode
 (*eos).TriggerFocus(); // wake up the camera
 idletime=0;
 }

 digitalWrite(LED_Pin, HIGH); //signal that a motion is detected
 if (burst){ //Once the motion has been detected and a picture taken, we go into this mode to keep taking pictures every 5s until the motion ends
 delay (burstInterval);
 (*eos).TriggerShutter();
 lastshot=millis();
 idletime=0;
 }
 if(lockLow){
 lockLow = false;// We enter in "motion" mode
 (*eos).TriggerShutter();// We take a picture right away
 delay(1000);
 (*eos).TriggerShutter();// We take a second picture 1s later
 delay(2000);
 lastshot=millis();
 idletime=0;
 burst=true; //Now we go in burst mode,ie picture will be taken every 5S
 }
 takeLowTime = true;
 }
 if(digitalRead(PIR_Pin) == LOW){ //If mothing is detected
 digitalWrite(LED_Pin, LOW); //Turn off the LED
 if(takeLowTime){
 lowIn = millis(); //save the time of the transition from high to LOW
 takeLowTime = false; //make sure this is only done at the start of a LOW phase
 }
 idletime=millis()-lastshot;
 burst=false;

 if(!lockLow && millis() - lowIn > pause){ // If there has been more than 2000ms inactivity, we exit the motion mode
 lockLow = true;
 }
 }

}

The Camera library is included in the project. It is a very simple library that avoids you to code the boring stuff (like setting LOW the trigger output, then HIGH again etc 🙂 )

To host the electronics and the camera, I built a wooden box big enough to put everything in easily, with a lid so It could be weather resistant. Here are the pictures

Motion detection on Arduino
You can see the PIR sensor, and a layer of tape around it. The goal is to make its FOV a bit narrower, so it only fires when the animal is in the camera frame.
Motion detection on Arduino
I used an old remote control from a broken RC helicopter (RIP 🙁 ) to power the Arduino. You can obviously put anything you want in here ( staying in the 7-12V range is recommended )
Motion detection on Arduino
Top view of this masterpiece of engineering.
Motion detection on Arduino
The camera is held here with its tripod mounting hole. You can also see the stereo jack.
Motion detection on Arduino
The lid. The foam layer is there to protect from the rain.
Motion detection on Arduino
The whole thing, with the 550D and the Sigma 10-20mm. The bungee cords can be used to set the device in a tree.

This is obviously far from being perfect, the DSLR shutter noise scaring most of the animals away after the first picture, and the size and weight of this thing making it hard to place anywhere you'd want 😀

On the other hand, it does work pretty well and can take some fun pictures.

Cat eating a pizza

Hungry birds.

Hope this can give little help to those of you looking for ways to photograph animals 🙂

21 thoughts on “Animal motion detection : an Arduino project for photography

    1. Hi michele,
      Thansk for your comment!

      You shouldn't look at the picture I posted, but rather to the schematics. If you don't understand it, feel free to ask your questions here !

  1. Hi there!

    I'm trying to do your project, so first off all, thank you for sharing! 🙂
    I have a question, i guess you could help me.

    In the code is there "Camera* eos;" , it mean i have to writte the name of my camera, instead of "Camera* eos".
    Am I right?

    Regards, Hélder

    (sorry if my english is too bad)

  2. Hi

    thanks for this script and posting your project; its great and I've used it as a baseline to build my own.

    I'm hoping this discussion thread is still active as I have an issue I am hoping to get some feedback on. My motion trigger is working great and the script is running more or less as it should; but for me the problem is that it seems the focus on my Canon 6D stays constantly in the "half pressed" mode or basically active; that is the focus pin must be staying in a "high" state or not going to a constant "low" state after motion is gone for a long enough period.

    The result is that the camera stays active (can hear the focus motor constantly going; and obviously it can not go into a sleep mode either) and the batteries will just drain if I try to leave it for long periods;

    Is this state comparable to others; or do you have suggestions on what parameters i can modify to prevent this constant active focus mode?

    any help is much appreciated!
    thanks!

    1. Hi Ian,

      Thank you for your comment! Have you checked with a multimeter that the Arduino output goes to the right states ? The problem could be rather electrical than in your program.

      1. Hi Alex,

        thanks a lot for the reply. I indeed did check the states of the output with a multi-meter and everything appeared to be going to its proper non-motion state; I've not been able to toy with this lately though so will check again asap....perhaps my camera model has some tweak in its hardware or software that is not behaving as older models have with the wired N3 plug remote shutter system (its a new 6D)...do you think thats possible or have you tried your system on any newer Canon SLR models?

        The remote trigger through the N3 plug seems a pretty standard and simple system though so I doubt that is possible? :-S

        1. Hi Ian,

          That's odd. The only thing that comes to my mind would be a mistake in the pins you used on the N3 plug. A quick search gave me this :" The bottom pin is ground. The other two are focus and shutter -- short one or the other to ground and it's just like pressing the shutter half-way and all the way respectively.". Is it what you did? Have you tried to check the resistance values of on the remote when using it? Maybe the problem comes from the resistor values I suggested. But I doubt it... Let me know!

  3. Hi Alex,

    Thanks once again for your reply and suggestions. I'm not an engineer or programmer for training, so lag behind a bit on some of the technical stuff...but trying to learn 😉 So forgive me if I state the obvious or don't use proper terminology etc...having your input is very much appreciated.
    I've double checked the pin positions, the plug wiring and the resistance values and all seems ok. but it remains to seem stuck in this constant burst/focus mode after the first motion is activated (it continues to release the shutter continuously as it shoudl while motion is activated, but again, the focus stays on constantly.

    it should not be the hardware though because I have tried the following sketch and it seems to all work fine and focus goes to low after motion has stopped. I like the burst mode addition to your sketch though so would love to get it working. Anyway, appreciate your help and thought would share what I found out. here is the sketch that does work fyi:

    boolean focus = true;

    int shutterPin = 3;
    int focusPin = 4;
    int PIRPin = 5;
    int LED_Pin = 13;

    int shutterPressDelay = 200;
    int focusPressDelay = 100;
    int interPictureDelay = 500;

    void setup(){
    pinMode(shutterPin, OUTPUT);
    pinMode(focusPin, OUTPUT);
    pinMode(PIRPin, INPUT);
    pinMode(LED_Pin, OUTPUT);
    }

    void loop(){
    if (digitalRead(PIRPin)) {
    digitalWrite(LED_Pin, HIGH); //signal that a motion is detected
    takePicture();
    delay(interPictureDelay);
    }
    if(digitalRead(PIRPin) == LOW){ //If mothing is detected
    digitalWrite(LED_Pin, LOW); //Turn off the LED
    }
    }

    void takePicture() {
    //If you want the camera to focus first set
    //the focus variable to true.
    if (focus) {
    digitalWrite(focusPin, HIGH);
    delay(focusPressDelay);

    delay(150);
    }
    digitalWrite(shutterPin, HIGH);
    delay(shutterPressDelay);
    digitalWrite(shutterPin, LOW);
    digitalWrite(focusPin, LOW);

    }

    1. So tell me if I'm wrong, but from what you're saying, the camera keeps focusing even though the pins go back to their idle state? Does this happen from the very beginning of the program? If so I think it might be because of the resitor values. I think you should maybe try higher values and see how it goes. I actually also own a 6D now so I will take a look as soon as I can get my hands on a multimeter (might be in 2 weeks).

  4. Ok, I'll look forward to seeing and hearing what you find out and if you come across the same phenomenon with your 6D (they're a nice camera eh).

    RE "does this happen from the very beginning..."
    Yup that is correct; well, the camera keeps in half pressed focus mode; if I had the focus set to the constant motion focus, then yes it will keep focussing; but I have it set at one-time focus setting so if for example i change the view point of the camera it will not refocus, but the camera stays in focus mode so to speak (you can hear the mechanism going and it will not go back to normal idle state or to sleep state. Its really as if the shutter button is always at half pressed. And yes it does this right from the beginning of the routine after the first picture is snapped.

    Thus, perhaps is as you say and is the resistor values. I can also try manipulating these and let you know if that solves it. On the other hand, the script I posted definitely works and the camera does go back to a normal idle state as soon as motion is stopped and the focus pin goes to low; that I can verify as well.

    Hope that helps answer your questions and thanks for investigating this so much! look forward to a version posted to github if you get around to that.

    Cheers!

  5. Hi Alex !

    Thanks for sharring this interesting project !
    I would like to make it too but the link to the camera.h library doesn't seem to work. Could you send me this library or tell me where I could find it ?

    Thanks a lot !

  6. Hi alex

    i can't seem to find the camera library as well.
    if you can give an address to download it from ill be more then happy

    thank you

Leave a Reply

Your email address will not be published. Required fields are marked *