Maker Advent Calendar Day #7: Monitoring Motion!
Welcome to day seven of your 12 Projects of Codemas Advent Calendar. Today we're going to be using a sensor that detects motion, allowing our Pico to react to things like people and animals when they are near our project.
This is a digital sensor, giving us a HIGH signal if movement is detected. We can code this in a similar way to the buttons from day #3 as a trigger for our program.
Box #7 Contents
In this box you will find:
- 1x Mini PIR Sensor
- 3x Male to male jumper wires
The sensor in your kit is a PIR sensor, which stands for Passive Infra-Red. PIR sensors detect movement via the heat energy (Infra-Red radiation) given off by humans or animals. It won't work on snowmen!
These sensors are commonly used in home alarm systems - if your home has an alarm, have a look in the corners of the ceilings and you may see something similar.
Today we're going to be setting up our motion sensor then testing it by moving our bodies. Then, similar to some of the previous boxes, we'll combine this with other components to create fun little projects including our own little alarm system with a new function to learn!
Construct the Circuit
You know how this starts...unplug your Pico from the USB port on your computer.
Now remove the light sensor parts from yesterday, leaving the LEDs and buzzer in place with the Pico on the main breadboard. Your circuit should look like this to start with:
Now to add your motion sensor. Just to note, the diagrams below also use a generic motion sensor part from Fritzing as there is currently no part for the mini version in your box. The wiring is the same.
Please hold the sensor at the edges of the green PCB when fitting as it is a delicate component!
Important! Sensor Orientation!
The orientation of the PIR pins is very important! Please see the image below with the orientation of the angled pins showing you which side is 3.3V and which is GND (the middle pin is for our GPIO pin):
Now fit your PIR to the top of the mini breadboard in the orientation shown in the image above (with the 3.3V pin to the left) as shown below:
Now connect the three pins to your circuit using the jumper wires:
- Connect the left pin to the 3.3V pin (physical pin 36)
- Connect the right pin to the blue GND lane
- Connect the middle pin to GPIO 26 (physical pin 31)
Your circuit should look like this.
Activity 1: Basic Motion Sensing
Let's get this sensor up and running with a minimal starter program. The code example below uses things we've covered in previous boxes so you should be quite comfortable with how it works.
As always we add our imports, then set up the GPIO pin for the sensor.
We're using a pull down here to ensure the sensor is LOW unless triggered, because we don't want that pin floating between the two (as we covered in day #3).
Something different you'll spot next is where we wait for the sensor to settle or 'warm up' before jumping into our while loop.
This is good practice with PIR sensors, especially if you have a project designed to run as soon as the microcontroller turns on. It gives the sensor a chance to baseline its surroundings before trying to detect changes. Some more advanced sensors even perform initial self-testing which can take a minute or two.
We allow 10 seconds which seems to be enough for this sensor.
Next we use a while loop to check for a HIGH signal on the PIR sensor, which then prints "I SEE YOU", waits 5 seconds, then continues the loop again.
Copy it over to Thonny and give it a whirl. We find that if you sit perfectly still, then wave your hands around, you should be able to test the program without having to leave the room!
# Imports from machine import Pin import time # Set up PIR pin with pull down pir = Pin(26, Pin.IN, Pin.PULL_DOWN) print("Warming up...") time.sleep(10) # Delay to allow the sensor to settle print("Sensor ready!") while True: # Run forever time.sleep(0.01) # Delay to stop unnecessary program speed if pir.value() == 1: # If PIR detects movement print("I SEE YOU!") time.sleep(5) # Wait 5 seconds before looking for more movement print("Sensor active") # Let us know that the sensor is active
Activity 2: Motion Alarm
This is a great project for motion sensors, especially if you have a pesky sibling who keeps "borrowing" things from your room...
We can use our PIR sensor to trigger our buzzer and LEDs, making our unwelcome guests jump and hopefully scare them off!
The example below adds our LEDs and buzzer back in, so we define those pins again ready to be used.
We also don't want you forgetting how to make functions (which we covered on day #5 with the buzzer), so you'll notice that we've made a function called alarm() which we call whenever we want to trigger the LEDs and buzzer. A function wasn't strictly necessary here, but it's good practice!
The function makes our LEDs and buzzer sound/light exactly 5 times, but we're not using a counter this time - instead we're going to introduce the range function...
The range function is really handy when you want to repeat something a certain number of times.
Let's say we wanted to print "Not another function!" twenty times. Well, we could add twenty lines of print, or even run a counter adding +1 each time, but another (nicer/shorter) way to do it is using range - and this is how it would look:
for i in range(20): print("Not another function!")
Don't get hung up on why the 'i' is an 'i' - change it to a 't' or a 'v' and see what happens - it's the same outcome! Traditionally 'i' has always been used so most programmers stick with that. Consider that the 'i' means iteration or index and it starts to make more sense..."for every iteration within the range of 20"...make sense?
We didn't introduce this earlier when we used counters instead, as we think the range function can be a little more intimidating to new coders. You can also add values within the brackets to set the range/steps, but we'll stick to the simplest usage for now.
We turn the buzzer volume up before the range function, and we turn it back down afterwards - notice the placement and indentation of these lines, keeping them outside of the range function. We also have a line at the start of our program to make sure the buzzer is always off before we begin.
OK, now that we understand what range does, copy the code below over to Thonny, run it and sit very still or leave the room for 20 seconds. When you come back in, you should set off the alarm!
# Imports from machine import Pin, PWM import time # Set up the LED pins red = Pin(18, Pin.OUT) amber = Pin(19, Pin.OUT) green = Pin(20, Pin.OUT) # Set up the Buzzer pin as PWM buzzer = PWM(Pin(13)) # Set PWM duty to 0% at program start buzzer.duty_u16(0) # Set up PIR pin with pull down pir = Pin(26, Pin.IN, Pin.PULL_DOWN) # Warm up/settle PIR sensor print("Warming up...") time.sleep(10) # Delay to allow the sensor to settle print("Sensor ready!") def alarm(): # Our alarm function # Set PWM duty (volume up) buzzer.duty_u16(10000) for i in range(5): # Run this 5 times buzzer.freq(5000) # Higher pitch red.value(1) # Red ON amber.value(1) # Amber ON green.value(1) # Green ON time.sleep(1) buzzer.freq(500) # Lower pitch red.value(0) # Red OFF amber.value(0) # Amber OFF green.value(0) # Green OFF time.sleep(1) # Set PWM duty (volume off) buzzer.duty_u16(0) while True: # Run forever time.sleep(0.01) # Delay to stop unnecessary program speed if pir.value() == 1: # If PIR detects movement print("I SEE YOU!") alarm() # Call our function print("Sensor active") # Let us know that the sensor is active again
Day #7 Complete!
That last activity included a lot of detail so we're going to leave it there for today and not overload your fresh coder brains!
The PIR sensor can be so much fun to use and they come in all different shapes and sizes too, you'll be making your own home security system in no time.
So what did we cover on day #7? Today you have:
- Built a circuit with a PIR sensor
- Learnt how to use a PIR sensor with MicroPython and the Pico
- Created a mini alarm system!
- Learnt about the range function
- Revisited functions
As always, keep your circuit safe somewhere until tomorrow (don't take anything apart just yet) and we'll see you after breakfast!