How to Make a 4G Enabled Raspberry Pi Zero for Remote Motion Detection - Garages, Sheds Etc
by harrylincoln in Circuits > Raspberry Pi
3762 Views, 17 Favorites, 0 Comments
How to Make a 4G Enabled Raspberry Pi Zero for Remote Motion Detection - Garages, Sheds Etc
![PXL_20230114_100000134.jpg](/proxy/?url=https://content.instructables.com/FNK/Y0S5/LCUJ7II2/FNKY0S5LCUJ7II2.jpg&filename=PXL_20230114_100000134.jpg)
If you're like me and live in a big city, you'll know it's the worst idea to keep your pride and joy, ie. a car or motorbike, parked outside on the street. It'll get bashed, tipped over, or just plain stolen.
The next best thing is to try and find a lockup to park your pride and joy. But are they ever close to your dwelling? Are they hell. Hence why I've tried to cobble together a few bits and bobs to try and at least warn me that I need to put some trousers on, grab a bat, and hightail it over to where I keep my bike...
It's worth mentioning, that my motorbike has a tracker installed on it, too. I don't want to reinvent the wheel here... just have some added info sent back to me about its surroundings.
Requirements checklist:
- Can connect to 4G as wiFi is out of the question
- Can run for a decent amount of time on battery - recommended reading
- Motion detection
- Takes a snap of the situation at time of said motion
- Warns me via email
Supplies
- Tupperware - x1 plastic & x1 glass
- Drill bits to make holes in said Tupperware
- Raspberry Pi Zero 2 (Facebook Marketplace is probably a better bet than eBay - at time of writing, big chip shortage so resell only)
- 4G hat that can be mounted on top of the Pi via some pins
- Data enabled SIM card
- 12V rechargeable lead battery
- Crimp connectors for battery
- Buck power module with USB out to step down the 12V from battery to 5V for the Pi
- Pi camera
- Pi camera holder
- Pi motion sensor
- GPIO leads that connect the motion sensor to the Pi
- USB mouse, keyboard and an HDMI to mini-HDMI adapter
- PCB spacers for mounting components
- Rubber grommets
- Electrical wire
- Breakaway pins to solder to the Pi
- A decent soldering iron - I say decent here as the tip has to be pointy and hot to solder those tiny Pi pins
Prep Your Containers
![PXL_20230108_154330646.jpg](/proxy/?url=https://content.instructables.com/FHB/0VYU/LCNDZ9LP/FHB0VYULCNDZ9LP.jpg&filename=PXL_20230108_154330646.jpg)
![PXL_20230109_193009474.jpg](/proxy/?url=https://content.instructables.com/F1O/IBK1/LCQ8TNMX/F1OIBK1LCQ8TNMX.jpg&filename=PXL_20230109_193009474.jpg)
![PXL_20230109_192145368.jpg](/proxy/?url=https://content.instructables.com/FRI/X2M9/LCQ8TNMW/FRIX2M9LCQ8TNMW.jpg&filename=PXL_20230109_192145368.jpg)
For the plastic Tupperware, use the grommets, as well as the drill bit, to fashion some holes for:
- 4G antenna out
- Micro USB power in
- GPIO leads for motion detector out
- Camera out
It's definitely an idea to test fit things before burning holes with the soldering iron for those spacer screws (yeah, you know it). ie if you mount the Pi in that spot, will you be able to plug in the usb cable for power, are the GPIO pins accessible etc.
For the glass Tupperware, just cut holes in the top for power leads in and out. Grommets as necessary. This will house the buck module. I wanted it to be separate, in case it decides to get warm.
Prep Your Pi
Snap x2 pairs of breakaway pins off and solder them to pins 1&2 and 13&14.
Once we get underway with the code, this will make sense.
Prep Alert Management - AWS
Some knowledge about Amazon Web Services (AWS) might make this step a little smoother, but here's the general jist:
AWS is a cloud computing platform that has a myriad of tools that allows you to set up a notification system that our pi can talk to, and then messages can be relayed accordingly ie. to us via email. To get started with AWS you can set up an account for free, but then you'll get charged for what you use... like anything.
The premise will go something like this:
- Pi sends a message to a notification service topic
- The topic will have subscribed to it an action to send an email
Prep Alert Management - Create Topic
![Screenshot 2023-01-08 at 20.27.36.png](/proxy/?url=https://content.instructables.com/FOJ/OEKC/LCNDZAF8/FOJOEKCLCNDZAF8.png&filename=Screenshot 2023-01-08 at 20.27.36.png)
To create topics in AWS, the product you want is SNS.
SNS will allow us to send a message to a topic. Once the message has landed in said topic, we can add a subscription to it - meaning that when a message is received, it does something with it. In this case, send us an email.
Go ahead and create a topic in SNS via the AWS Console (screenshot). Minimal options needed - just the name. garage-motion, perhaps.
Important note: Be mindful of the region you're in. Be sure to keep it the same.
Once that's created, make a note of its ARN. We'll need that later.
Prep Alert Management - Create Subscription
![Screenshot 2023-01-08 at 20.38.22.png](/proxy/?url=https://content.instructables.com/FRN/635G/LCNDZB04/FRN635GLCNDZB04.png&filename=Screenshot 2023-01-08 at 20.38.22.png)
Again in the SNS AWS console, create a Subscription.
Choose from the dropdown menu your Topic ARN, the protocol as email, and the endpoint will be your email address.
Click create subscription at the bottom.
We're ready to have the pi send the messages to AWS for it to pass to our email address. (Ps. you can definitely send an SMS too, and loads of other things, but they do get a bit spenny)
Pi Zero OS
Flash your micro SD card using the raspberry pi imager.
Best to go for a Pi OS version with a desktop. The main reason being that if you were to ssh into the pi from another machine to configure networking options for the 4g hat, the connection will drop, and you'll be unable to perform any other terminal operations as its ip address will have changed, known hosts, etc etc
To add ssh on startup and give it your wifi creds, use the advanced options cog icon in the bottom right of the imager to set your wireless lan and ssh settings
Once done and the sd card is installed in the pi, ssh on and enter the following to ready the GPIO pins:
sudo apt-get install rpi.gpio
Then:
sudo raspi-config
In here go to Interface Options and then to I2c, enable I2c by selecting Yes.
Reboot.
After a reboot, do the same for SPI in the Interface Options.
Reboot again.
Install the AWS CLI
The AWS CLI is the command line tool needed to authenticate with your account you made the SNS additions to earlier.
Our Pi needs to be able to auth with your AWS account and send the message to that topic. We need to install a global library on the Pi to allow us to do that and configure it.
pip3 install awscli
export PATH=/home/pi/.local/bin:$PATH
aws --version
aws configure
You'll be asked to input some details you'll be able to grab from your AWS account
Install Some Code Dependencies
For this project, we'll be using python3 virtual environments (venv) to manage dependencies etc.
Open up a terminal on the pi and create a project space and venv:
mkdir projects && cd &_ && mkdir garage-motion && cd &_ && python3 -m venv venv
Create requirements file:
touch requirement.txt
Add requirements to file:
boto3==1.26.45
botocore==1.29.45
colorzero==2.0
gpiozero==1.6.2
jmespath==1.0.1
python-dateutil==2.8.2
RPi.GPIO==0.7.1
s3transfer==0.6.0
six==1.16.0
urllib3==1.26.13
Activate the venv:
source venv/bin/activate
Install the requirements:
pip install -r requirements.txt
Motion Sensor Connections
![xO4cooX8woFXbeNrsRGK4U0cBbvLJgZxKWwrJrOX (1).jpg](/proxy/?url=https://content.instructables.com/F2F/LFB7/LCNDZD3F/F2FLFB7LCNDZD3F.jpg&filename=xO4cooX8woFXbeNrsRGK4U0cBbvLJgZxKWwrJrOX (1).jpg)
With the sensor facing up, connect your GPIO pins thusly:
Positive 5V: 5V (pin 2)
Output: GPIO27 (pin 13)
Ground: ground (pin14)
YOURS MAY DIFFER! Check the PCB for more.
Motion Sensor and Sending Message
Make sure you're still in the directory you created, cd into the venv, and create the python script we'll run:
touch garage-motion.py
Open up the file and add the code, being careful of indentation:
import time
import boto3
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(13, GPIO.IN) # Middle pin defined in Step 9
client = boto3.client('sns')
while True:
i=GPIO.input(13)
if i==0: # When output from motion sensor is LOW
print("No intruders",i)
time.sleep(0.1)
elif i==1: # When output from motion sensor is HIGH
print("Intruder detected",i)
response = client.publish(
TargetArn='yourSNSTopicARN',
Subject='Garage update',
Message="Yo, you got movement",
MessageStructure='string'
)
print(response['MessageId'])
time.sleep(0.1)
Remember to replace the topic ARN from Step 4 here.
Next step is to run the script:
python3 garage-motion.py
Move in front of your motion sensor, and you should get an email!
At this point it might be a good idea to have a fiddle with your potentiometers on the motion sensor and rerun the script.
The potentiometer on the right controls the sensitivity, and the potentiometer on the left controls the timeout. Fully anti-clockwise and the sensitivity and timeout are at their lowest.
When the timeout is turned fully anti-clockwise, the sensor will output a signal for about 2.5 seconds, whenever motion is detected. If the potentiometer is turned fully clockwise, the output signal will last for around 250 seconds. When tuning the sensitivity, it is best to have the timeout set as low as possible.
Time for Local Pi Development!
![PXL_20230111_163250556.jpg](/proxy/?url=https://content.instructables.com/FG9/G6J2/LCS1B9TF/FG9G6J2LCS1B9TF.jpg&filename=PXL_20230111_163250556.jpg)
![PXL_20230109_181255275.jpg](/proxy/?url=https://content.instructables.com/FIY/B2KR/LCS1B9T5/FIYB2KRLCS1B9T5.jpg&filename=PXL_20230109_181255275.jpg)
Soon we're going to put the 4g hat on the pi but when we do and configure it, we'll lose the ssh connection since it won't route traffic through its wireless interface anymore.
- Setup your SIM card and push into slot on 4g hat - i used a Things Mobile Sim
- Screw the hat on to the PI - making sure to line up the pins correctly to the underside of the GPIO board
- Add your USB mouse and USB keyboard to the ports of the hat
- Add your HDMI mini output to the pi
- Connect the GPIO pins to the Pi from the sensor
Connect usb power to the pi and use it like you would a computer - mouse, keyboard, display etc. Open a terminal window...
Make the Network Changes to the Pi to Allow Traffic to Be Routed Through the Hat (not Wifi)
This is probably the most involved step of the build - well, it was for me at least since I'm not too hot at networking.
I found that the software setup step from Twilio seemed to be the closest to the setup and use of what I'm attempting.
Since you've already connected the hat through pins to the pi zero just skip to the software step.
You don't really need to open a browser at the end of those steps to prove that you have a connection (it's also abysmally slow). Just a "ping apple.com" should suffice from the terminal window.
We now need to automate the last two steps so that on boot pon is running and the route is set.
To do this there are three parts:
Create a service to start pon in the background, update the route table for ppp0, and then get the python script to run:
1. Pon service
To do this we will use the pi's systemd services which run at startup.
Let's create a service:
sudo touch /etc/systemd/system/4gpon.service
Give it the correct permissions:
sudo chmod 644 /etc/systemd/system/4gpon.service
Then we add what we want it to do:
sudo nano /etc/systemd/system/4gpon.service
Then add the following:
[Unit]
Description=4G hat networing
[Service]
Type=forking
ExecStart=/usr/bin/pon
ExecStop=/usr/bin/poff
Restart=always
[Install]
WantedBy=multi-user.target
Then we tell the pi to use this script on startup:
sudo systemctl enable 4gpon.service
Restart the pi.
Enter into a terminal window
ps aux | grep pon
and this should show the process running the background. Nice.
2. Update route table
These commands will wipe the default route and add our ppp0 interface for the pi as the new default
sudo ip route delete default
sudo ip route add default dev ppp0
Then we want to add an actual ppp0 interface
sudo nano /etc/network/interfaces.d/ppp0
Then add to the file:
auto ppp0
iface ppp0 inet provider
up ip route add default dev ppp0
We have one more thing to add into the provider we would have touched on in the Twilio steps...
sudo nano /etc/ppp/peers/provider
Add at the bottom:
replacedefaultroute
3. Motion service
Much like 1. in this step, we will need to create a service to run the script on startup, but when the network is up. systemd services are clever like this, so we can rely on other things to be up etc. So...
Let's create a service:
sudo touch /etc/systemd/system/garage-motion.service
Give it the correct permissions:
sudo chmod 644 /etc/systemd/system/garage-motion.service
Then we add what we want it to do:
sudo nano /etc/systemd/system/garage-motion.service
with:
[Unit]
Description=Motion detector service
After=network.target network-online.target 4gpon.service
[Service]
Type=simple
Environment="AWS_DEFAULT_REGION=***your-region***"
Environment="AWS_ACCESS_KEY_ID=***your-key***"
Environment="AWS_SECRET_ACCESS_KEY=***your-secret-key***"
ExecStart=/bin/sh -c '/home/pi/projects/garage-motion/venv/python3 /home/pi/projects/garage-motion/venv/garage-motion.ph --serve-in-foreground'
Restart=on-abort
[Install]
WantedBy=multi-user.target
Let's start the service:
sudo systemctl start garage-motion.service
To check that the service is up, you can do:
sudo systemctl status garage-motion.service
Check if you get an email from the script!
Then we tell the pi to use this script on startup:
sudo systemctl enable garage-motion.service
FINALLY, we need to make sure we don't have the desktop display blocking the startup of services. Up until now, the pi has thought that we're desktop users, and initialises services when the HDMI display is present.
Use sudo raspi-config to set a forced screen resolution. (Choose anything other than monitor default).
Shut down the pi with a sudo shutdown now. You're ready to take this out in the world and try it out!
Battery and Buck Module
![PXL_20230113_162303613.jpg](/proxy/?url=https://content.instructables.com/FJW/M0M7/LCUJ5O36/FJWM0M7LCUJ5O36.jpg&filename=PXL_20230113_162303613.jpg)
![61Qs9uZTk-L._AC_SX679_.jpg](/proxy/?url=https://content.instructables.com/FQ8/NKUC/LCUJ5O2S/FQ8NKUCLCUJ5O2S.jpg&filename=61Qs9uZTk-L._AC_SX679_.jpg)
![PXL_20230113_162227948.jpg](/proxy/?url=https://content.instructables.com/FAU/BKO5/LCUJ5O33/FAUBKO5LCUJ5O33.jpg&filename=PXL_20230113_162227948.jpg)
![PXL_20230113_162231066.jpg](/proxy/?url=https://content.instructables.com/FVO/9CPB/LCUJ5O34/FVO9CPBLCUJ5O34.jpg&filename=PXL_20230113_162231066.jpg)
![PXL_20230113_162232687.jpg](/proxy/?url=https://content.instructables.com/FOR/3I00/LCUJ5O35/FOR3I00LCUJ5O35.jpg&filename=PXL_20230113_162232687.jpg)
Crimp your connectors for the battery on the wires. Connect the other end of your wires to the buck module.
!! CONNECT NOTHING TO YOUR BUCK MODULE OUTPUT (yet) !!
You don't know where the screw is set that sets the output voltage (and current, but not as important). You could connect something at 12v and blow it up.
IT IS IMPERATIVE you screw the voltage screw as anti-clockwise as it will go, as a baseline.
Next, connect something you don't care too much about (a fan I have here in the pictures).
The voltage has to be set correctly - the current will alter itself based on what it draws, so we're not too worried about that.
Set the voltage to 5.1v using a screw driver on the left blue component shown in the diagram.
More reading about Pi Zero 2 power consumption
Take It All Outside and Have Go!
Bonus - Added Camera
You might want the added security of a camera snap when the motion detector fires.
- Connect up the camera.
- Enable the camera in the interfaces of sudo raspi-config
- Follow this guide to set up openCV
- Setup an s3 bucket with public permissions
- Amend the python script to upload a shot to s3 and include the path in email so you can view immediately :
from datetime import datetime
import time
import boto3
import RPi.GPIO as GPIO
import cv2
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(13, GPIO.IN) # Middle pin defined in Step 9
client = boto3.client('sns')
s3_client = boto3.client('s3')
while True:
i=GPIO.input(13)
print(f'Sensitivity: {i}')
if i==0: # When output from motion sensor is LOW
print("No intruders",i)
time.sleep(0.1)
elif i==1: # When output from motion sensor is HIGH
print("Intruder detected",i)
now = datetime.now()
date_time = now.strftime("%m%d%Y-%H%M%S")
# camera bits
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
if ret:
cv2.imwrite(f'intruder-{date_time}.jpg', frame)
cap.release()
del(cap)
s3_client.upload_file(
Filename=f'/intruder-{date_time}.jpg',
Bucket='your-s3-bucket',
Key=f'intruder-{date_time}.jpg'
)
# SNS send
response = client.publish(
TargetArn='your-arn',
Subject='Garage update',
Message=f'Yo, you got movement: https://your-s3-bucket.s3.eu-west-2.amazonaws.com/intruder-{date_time}.jpg',
MessageStructure='string'
)
print(response['MessageId'])
time.sleep(0.1)