DIY motion sensor

I bemused a lot about building a motion sensor, but now I can actually post something useful. Everything I am about to tell you about can be found at my github page, including the Eagle files and Arduino scripts. Here is the finished product (still thinking about making an enclosure):

Motion sensor

Motion sensor + RF transmitter

Components (order from eBay to get really cheap)

The motion sensor is simply a PIR sensor connected to a 434MHz RF transmitter via an encoder. The encoder uses four bits, in the form of resistors tied to HIGH (+VCC) or LOW (GND). That’s enough for 12 sensors. The ATtiny85 is programmed via an Arduino which allows for devising a smart way of sending the RF data. It can be programmed to send the output as randomized timed sequences in order to reduce the conflicts of having other motion sensors on the same band. I also used some code from Alex for running the ATtiny at low power, so it is battery capable:

#include <avr/sleep.h> //Needed for sleep_mode
#include <avr/wdt.h> //Needed to enable/disable watch dog timer

int pinLed = 0;
int irSensor = 2; // (pin 7 on chip)

void setup(){
  pinMode(pinLed,OUTPUT);
  pinMode(irSensor,INPUT);
    //Power down various bits of hardware to lower power usage
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Power down everything, wake up from WDT
  sleep_enable();
}

void loop(){
  ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
  setup_watchdog(5); //Setup watchdog to go off after 1sec
  sleep_mode(); //Go to sleep! Wake up 1sec later and check water

  //Check for water
  ADCSRA |= (1<<ADEN); //Enable ADC
    int val = digitalRead(irSensor);
    while (val == HIGH) {
        digitalWrite(pinLed, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(500);               // wait for a second
      val = digitalRead(irSensor);
    }
      digitalWrite(pinLed, LOW);    // turn the LED off by making the voltage LOW
}

//This runs each time the watch dog wakes us up from sleep
ISR(WDT_vect) {
  //Don't do anything. This is just here so that we wake up.
}

//Sets the watchdog timer to wake us up, but not reset
//0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
//6=1sec, 7=2sec, 8=4sec, 9=8sec
//From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void setup_watchdog(int timerPrescaler) {

  if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings

  byte bb = timerPrescaler & 7;
  if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary

  //This order of commands is important and cannot be combined
  MCUSR &= ~(1<<WDRF); //Clear the watch dog reset
  WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable
  WDTCR = bb; //Set new watchdog timeout value
  WDTCR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int
}

Here is the schematic for the main motion sensor module:

Motion sensor schematic

And the resulting board schematic (after lots of trials to eliminate air-wires):

Motion sensor board schematic

To make the board, I followed the instructions from blondihacks to the tee. The only difference is that I used a etching solution of 4% HCl and 1% H2O2 which etched in about 10min (the vinegar was too slow for me). Here is the finished version:
Finished board
Although this was after some trial and error.

RF Receiver

Components

  • Arduino
  • PT2272 encoder
  • 434 MHz RF receiver

This circuit is even simpler. Connect the RF receiver output to the DIN of the PT2272. Then put each output pin (the four bits) into the Arduino pins 3-6. It’s best to connect the VT (Viable Transmission indicator) pin of the PT2272 to the Pin 2 of the Arduino so that you can attach an interrupt on it. This way whenever VT goes high, the Arduino will read the other four pins and use that to determine which sensor is which (I leave this to you, though). The basic code for this is very simple:

int ledpin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE); //pin 2
  Serial.begin(9600);
}

void loop()
{
  digitalWrite(ledpin, state);
}

void blink()
{
  int a = digitalRead(3);
  int b = digitalRead(4);
  int c = digitalRead(5);
  int d = digitalRead(6);
  Serial.println(String(a) + " " + String(b) + " " + String(c) + " " + String(d) + " ");
  if (a+b+c+d>0){
    state = true;
  } else{
    state = false;
  }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: