Simple Security System

Jenn Case's picture

Introduction

Who hasn't wanted to monitor what goes on when they aren't there. When I was little, I was always curious about whether or not anyone was going into my room and would have loved a camera monitoring system. It may even be a good idea to have a simple security setup for an apartment.

This tutorial shows how to set up a PIR sensor along with a small TTL camera and an SD card to capture images whenever there is movement in the monitored area.

The necessary libraries are: SoftwareSerial (for the camera) and SDFat (for the SD card).

Parts

  • PIR Sensor
  • TTL Camera by Linksprite
  • SD Card Breakout Board
  • SD Card
  • 2 10k Resistors
  • 3 other Resistors (I'm not sure if size matters, but mine were all above 1k)
  • Wires
  • Arduino

Schematic

Code

Arduino

Below is the code:

/***************************
PIR Motion Detection - Camera Capture

by Jennifer Case
5/21/2013

Parts:
-PIR Sensor
-SD Card Breakout Board
-TTL Camera

Pin 2,3 - Camera
Pin 8 - PIR Sensor
Pin 10 - CS/D3
Pin 11 - CMD
Pin 12 - D0
Pin 13 - CLK
****************************/
#include <SoftwareSerial.h>
#include <SdFat.h>

//SD Card
SdFat sd;
SdFile myFile;
int picCnt = 0;

//Camera
byte incomingbyte;
SoftwareSerial cameraSerial = SoftwareSerial(2, 3);   //Configure pin 2 and 3 as soft serial port
int a=0x0000,j=0,k=0,count=0;   //Read Starting address       
uint8_t MH,ML;
boolean EndFlag=0;

//Declare pins
const int chipSelect = 10;
int pirPin = 8;

void setup() { 
  Serial.begin(19200); //start serial
  cameraSerial.begin(38400); //start serial with camera
  
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();
  
  SendResetCmd(); //allows camera to take pictures
  delay(3000); //delay necessary for camera reset
}

void loop() {
  int val = digitalRead(pirPin); //read from PIR sensor
  
  //when val is HIGH, there is motion -> take pictures
  if (val == HIGH) {
    //create title for images
    char photoTitle[25] = {};
    sprintf(photoTitle, "pic%d.txt", picCnt);
    //Serial.println(photoTitle);
    
    //make sure file can be created, otherwise print error
    if (!myFile.open(photoTitle, O_RDWR | O_CREAT | O_AT_END)) {
      sd.errorHalt("opening photoTitle.txt for write failed");
    }
    
    //Serial.print("Writing to file...");
    
    SendTakePhotoCmd(); //take photo
    delay(200); //delay to make sure there is no drop in the data
    //Serial.println("Start pic"); 
  
    while(cameraSerial.available()>0) {
      incomingbyte=cameraSerial.read(); //clear unneccessary serial from camera
    }
    byte b[32];
    
    while(!EndFlag) {  
      j=0;
      k=0;
      count=0;
      SendReadDataCmd(); //command to get picture from camera
             
      delay(75); //delay necessary for data not to be lost
      while(cameraSerial.available()>0) {
        incomingbyte=cameraSerial.read(); //read serial from camera
        k++;
        if((k>5)&&(j<32)&&(!EndFlag)) {
          b[j]=incomingbyte;
          if((b[j-1]==0xFF)&&(b[j]==0xD9))
          EndFlag=1; //when end of picture appears, stop reading data                          
          j++;
          count++;
        }
      }
              
      for(j=0;j<count;j++) { //store picture into file
        if(b[j]<0x10)
          myFile.print("0");
        myFile.print(b[j], HEX);
      }
      myFile.println();
    }
    
    StopTakePhotoCmd(); //stop this picture so another one can be taken
    EndFlag = 0; // reset flag to allow another picture to be read
    //Serial.println("End of pic");
    
    myFile.close(); //close file
    //Serial.println("done.");
    //Serial.println();
    
    picCnt++; //increment value for next picture
  }
}

//Send Reset command
void SendResetCmd() {
  cameraSerial.write((byte)0x56);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x26);
  cameraSerial.write((byte)0x00);   
}

//Send take picture command
void SendTakePhotoCmd() {
  cameraSerial.write((byte)0x56);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x36);
  cameraSerial.write((byte)0x01);
  cameraSerial.write((byte)0x00);
    
  a = 0x0000; //reset so that another picture can taken
}

void FrameSize() {
  cameraSerial.write((byte)0x56);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x34);
  cameraSerial.write((byte)0x01);
  cameraSerial.write((byte)0x00);  
}

//Read data
void SendReadDataCmd() {
  MH=a/0x100;
  ML=a%0x100;
      
  cameraSerial.write((byte)0x56);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x32);
  cameraSerial.write((byte)0x0c);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x0a);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)MH);
  cameraSerial.write((byte)ML);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x20);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x0a);

  a+=0x20; 
}

void StopTakePhotoCmd() {
  cameraSerial.write((byte)0x56);
  cameraSerial.write((byte)0x00);
  cameraSerial.write((byte)0x36);
  cameraSerial.write((byte)0x01);
  cameraSerial.write((byte)0x03);        
}

This code sets up the SD card, reads from the PIR sensor and then takes pictures while there is motion. Everytime a picture is taken, the name of the file is incremented up.

Python

The Python code from the camera tutorial has been revamped to allow for multiple photos to be processed at a time. This is set up to work with the naming given in the above code. The user may still have to adjust the range depending on the number of photos.

#!/usr/bin/python
# open file
import binascii

count = 0

for count in range (0,4):

    f = open ("PIC%d.txt" % (count),"r")
    nf = open("IMAGE%d.jpg" % (count),"wb")

    #Read whole file into data
    while 1:
        c = f.readline()
        d = c.strip()
        #print (c)
        #print (d)
        if not c:
            break
        nf.write(binascii.a2b_hex(bytes(d, "ascii")))


    # Close the file
    f.close()
    nf.close()

Sample Images

Here are a couple proof of concept images showing that the camera and motion detection works.