Home‎ > ‎Attiny85 Hacks‎ > ‎

Motion Detector

Background:

     One day recently, i got a call from my sister asking me if i could set up some video surveillance at her house.  She then proceeded to explain how her son is sneaking out at night, and they need a way to catch him.  I figured rather than using a video camera, the purpose is to catch him doing it, 

it was already determined that he was in fact leaving the house at night.  Then came the idea to create a small motion detector, using a PIR sensor, battery pack, a Photo Diode and a Attiny85!  Now i realize you can do this with just discrete components, but i'm trying to build up my knowledge 

with Microcontrollers.  My knowledge extends into a lot of areas but what about programming and micro controllers? Lets put it this way, 30 days ago, i didn't know what an arduino was, i didn't even know what a diode did. So suffice it to say, i am new to it all ! 

Problem:

     Motion outside of a window needs to cause an audible alarm in another part of a house, and be silent during the day.  Solution must be battery powered, easy to install, removable, and have a usable run time inbetween charges.

Solution:

      Use a PIR Motion detector, a Photodiode, and a Attiny85 to detect motion only in the evenings/during the night. Then, sound an audible alarm in the parents bedroom to alert them.

The Build:
   
      To begin the build, i took a trip to my local radio shack to pick up some discrete components i required.  Such as, Photoresistors, PIR Sensor, Batteries, Diodes, Battery Holder, and Buzzer.  I already had a plenty of Attiny85's that i have ordered.  I will list a bill of materials, and sources near 

the end.

     Here is a full schematic of what i used:



**Note -- The PIR Sensor is in the upper left.

Its a pretty basic layout and component list.  If i were to change anything, it would probably be putting a limit resistor between pin 8 and the transistor, in case something fried, but since everything is 5V, even if it did, it shouldn't damage the micro controller.  As a side note, the Transistor is probably

not necessary as i could have just a series resistor to keep the ma draw low, but since i wanted a nice audible tone produced, i let it draw a full ~78mA with a transistor. Also, i thought about changing the

resistor values i used for the LDR, since this is a low current draw device, the 10kohm resistor + the LDR resistance uses up to 200 microamps, which is quite a lot for what it needs to do.  This would require me to re-calibrate the sensitivity settings in my programming, 

and since its a little difficult to do without having serial output set up, i just have decided to keep it the way it is.

So, after working out how i was going to build it, i went ahead and worked up the circuit on a breadboard. you can ignore all the extra wiring at the bottom, it was used for programming.


Okay, so, the circuit is all built, and everything works, awesome!  But what, we have a problem?  Without enabling the sleep functions of the AtTiny85, we get a power usage of 2.5mA WAY to much! :)  So what can we do to take the standby current down?

Well, for me, i got my start by looking into two videos posted by InsideGadgets on youtube.  Here are the links two the videos if you are interested.  He does go over some of the power down settings, but the videos lack some quality, and they are more about the "Watchdog Timer"  Which is

useless in this circuit.



Okay, well if you watched those videos, you will now have a slightly better understanding of what you can do to put the Attiny85 to sleep when you are trying to conserve power.  The main difference between his application, and mine, is that i want to put the Microcontroller to sleep ALL the time,

and only come awake when we receive an pin interrupt from the PIR sensor.  for the purpose of this write up, i will skip through a lot of the datasheet, and cut straight to the code, i tried to explain and comment everything out well enough for you to know whats going on.

This code is written in the Arduino IDE, and uses the libraries from http://hlt.media.mit.edu/wiki/pmwiki.php?n=Main.ArduinoATtiny4585  From the videos, and the examples from the watchdog battery, there was some extra code, and some things that could be optimized, so i included them

in my project.  The main things were the sleep mode set bits do not need to be set up in the setup portion of the sketch, but only need to be called by the sleep function before sleep.  also, in the videos and example, they manually set the outputs to inputs before sleeping, this is not necessary,

as you can set the register bits to do this for you, outlined in my code as "sbi(MCUCR,PUD);"  Which, if you read from Page 38 from the datasheet, you will see this register, and its function and how to use it.

***Begin code:


/*AtTiny85 Motion detecting buzzer with photocell enabler.  --Created by The Hack Skunk Lazerusrm@gmail.com 
  With help from InsideGadgets and Code snippets from Martin Nawrath, nawrath@khm.de @ http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
*/

#include <avr/sleep.h>
#include <avr/wdt.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= -_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int Buzzer = 1;                                       //Buzzer connected to Digital Pin 0 
int Photocell = 2;                                    //Photo Cell Connected to Analog Pin 1
int Pir = 0;                                          //Passive Infra-Red Sensor Connected to Digital Pin 1 
int Photoval = 0;                                     //Interger to hold status of the Photo Cell light value
int Pirval = 0;                                       //Integer to hold status (value) of the PIR
void setup() {
   pinMode(Buzzer,OUTPUT);                            // Enable internal pullup resistors for buzzer output.
 }
 
void system_sleep()
{
  sbi(MCUCR,PUD);                                  //Disables All Internal Pullup Resistors
  sbi(GIMSK,PCIE);                                   //Enable Pin Change Interrupts Interrups
  sbi(PCMSK,PCINT0);                              //Changes Interrupt to PIN1 (PCINT1) 
  cbi(ADCSRA,ADEN);                              //switch Analog to Digital Converter OFF
  cbi(MCUCR,SM0);                                  //Power Down Mode
  sbi(MCUCR,SM1);                                  //Power Down Mode
  sbi(MCUCR,SE);                                    //sleep Mode Power down enable (Sleep_enable(); should set this-- not tested yet)
  sleep_enable();                                      //Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
  sleep_mode();                                       //sleep begins here
  sleep_disable();                                     //Coming out of sleep
  sbi(ADCSRA,ADEN);                             //switch Analog to Digital Converter ON
  cbi(MCUCR,PUD);                                 //Enables Pullup Resistors Again (this should happen anyway, but i have it here for now just in case, haven't fully tested yet)
 }

void loop()
{
  digitalWrite(Buzzer,LOW);
Photoval = analogRead(Photocell);                     //Read the status of the photocell, if it is dark outside, Enable Buzzer output if Motion Deteced by PIR Sensor
Pirval = digitalRead(Pir);                                   //read the status of the PIR, sets the value to HIGH or LOW
if ((Pirval ==HIGH) && Photoval <300)                 //Check status of Photocell, If it is light, Turn outputs off)
{
  digitalWrite(Buzzer,HIGH);
  delay(1000); 
}
system_sleep();                                      //Runs the system_sleep() function
}


*** End code

    Okay, so basically what is happening, is very simple. It goes like this:

1.) Make sure the buzzer is OFF.

2.) Read the value of the LDR / Photoresistor.

3.) Read the status of the PIR Sensor.   

4.) If function -- If the PIR is HIGH (Meaning motion is detected) & The Photoresistor is within the calibrated range (in this case if the ADC is seeing a value less than 300) Then we run the stated functions.

5.) Turn on the buzzer if applicable, and wait a bit.

6.) Enter sleep mode, and wait for an external interrupt to wake the Micro controller back up. (In this case, we have the PIR sensor connected to Digital pin 1, which is also PCINT1)

7.) Loop all.

Now, the hard part in this was figuring out how to the Micro controller to awake out of sleep mode.  Since i have no experience with any of this, it made it even more difficult for me to figure out how to do this. I hardly knew where to begin other than reading the datasheet and examining code.

Basically, when the Attiny is in full Power down mode, only a few things can wake it up.  Either internal interrupts, or a Reset by default.  I wanted to use a pin change interrupt w/ a PIR sensor connected to PCINT1.  So again, referring

to the datasheet, i learned how to do this.  you can read about the registers and the bits to set on Pg 51-53 or so.  Once i had this information, it was merely setting the proper bits before sleeping to enable external interrupts, and then enable interrupts on INT1.


Success!

     After programming, using my multimeter, i observed the current draw at idle. We now sit at a cool 500-600uA ! that is a reduction of nearly 2 Milliamps! Huge!  To calculate my battery lifespan, i used the battery life calculator located at http://oregonembedded.com/batterycalc.htm


*****Update:

     So after initial testing, i decided to design a PCB and lay it all out on that.  So here is the final layout W/ PCB. I designed the circuit in Eagle, and printed using the toner transfer method. I will attach the files at the bottom for you to look at if you're interested. Now i just need a project enclosure, 

and it will get installed today!


Here is the layout of the PCB in EagleCad that i made. I really needed 2 2 pin terminals and one 3 pin, but i only had 3 two pins... so i made it work.





     Here is the finished printed circuit board, with the holes drilled, and some of the parts laid out.








Here is the finished PCB with all the parts populated!  There seems to be an error in the spacing used on the screw terminals, i would have liked them to lock together, but thats okay.




Final Design, minus enclosure.








Conclusion:

This build is probably overcomplicated. The idea was really to implement this with a microcontroller as a educational experiment. In that respect, i consider it a total success regardless!  It works great, and had pretty good range with the PIR on low sensitivity! Overall, i am very happy with this 

project!


Bill of Materials:

1 X PIR Sensor http://www.radioshack.com/product/index.jsp?productId=2906724                   $10.19


1 X Battery Holder http://www.radioshack.com/product/index.jsp?productId=2062242              $2.59



1 X Atmel Attiny85 http://www.sparkfun.com/products/9378                                                   $2.84
  
1 X Breadboard http://www.sparkfun.com/products/7916                                                       $3.95

1 X Jumper Wire Pack http://www.sparkfun.com/products/8431                                            $3.95

1 X Resistor Pack  http://www.sparkfun.com/products/10466                                                 $0.95
                                                                                 

------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                 $34.64


    Obviously, you can source parts from many different places (and perhaps cheaper too!) and also,  I just hate it when people don't list their source or _A_ source, for parts used. It makes it easier if you just post a bill of materials so others can replicate it easy if they want!  The price list does not

include cost to make the PCB or Screw terminal connectors, nor the enclosure. 

Here is the full documents and pictures for download, including EagleCad Drawings, and the Arduino Sketch. to use this sketch on an Attiny85, you will need to turn your arduino programmer into an ISP AVR programmer. you can use this guide:

How To: Arduino ISP Programmer for Attiny45/85 - http://hlt.media.mit.edu/wiki/pmwiki.php?n=Main.ArduinoATtiny4585 

Full information Download: - http://www.mediafire.com/?kjf01go71j0sk02

--The Hack Skunk


Note:  You can buy something like this and it will work dang near the same, in a nice package, just a fair bit larger, and is wireless!  I knew about this before i started, but i wanted the experience of making it myself.



Comments