Close

#buildinstructions for hardware: PIR and camera

A project log for Elephant AI

a system to prevent human-elephant conflict by detecting elephants using machine vision, and warning humans and/or repelling elephants

neil-k-sheridanNeil K. Sheridan 09/23/2017 at 18:280 Comments

Let's get started on building this and writing the code! We'll do it in increments. So just check the parts, and skip to near the end if you don't want to bother with that.


1. Parts required for PIR and camera component of system 

-- resistor[?]

-- Panasonic AMN14111 Pir Sensor 10m Long Range - Black (£15.39)

The datasheet for this is here: http://docs-europe.electrocomponents.com/webdocs/0030/0900766b80030a9d.pdf (PDF). 

Rated operating voltage: 3V DC - 6V DC

Consumption current: 300 µA max

Output current: 100 µA

Output voltage: min = vdd -5 ; max = vdd - 0 (so same as operating voltage)

Stability time:  min - 7s; max = 30s

* Need to be aware that whilst AMN14111 has digital output, some of the other AMNx series have analogue outputs. For instance those AMN2x are analogue output. Whilst AMN3x are digital again.

-- Female to female jumper cables x3

-- Raspberry Pi Camera V2 (IR-filtered)

NB. Yes, you might have noticed the PIR I used in the testing photos and videos wasn't the panasonic one! It really doesn't matter for demonstrating how to perform the testing!

2. Testing the PIR with a simple circuit

The following components were used for testing: breadboard, breadboard jumper wire, 300 Ohm resistor, visible wavelength LED, DC power supply (AA batteries summing 6v, in a battery holder with +ve and -ve connecting leads built-in, female to male jumper cables x3. 

You could do it without a breadboard by stripping, and then just coiling the wires around the components I expect! Be careful with the PIRs because one of mine was broken in storage!


First of all inspect the PIR and determine which terminal is used for what!  You can find the designations written on the front. You''ll have to gently remove the plastic lens to see them. There are three male terminals on a PIR: VCC, OUT, GROUND. The VCC takes the +ve voltage for power, whilst the OUT is signal out and will return high (e.g. 3.3V) when the PIR detects infrared (i.e. motion), ground is for ground -ve. There's a tutorial all about PIRs here -> https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/connecting-to-a-pir


That's the sensor in the image above, with the designations of the terminals written at the top. In the image below you can see the plastic lens over the sensor.


In the image below you can see the three male terminals for VCC, OUT, GND (GROUND). You need to connect your female ends of jumper cables to these. For the testing, we are using female to male jumper cables. So the male ends go into the breadboard.


Here's the circuit we need to build for the testing!


Now, once the PIR is connected to the circuit, we need to wait 60 seconds for the PIR to 'stabilize' - the LED might be on or blink for the first few seconds. Wait until it has been off for 60 seconds before putting your hand in front of the PIR for testing. Hopefully it all worked ok!


You can use the yellow trimpots for adjusting sensitivity of the PIR.

3. Connecting the PIR to raspberry Pi and basic code for testing

So now we need to connect the PIR to the Raspberry Pi. We need female to female jumper cables for this. That's if we are not adding a resistor again. If we do depends on the PIR. So, we connect VCC to 5v out pin on raspberry pi. We connect GND to a GND pin (ground). We can connect the OUT to any GPIO (e.g. GPIO4). In the below image, we are connecting the OUT for GPIO4. It's using the adafruit cobbler on a breadboard for ease of testing.

Remember the Raspberry Pi pins aren't marked on the board. The site https://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-header-and-pins/ has pin out diagrams for the Pi 3 Model B, and all the others.

Since you won't be using that in end - here are the connections shown to the actual pins on the raspberry pi. We've got the orange wire to pin 2 (5V out) for connecting to VCC on PIR. The brown wire is to pin 6 (Ground) for connecting the GND on the PIR. The yellow wire is to Pin 7 (GPIO4) input from the OUT on PIR. Pin 7 is on the column of pins closest to center of Raspberry Pi. Pins 6 and 2 are on the column closet to edge of Raspberry Pi. Remember if you are using BOARD numbering method you start counting pins from the end of board closest to the microSD card slot.


Here's some simple code to test the PIR is communicating correctly with the raspberry pi. So with this we'll get 0 printed whilst nothing is detected by the PIR, and 1 when something is detected by the PIR! Don't forget to let your PIR stabilise for 60 seconds first!

import RPi.GPIO as GPIO
import time 
# import GPIO library & time library
GPIO.setmode(GPIO.BOARD)
# set mode as BOARD (vs. BCM) so we use the board numbering system for pins,
# in this case that would make GPIO4 = number 7 on the board (count and see!)
GPIO.setup(7, GPIO.IN)
# set number 7 pin on Raspberry Pi for input from the PIR out 
try:
    while True:
        val = GPIO.input(7)
        # val variable gets either True or False depending if PIR
        # output is giving a voltage to pin 7 or not
        if (val == True):
            print("PIR DETECTED SOMETHING!!!")
        else:
            print("NOTHING HERE!")
            time.sleep(3)
            # wait 3 seconds
except KeyboardInterrupt:
    GPIO.cleanup()
    # clean up GPIOs

4. Test the PIR indoors in conjunction with the camera

So next we are going to use the PIR to trigger the raspberry pi camera. 

First, let's attach the Raspberry Pi Camera Module to the Raspberry Pi and check it works! Connect the flex cable from the camera to the CSI (camera serial interface) on the raspberry pi. It can be a bit fiddly and sometimes pops right out again - push it gently but firmly.


Now we can enter some testing code:

from picamera import PiCamera
from time import sleep
camera = PiCamera()
camera.start_preview()
sleep(10)
camera.stop_preview()

Don't forget to enable the camera is the operating system! You can do that from preferences -> raspberry pi configuration tool using your GUI. Or it can be done from command line with: 

sudo raspi-config

The image acquired from the camera will pop up on your screen when you run the code!

Great! Now let's combine the PIR and the camera in some code.  So when the PIR is triggered we acquire an image and save it to a file: 

import RPi.GPIO as GPIO
import time
from picamera import PiCamera
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.IN)
camera = PiCamera()
# assign PiCamera to our camera variable
counter = 0
# counter to zero
try:
    while True:
    val = GPIO.input(7)
    if (val == True):
    camera.start_preview()
    time.sleep(1)
    camera.capture('/home/pi/image%s.jpg' % counter)
    #capture image and write to file %s being counter so it's not
        #just overwriting the same file again and again
        counter = counter + 1
    camera.stop_preview()
    time.sleep(3)
 else:
    print("NOTHING HERE")
    time.sleep(3)
except KeyboardInterrupt:
    GPIO.cleanup()

 Now you can see what happens when we run this! You can see the imagex.jpg files we got in the directory. And an example of one of the images (the camera was pointing up and I moved a pen over the PIR)

So, in the final version of the elephant detection device, we'll not work with that code. Instead we'll be wanting to take a certain number of images each time the PIR is triggered, then work with those (i.e. send them for classification, notify system users if they are classified as elephants, trigger deter devices), before going back to a loop to wait for the PIR to be triggered again.

That will look a little like this:

import time
import picamera
import datetime
import RPi.GPIO as GPIO

def CheckPIR():
    # dependencies are RPi.GPIO and time
    # returns whats_here with "NOTHING HERE" or "SOMETHING HERE"
    time.sleep(1)
    #don't rush the PIR!
    GPIO.setmode(GPIO.BOARD)
    # set numbering system for GPIO PINs are BOARD
    GPIO.setup(7, GPIO.IN)
    # set up number 7 PIN for input from the PIR
    # need to adjust if you connected PIR to another GPIO PIN
    try:
        val = GPIO.input(7)
        if (val == True):
            PIR_IS = 1
            #PIR returned HIGH to GPIO PIN, so something here!
        if (val == False):
            PIR_IS = 0
            #PIR returned LOW to GPIO PIN, so something here!
            GPIO.cleanup()

    except:
        GPIO.cleanup()

    return PIR_IS
   


PIR = 1
count = 0


while True:
    PIR = 0
    #Now to check the PIR and send what it returns to PIR
    PIR = CheckPIR()
    if PIR == 0:
        print("Nothing has been detected by PIR")
    elif PIR == 1:
        print("Something has been seen! Time to photograph it!")
        i = 0
        with picamera.PiCamera() as camera:
            while i < 5:
                i = i+1
                print(i)
                camera.start_preview()
                time.sleep(1)
                utc_datetime = datetime.datetime.utcnow()
                utc_datetime.strftime("%Y-%m-%d-%H%MZ")
                #get date and time so we can append it to the image filename
                camera.capture('image_'+str(utc_datetime)+'.jpg')
                camera.stop_preview()
                time.sleep(1)
                if i == 5:
                    break
            

GitHub: https://github.com/nksheridan/elephantAI/blob/master/demo_Take_Photo_when_PIR_high.py

So first of all we put our PIR code into a function, checkPIR(). That goes and returns a variable called PIR_IS. This has 0 in it if the PIR doesn't detect anyway, and 1 if it does!

Then we set up a while True loop, so this just keeps on going. The first thing we do that is call our checkPIR() function and put the value it returns (0 or 1) into a variable called PIR.

Next we have an if PIR == 0, so if that's true then we didn't detect anything.

Now we have an if PIR ==1, so if that's true then we did detect something! And we go ahead to capture images. Here we are getting 5 images. So let's assign PiCamera as camera. And set i as 0; i is going to be our counter for the number of images we've taken.

Right! We've got a while i < 5 loop now. So we keep taking images until we get 5 of them! First thing we do in that is increment i with i = i + 1 to keep track of how many images we have.

Then we warm up the camera with camera.start_preview()

Next, we can use utc_datetime to get the date and time. We will append this to the end of our image filename. 

Now we use camera.capture to capture an image and store it as image_dateandtime.jpg

Ok, let's run the code, and we can test it by putting our hand in front of the PIR! Here's the kind of output we get:

5. Testing the PIR and camera indoors with a cat feeding station [not done]

Here we'll go ahead and show how to add a reset button and a safe power-down button. And we'll power the Raspberry Pi from a LiPo battery with the RPI PowerPack V1.1 (specifications here: http://www.raspberrypiwiki.com/index.php/RPI_Lithium_Battery_Expansion_Board_SKU:435230). I was going to add using tensorflow to detect cats too, but I'm probably running out of characters for my log! So I'll do that in another one instead. It's fun if you've cats and dogs in your house and Kaggle had a competition about this too. So everything is easily available: https://www.kaggle.com/c/dogs-vs-cats/data

6. Testing the PIR and camera outdoors [not done]

Here we'll get everything in a waterproof case, and put it outdoors. Hopefully we should spot some birds, more cats, and anything else that moves in your garden/yard. I'll add Twython code so the images can be uploaded to twitter. 

That's about it for the testing iterations of the PIR and camera part of the ElephantAI system. Next it would be builds for various enclosures and the build for the entire ElephantAI detection devices.

It might appear a bit over-simplistic for me to add all these build instructions, including even an LED and PIR circuit with a battery! But people who are deploying the ElephantAI system might not have any experience of electronics at all! So we want to start from the basics and work up with these iterations. 

====

What I'm going to do is add build instructions for using commonly available enclosures for PIR and camera mounting. Such as ModMyPi (£16-£26), the SPi-Box (which is fairly low-cost e.g. £13 on Amazon). Then I'll go through just using a couple of random enclosures and cutting holes in them. In addition, how to go ahead and mount the commonly available enclosures into a waterproof enclosures. Then I'll detail the build instructions for the entire detection device in one enclosure. I'll do this in another log. The whole idea of the elephantAI system is to be flexible, thus utilizing whichever materials are easily available!

 I'm not sure if to offer a 3d printed solution - just because it is going to be more expensive than buying ABS enclosures. For instance, you could go on ebay and find a 200x120x75mm ABS enclosure that is IP65 rated (IP65 is no dust ingress and protected against low pressure water jets from any direction. Limited ingress permitted.) for £6. Then adding grommet seals, plastic eyelets, etc. to any holes you've cut + glue!

======

Discussions