Jump to content
Sign in to follow this  
paradug

Motion Detection Wildlife Camera

Recommended Posts

The project that I would like to submit to the November contest is a Motion Detection Wildlife Camera. It uses a re-purposed PIR sensor module from an air freshener to provide motion detection, an inexpensive key chain camera to capture images, and a TI msp430g2211 microprocessor from the Launchpad kit to provide the necessary brains.

 

Cheap-Motion-Detection-Wildlife-Camera.jpg

 

The project is described in depth at http://www.instructables.com/id/Cheap-Motion-Detection-Wildlife-Camera/

This link includes the code and schematic for the project.

 

An overview of the schematic is shown below:

 

The-Circuit.jpg

Share this post


Link to post
Share on other sites

Nice job, paradug! A great mash-up of hackable items!

 

You should probably post the code here as well, since it's in the contest requirements. ;)

 

I might like to make a similar project some time. Do you get many false triggers? What's the range for small animals like squirrels? Dogs? Deer? People?

Share this post


Link to post
Share on other sites
You have to be careful about what type of feeder you are monitoring with birds or you will have lots of pictures of a feeder swinging in the wind. LOL

Now that you say it...

 

You should probably post the code here as well, since it's in the contest requirements. ;)

 

I would agree with GeekDoc on this. This will keep everything in one place.

Share this post


Link to post
Share on other sites

Here is the code for the Motion Detection Wildlife Camera.

 

/**********************************************
Motion Detection Wildlife Camera
PIR Activated Keychain Camera
Copyright: Doug Paradis - 2010
All rights reserved
This code may be used for private use, as long
as, copyright notice retained.
Acknowledgements: Some code based on TI App note
SLAA335 authored by Mike Mitchell
P1.3 (input - pin 5) --> PIR signal (low = motion)
P1.4 (output - pin 6) --> Shutter switch
P1.5 (output - pin 7) -->  Mode switch
compiled using IAR Embedded Workbench
**********************************************/
#include  "msp430.h"
unsigned char shot_cnt = 60;            // num of shots available
unsigned long int cntr_val = 120000;          // 120000 ~= 1 sec
unsigned int vlo_counts = 0;            // # of VLO clocks in 1 Mhz
unsigned char band_flg = 0;             // flg indicating timing PIR
unsigned char trip_flg = 0;   // flag to monitor if PIR signal is'nt long enough

// Function protos                   
unsigned int cal_VLO(void);
void take_photo(void);
void interval_delay(int delay_time, char wait_flg);
void chg_mode_to_compressed(void);
void turn_off(void);
void turn_on(void);
void main(void)
{
 WDTCTL = WDTPW + WDTHOLD;              // Stop watchdog timer

// Ports
 P1SEL = 0;                               // all p1 pins i/o                                                     
 P1SEL |= BIT0;                           // pin P1.0 selected as ACLK
 P1DIR |= 0xf7;                           // all p1 pins output except p1.3
 P2SEL = 0;                               // necessary for p2
 P2DIR |= BIT6 + BIT7;                    // all p2 pins output
 P1OUT &= ~(BIT4) + ~(BIT5);              // p1.4 and p1.5 output low
 P2OUT |= BIT6 + BIT7;                    // all p2 pins high

// Clocks  --  Setup DCO and VLO
 BCSCTL1 = CALBC1_1MHZ;                // Use 1Mhz cal data for DCO
 DCOCTL = CALDCO_1MHZ;                 // Use 1Mhz cal data for DCO
 BCSCTL3 = LFXT1S_2;                   // Use VLO for ACLK

// VLO calc
 vlo_counts = cal_VLO();               // # of VLO clocks in 1 MHz

// chg mode to compressed HR 
 chg_mode_to_compressed();   

// 30 sec startup delay
 interval_delay(30,1);           // 30 sec delay before allowing 1st photo
 TACCTL0 &= ~CCIFG;              // Clear CCIFG  

// turn on p1 interrupts    
 P1IE |= BIT3;                // Enable p1 interrupt for p1.3  
 P1IES |= BIT3;               // Interrupt edge select, high-low (falling edge)
 P1IFG = 0;                   // clear p1 interrrupts

 _BIS_SR(LPM3_bits + GIE);    // Enter LPM3 with interrupts enabled

}
/*************** subroutines ***************/
// delay_time = len of delay, wait_flg = wait for interrupt or not
void interval_delay(int delay_time, char wait_flg)
{
 unsigned int sec_int;                       
 signed long temp = delay_time * cntr_val;     
 // TimerA setup 
 TACTL = TASSEL_1 + ID_3 + TACLR;              // TA = ACLK, divide by 8
 TACCTL0 = CCIE;                              // Enable CCR0 interrupt

 // Divide 1 Mhz by counts to get # of VLO counts in period
 sec_int = 0;
 do {
   temp -= vlo_counts;
   sec_int++;
 } while (temp > 0);
 TACCR0 = sec_int;                     // TACCR0 period for delay

 // Start timer
 TACTL |= MC_1;                        // Up mode

 // wait for timer or not
 if (wait_flg == 1)
 {
   while ((TACCTL0 & CCIFG) == 0);       // Wait for next capture
 }

}

unsigned int cal_VLO (void)
{
 unsigned int first_cap, vlo_counts;
 BCSCTL1 |= DIVA_3;                    // Divide ACLK by 8
 TACCTL0 = CM_1 + CCIS_1 + CAP;        // Capture on ACLK
 TACTL = TASSEL_2 + MC_2 + TACLR;      // Start TA, MCLK(DCO), Continuous
 while ((TACCTL0 & CCIFG) == 0);       // Wait until capture
 TACCR0 = 0;                           // Ignore first capture
 TACCTL0 &= ~CCIFG;                    // Clear CCIFG
 while ((TACCTL0 & CCIFG) == 0);       // Wait for next capture
 first_cap = TACCR0;                   // Save first capture
 TACCTL0 &= ~CCIFG;                    // Clear CCIFG
 while ((TACCTL0 & CCIFG) == 0);       // Wait for next capture
 vlo_counts = (TACCR0 - first_cap);    // # of VLO clocks in 1 Mhz

 return vlo_counts;
}

void take_photo (void)
{
 if (shot_cnt > 0)
 { 
   // turn off p1 interrupt
   P1IE &= ~BIT3;                           // Disable p1 interrupt for p1.3
   P1IFG = 0;                               // reset all p1 interrupts
   // turn camera on
   turn_on();
   // take photo
   P1OUT |= BIT4;                           // set p1.4 to one - shutter
   interval_delay(1,1);
   P1OUT &= ~BIT4;
   shot_cnt--;
   // turn camera off
   turn_off();
   // if camera full - go to LPM4
   if (shot_cnt == 0 )
   {
     LPM4;
   } 
   // post photos PIR lockout period
   interval_delay (10,1);                // wait 10 sec
   P1IE |= BIT3;                         // Enable p1 interrupt for p1.3
   P1IFG = 0;                            // reset all p1 interrupts

 }
}

void chg_mode_to_compressed(void)
{
// set mode to compressed high resolution
   // turn off p1 interrupt
   P1IE &= ~BIT3;                       // Disable p1 interrupt for p1.3
   P1IFG = 0;                           // reset all p1 interrupts
   interval_delay(1,1);
   // push mode switch 8 times
   for (int j = 1; j <= 8; j++)       
   {  
     P1OUT |= BIT5;                   // set p1.5 to one - mode switch
     interval_delay(1,1);
     P1OUT &= ~BIT5;                  // set p1.5 to zero
     interval_delay(1,1);
   }
   // push shutter once
   P1OUT |= BIT4;                     // set p1.4 to one - shutter
   interval_delay(1,1);
   P1OUT &= ~BIT4;                    // set p1.4 to zero 
   interval_delay(1,1);
   // turn camera off
   turn_off();
   // PIR lockout period
   interval_delay(15,1);       // 15 sec lockout before next pair of photos
   // turn on p1 interrupt
   P1IE |= BIT3;                      // Enable p1 interrupt for p1.3
   P1IFG = 0;                         // reset all p1 interrupts

}   

void turn_on(void)
{
 cntr_val = 60000;                // 60000 ~= 0.5 sec  
 interval_delay(1,1);
 // hit mode switch once
 P1OUT |= BIT5;                   // set p1.5 to one - mode switch
 interval_delay(1,1);
 P1OUT &= ~BIT5;                  // set p1.5 to zero
 interval_delay(1,1);
 cntr_val = 120000;               // 120000 ~= 1 sec
}

void turn_off(void)
{
 interval_delay(1,1);
 // hit mode switch once
 P1OUT |= BIT5;                   // set p1.5 to one - mode switch
 interval_delay(1,1);
 P1OUT &= ~BIT5;                  // set p1.5 to zero
 // hit shutter switch once
 interval_delay(1,1);
 P1OUT |= BIT4;                   // set p1.4 to one - shutter
 interval_delay(1,1);
 P1OUT &= ~BIT4;                  // set p1.4 to zero 
 interval_delay(1,1);
}

/******************* ISR ********************/
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A0 (void)
{ 
 P1OUT ^= BIT1;                        // toggle p1.1 - troubleshooting
 if (trip_flg == 1) 
 {
   trip_flg = 0;
 }
 // if band time is reached and p1.3 still 0
 else if ((band_flg == 1) & ((P1IN & BIT3) == 0)) 
 {
   band_flg =0;
   take_photo();
 } 

}  

// P1.0 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void port_1 (void)
{
   if (trip_flg == 0)
   {
     band_flg = 1;
     // set band time
     cntr_val = 15000;        // 15000 ~= 0.125 sec  
     interval_delay(1,0);
     cntr_val = 120000;       // 120000 ~= 1 sec
   }
   else 
   {
     trip_flg = 1;
   } 
 P1IFG = 0;              // clear p1 interrupts   

}




Share this post


Link to post
Share on other sites
Nice job, paradug! A great mash-up of hackable items!

 

You should probably post the code here as well, since it's in the contest requirements. ;)

 

I might like to make a similar project some time. Do you get many false triggers? What's the range for small animals like squirrels? Dogs? Deer? People?

 

I have posted the code to the Motion Detection Wildlife Camera project to this topic.

 

The range of the PIR sensor is about 15 to 20 feet for large movements. The code has a sensitivity adjustment that consists of requiring the signal from the PIR to be low for a period of time before the response is considered valid. I have it set at approximately 1/8 of a second. This stops little noise spikes and very slight movements.

 

Since the camera's resolution is only 352 x 288 pixels you want your target to be within 3 to 6 feet to get good images of a squirrel sized object. At this range the PIR can pickup a leaf blowing across its field of view. At longer range (15 to 20 feet) it can pickup a deer or person moving into the sensor's line of sight.

 

What is surprising is how still animals are when they are eating. Watching a squirrel through a window I know he is there for several minutes but I will only have 10 or so pictures. It is because when he eats he moves just enough to pickup the seed. So I get pictures when he comes into view, when he moves to a different area of seeds, when he changes position, and when he leaves the field of view. Most of the time he is just reaching down to the pile and chewing. I may get pictures of him reaching down and chewing, but not consistently. So when baiting with food, it is best to spread it about a little bit so the animal has to move to get it all.

Share this post


Link to post
Share on other sites
What is surprising is how still animals are when they are eating. Watching a squirrel through a window I know he is there for several minutes but I will only have 10 or so pictures. It is because when he eats he moves just enough to pickup the seed. So I get pictures when he comes into view, when he moves to a different area of seeds, when he changes position, and when he leaves the field of view. Most of the time he is just reaching down to the pile and chewing. I may get pictures of him reaching down and chewing, but not consistently. So when baiting with food, it is best to spread it about a little bit so the animal has to move to get it all.

I read this in David Attenborough's voice.

Nice explanation, paradug.

Share this post


Link to post
Share on other sites

What is surprising is how still animals are when they are eating. Watching a squirrel through a window I know he is there for several minutes but I will only have 10 or so pictures. It is because when he eats he moves just enough to pickup the seed. So I get pictures when he comes into view, when he moves to a different area of seeds, when he changes position, and when he leaves the field of view. Most of the time he is just reaching down to the pile and chewing. I may get pictures of him reaching down and chewing, but not consistently. So when baiting with food, it is best to spread it about a little bit so the animal has to move to get it all.

 

Then make it take two or three pictures, spaced out by a second or two, on every valid trigger.

Share this post


Link to post
Share on other sites
Then make it take two or three pictures, spaced out by a second or two, on every valid trigger.

 

I originally had the camera take pairs of pictures spaced by 5 seconds, but I decided that I preferred to have more "events" than sets of photos. It just a matter of preference. The code change is easy. I suspect it depends on how long you plan to leave the camera unintended, the target that you are trying to capture, and the purpose of your shots. For example if you want to know if there are deer going to your location you would be interested in events and you might want to increase the minimum time between shots. If you are looking for cute pictures (what I'm doing) you might want to do sets of photos.

 

Thanks for the comment.

Share this post


Link to post
Share on other sites

...or, if you want to (hypothetically) capture photos of neighborhood kids who keep climbing the fence into your yard... You could (hypothetically) take an old 1.3MP camera you have, make sure the flash is exposed, house this in an unbreakable case, and take sets of photos so you get shots of all the little delinquents! :twisted:

 

(hypothetically)

Share this post


Link to post
Share on other sites

Thank you, paradug, for a great project that stimulated my efforts. I have a fish pond that has been visited by "critters" and reduced my fish population. I wanted to find out who the critters were.

My version of this critter cam is based on an Argus DC3185 I got on ebay. The camera is 3.2 mega pixel with an auto flash. And can use a 512 Meg SD card with computer download.

Instead of the air wick PIR I used a Parallax PIR.

Your code was great and easy to modify.

Changes I had to do for the Argus included

-- removing the mode commands

-- several time delay changes to match the Argus button pushes

-- powering with 3 @ AA instead of built-in AAA batteries for longer life of flash

 

Also changed the interrupts signal I used high=motion mode. And added a pulldown resistor.

 

The most difficult (and still most fragile) part of the effort was soldering the switching transistors to the surface mount on/off switch.

 

Now to see if I can capture some critters :D

Share this post


Link to post
Share on other sites

It took some time to get the camera in right spot and of course, match my "visitor's" schedule. One thing I have learned is that the flash in a small cameras isn't all that powerful and only lights a short range. Early on I got a long shot (very poor lighting) of a raccoon. Here is a much better shot of my visitor last night.

 

post-2631-135135507342_thumb.jpg

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...