# Home Alarm
### *Author:* Simon Palm (sp222ym)
This is a project for the course **‘Applied IoT’** at the Linnaeus University. The project took around 4 weeks and was completed in late July of 2021.
<img src="https://i.imgur.com/xv9W0lr.jpg"
alt="lopy4"
style="height:60%; width:60%; display: block;
margin-left: auto;
margin-right: auto;
width: 50%;" />
The project I choosed was to make a home alarm which is a good way to keep track if someone enters my apartment unannounced and could potentialy scare burglars.
The project was finsihed in about **~12-15 hours** for a not experienced programmer in micro python and sensors. Hopefully this tutorial will help you with your code and understanding of how you could do it on your own.
## Objective
This project was created to have some more security at home, and since I live in a student dorm. Usually I leave my apartment unlocked when I am in the shared kitchen. Therefore some extra security would suit me well to keep track on nosy neighbors. The device will keep track of any movement detected when entering from the main door.
This project gives insight on how to use sensors like a PIR (Passive Infrared sensor) and a buzzer as well as a push button. It gives a brief exploration of MicroPython and IoT architechture with the use of a lib folder, and aims to be a good introduction to the universe of IoT.
## Material
<img src="https://i.imgur.com/DAf6d2d.jpg"
alt="lopy4"
style="height:50%; width:50%;" />
| Material | Price | Where? | Short specifications |
|-----------|-----------|-----------|-----------|
| Lopy4 | 392,86 Kr | [Link to pycom](https://pycom.io/product/lopy4/) | The LoPy4 is a Micropython-programmable microcontroller which sses LoRa, Sigfox, WiFi and Bluetooth, to transfer data. | |
<img src="https://i.imgur.com/xhDtyGp.png"
alt="lopy4"
style="height:60%; width:60%;" />
| Material | Price | Where? | Short specifications |
|-----------|-----------|-----------|-----------|
| Expansion board | 179,83 kr | [Link to pycom](https://pycom.io/product/expansion-board-3-0/) | Enables USB power and simplifies cable connection. | |
<img src="https://i.imgur.com/QjT23PH.jpg"
alt="lopy4"
style="height:40%; width:40%;" />
| Material | Price | Where? | Short specifications |
|-----------|-----------|-----------|-----------|
| PIR | 49.00 kr | [Link to electrokit](https://www.electrokit.com/produkt/pir-rorelsedetektor-hc-sr501/) | Motion sensor that senses the heat from humans and animals. | |
<img src="https://i.imgur.com/G8PLDii.jpg"
alt="lopy4"
style="height:40%; width:40%;" />
| Material | Price | Where? | Short specifications |
|-----------|-----------|-----------|-----------|
| Push button | 19.00 kr | [Link to electrokit](https://www.electrokit.com/produkt/tryckknapp-momentan/) | A button which gives a value of 1 or 0 when pressed and not pressed. | |
<img src="https://i.imgur.com/Z0BWNdL.jpg"
alt="lopy4"
style="height:40%; width:40%;" />
| Material | Price | Where? | Short specifications |
|-----------|-----------|-----------|-----------|
| Piezo element | 36.00 kr | [Link to electrokit](https://www.electrokit.com/produkt/piezohogtalare-passiv/) | A speaker which makes sounds. | |
<img src="https://i.imgur.com/cH0iwXC.jpg"
alt="lopy4"
style="height:40%; width:40%;" />
| Material | Price | Where? | Short specifications |
|-----------|-----------|-----------|-----------|
| Breadboard | 59.00 kr | [Link to electrokit](https://www.electrokit.com/produkt/kopplingsdack-400-anslutningar/) | Used to connect power, ground and output to the different element and sensors. | |
<img src="https://i.imgur.com/3Rp4XMM.jpg"
alt="lopy4"
style="height:20%; width:20%;" />
| Material | Price | Where? | Short specifications |
|-----------|-----------|-----------|-----------|
| USB cable | Found one at home | [Link to electrokit](https://www.electrokit.com/) | Gives power to the expansion board. | |
<img src="https://i.imgur.com/tOFHeIX.jpg"
alt="lopy4"
style="height:40%; width:40%;" />
| Material | Price | Where? | Short specifications |
|-----------|-----------|-----------|-----------|
| Wiring | 29.00 Kr | [Link to electrokit](https://www.electrokit.com/produkt/labsladd-1-pin-hane-hane-150mm-10-pack/) | Wirings to connect power,ground and output to the elements and sensors. | |
## Computer & Pycom setup
### Step 1: Flash the expansion board
Before starting it's recommended to flash the firmware on the expansion board to the latest version.
When doing this project my board already had pretty recent firmware, so I skipped flashing. If your expansion board needs to update, [follow this guide](https://docs.pycom.io/updatefirmware/expansionboard/) to get it done.
### Step 2: Update the firmware on your LoPy4
After step 1 is finished or not, you should update the firmware on the LoPy4. Then we need to download the [Pycom updater tool](https://docs.pycom.io/pybytes/connect/quick/#download-pycom-firmware-updater-tool) to start update your device. If you’re not on Mac or Linux, you might need to install drivers from [Pycom](https://docs.pycom.io/index.html) to get things working correctly.
When that is done, check this guide [pycom getting started guide](https://docs.pycom.io/gettingstarted/). To connect your LoPy4 to the expansion board by lining up the LoPy4 and the Expansion board the right way before connecting them. Make sure you can read “Pycom” the direction way on both units before you push them together.
### Step 3: Installing your IDE
IDEs are software in which you write your code and communicate with the pycom device. For this project I choose to work in the **IDE: Visual Studio Code** which I am familiar to. Another alternativ is the IDE called **Atom**.
When you have installed your prefered IDE, then it is time to install the extension **pymakr** which made it possible to run and upload the code to the pycom device. To use Pymakr you need to install **Node.js**, [install Node.js](https://nodejs.org/en/download/) if you have not already.
### Step 4: Make sure everything works (Optional)
To make sure the setup worked correctly you can make your first blinking program with the led on the LoPy4, which is good to make sure that it has been setup accurately, [the guide can be found here](https://docs.pycom.io/gettingstarted/).
Congratulations! You have now learned the basics to communicate with your pycom device.
### Putting everything together
Putting everything together could seem overwelming but it is not that complicated, hopefully I will make it clear what you need to do.
### General information
All the sensors used has either one or more pins which are **Power, Ground and Output**. **Power** pin needs to be connected to a voltage source to power the sensor. Usually **3V3** or **VIN** pin on the Lopy4 depending on what voltage the sensor needs.
The sensors has a ground pin which needs to be connected to ground to allow a current to flow. This is also necessary for the sensor to be powered. There is a **GND** pin on the Lopy4.
Lastly there is a pin for data which is the **output/signal** pin. Depending on type, can either be used to control the sensor, or collect data from it. Have a look in the documentation for your sensor to read up on how it works. A output/data pin can generally also be either analogue or digital.
* Analogue pin sends unalike values depending on the voltage level from the pin. This might be useful for example a temperature sensor.
* Digital pin has a HIGH or LOW value from the voltage. The HIGH and LOW state can be interperated to a 1 or 0 to the Pycom device.
### Passive Infrared sensor (PIR)
The PIR used in this project is called HC-SR501 this sensor captures the warmth of the environment, and detects motion through changes in this typ of heat. Below is an instruction which explains how you can increase/decrease the delay when it triggers.
<img src="https://i.imgur.com/tqEhHhc.jpg"
alt="lopy4"
style="height:40%; width:40%;" />
* The PIR needs 4.5-20V so we connect the power pin on the sensor to the VIN on the breadboard. This gives the PIR around 5V, which is all right. The ground is connected to GND on the breadboard. The output pin is connected to **PIN 13** on the expansion board.
<img src="https://i.imgur.com/QXmEdMJ.png"
alt="lopy4"
style="height:40%; width:40%;" />
### Passive Piezoelectric Buzzer
<img src="https://i.imgur.com/x1vWuPC.png"
alt="lopy4"
style="height:50%; width:50%;" />
This buzzer needs 3.3V so we connect the power pin on the sensor to the 3V3 on the breadboard. The ground is of course also connected to GND on the breadboard. The output pin is connected to **PIN 23** on the expansion board.
### Push Button
This push button needs 3.3V so we connect the power pin on the sensor to the 3V3 on the breadboard. The ground is connected to the GND on the breadboard. The output pin is connected to **PIN 16** on the expansion board.
<img src="https://i.imgur.com/xdtbnb1.png"
alt="lopy4"
style="height:50%; width:50%;" />
### Circuit
The circuit can look something like the image below. Before you start to make the circuit like me check your documentation that your sensors have the same kind of layout as mine before connecting the wires.
<img src="https://i.imgur.com/pqDt9Rr.jpg"
alt="lopy4"
style="height:40%; width:40%;" />
I made a hand drawn circuit diagram to show how I wired everything on my breadboard. Hopefully it is not to hard to follow.
<img src="https://i.imgur.com/sBk89ZS.jpg"
alt="lopy4"
style="height:80%; width:80%;" />
* **Note:** This project is made for development and for testing around. It’s made in way to take it apart again if you want to try another project.
### Platform
Here I will mention some of the platforms for your IoT project, I have used **Ubidots** for my own project.
* **Ubidots**, is a free platform if you use the STEM plan. There is a lot of good documentation which makes getting started pretty comfortable. There are widgets, plugins and events which you can controll and change.
* **Pybytes**, is a also a free cloud-based device management platform and available for all Pycom development boards and modules. I have not tried it my self but I has a lot of documentation and seems easy to get started with.
### The code
The code structure consist of a lib folder where **button, keys, pir, sounds, ubi , and urequests** and in the root **boot, and main**.
<img src="https://i.imgur.com/aSmDsLD.png"
alt="lopy4"
style="height:40%; width:40%;" />
| File Name | Description
|-----------|-----------|
| boot | Connects to WiFi etc when the LoPy4 is started up.
| main | Holds the main code.
| keys | Contains your SSID, WiFi password, ubidots token etc.
| urequests | A lean library that simplifies the process of connecting to ubidots.
| pir | Functions for the PIR sensor.
| button | Functions for the Push button.
| sound | Functions for the Buzzer.
| ubi | Functions for communication with ubidots from my project.
### Boot
The boot file basically connects the LoPy to WiFi and preps the device for communication with ubidots.
````
from machine import UART
from network import WLAN
import machine
import time
import os
import pycom
import keys
# pycom.pybytes_on_boot(False)
pycom.heartbeat(False)
uart = UART(0, baudrate=115200)
os.dupterm(uart)
# config wifi hardware
wlan = WLAN(mode=WLAN.STA)
wlan.antenna(WLAN.INT_ANT)
# Assign your Wi-Fi credentials
wlan.connect(keys.ssid, auth=(WLAN.WPA2, keys.ssid_pass), timeout=5000)
# Connecting to WiFi
while not wlan.isconnected ():
print("Connecting to WiFi...")
time.sleep(1)
#machine.idle()
print("Connected to Wifi \n")
time.sleep(0.5)
machine.main('main.py')
````
### Main
This file handles the installation of the PIR sensor, push button and checks the current mode from ubidots.
````
# Imported libraries
from machine import Pin
import machine
import time
import pycom
# Import own libraries to structure the code
import ubi
import keys
import sound
import pir
import button
# Config
INIT_DELAY = 60 # Delay to allow initialization of PIR Sensor. 60s according to docs.
## -- MAIN CODE -- ##
# Startup
state = machine.disable_irq() # Makes sure device can't be interrupted by PIR.
print("Home Alarm is starting in " + str(INIT_DELAY) + " seconds")
time.sleep(INIT_DELAY)
machine.enable_irq(state) # Allow interruption again.
while True:
pir.motionDetected()
button.isAlarmOn()
````
### Pir
This file takes care of the PIR interactions when the sensor is triggered and then sends a trigger to **ubidots**.
````
import machine
import time
from machine import Pin
import sound
import ubi
import pycom
# Config of the PIR Sensor
LOCKOUT_TIME = 5 # Lockout time after the sensor has been triggered to avoid multiple triggers of one event.
PirPin = machine.Pin('P13', Pin.IN)
# Function that runs when PIR is triggered (interruption)
def motionDetected():
PirPinValue = PirPin()
mode = ubi.alarm_mode()
if mode== 1 and PirPinValue == 1:
post_trigger_to_ubi(mode) # Silent Alarm mode
time.sleep(0.5)
elif mode== 2 and PirPinValue == 1:
post_trigger_to_ubi(mode) # Alarm fully activated
sound.play_mario()
elif mode==0:
pass # Alarm turned off
state = machine.disable_irq()
time.sleep(LOCKOUT_TIME)
machine.enable_irq(state)
# Post a trigger event to Ubidots
def post_trigger_to_ubi(mode):
print("[Motion in apartment detected]")
pycom.rgbled(0x7f0000) # red
ubi.post('alarm-triggers',mode)
time.sleep(4)
pycom.heartbeat(False) # LED off
````
### Button
This file conains the code for the push button, it makes the LoPy4 LED light in different colors depending on the current alarm mode.
````
# Imported libraries
from machine import Pin
import machine
import pycom
import ubi
PushButton = Pin('P16', mode = Pin.IN)
# Function checks if alarm is on
def isAlarmOn():
mode = ubi.alarm_mode()
ButtonValue = PushButton()
if ButtonValue == 0 and mode > 0:
print('Alarm is active')
pycom.rgbled(0x007f00) #LED should glow green
elif ButtonValue == 0 and mode == 0:
print('Alarm is not active')
pycom.rgbled(0x7f7f00) # LED should glow yellow
elif ButtonValue == 1:
pycom.heartbeat(False) #LED off
````
### Ubi
This code posts the data to **ubidots**. It also detects when the mode changes.
````
import urequests as requests
import keys
import sound
last_mode = None
# Function builds the JSON object to send the request to ubidots
def build_json(variable, value):
try:
# data array creation
data = {variable: {"value": value}}
return data
except:
return None
# Sends the request. Please reference the REST API reference https://ubidots.com/docs/api/
def post(topic, value):
try:
data = build_json(topic, value)
if data is not None:
response = requests.post(url=(keys.url + keys.pub), headers=keys.headers, json=data) # include data as JSON object
json_obj = response.json()
response.close()
return json_obj
else:
print("ERROR: JSON Empty. Nothing to post.")
pass
except:
print("ERROR: Can't send data to Ubidots.")
pass
# Function sends an api get request for the mode from the Ubidots server.
def getMode(api):
response = requests.get(url=(keys.url + api), headers=keys.headers)
obj = response.json()
value = int(obj['last_value']['value']) # Takes the value from the response object
response.close()
return value
#Function checks for a mode change
def alarm_mode():
global last_mode
mode = getMode(keys.sub)
if mode==last_mode:
pass
else:
print("Mode: [" + str(mode) + "]")
sound.mode_change(mode)
last_mode = mode
return mode
````
### Transmitting the data / connectivity
The PIR,Push Button sends data to the LoPy4 and the Passive Buzzer gets data from the LoPy4.
<img src="https://i.imgur.com/Hq6tNUN.png"
alt="Connectivity"
style="height:60%; width:60%;" />
#### Wireless protocol
For this home alarm I fought it was most suitable to use **WiFi with MQQT protocol** since the device is positioned in range of a WiFi access point.
#### Transport protocols
In terms of transport protocol I use MQTT since it seemed like a generally great protocol for IoT devices. Through MQTT,my pycom device connects to Ubidots platform through their middleman.
### Presenting the data
<img src="https://i.imgur.com/KaQp4tF.png"
alt="Connectivity"
style="height:60%; width:60%;" />
#### Dashboard and database
The data is presented in Ubidots on a dashboard like the one above. Here we can see the Active alarm mode of the alarm as well as controlling the mode with the slider to the right. We also see spikes on the graph when the alarm has been triggered.
Data is stored whenever a trigger happens from the home alarm and Ubidots STEM keeps my data in their database for 1 month, which is good for my home alarm. It’s a free cloud solution for students, which is what I was looking for when choosing database and platform.
#### Modes
You can change modes from **ubidots** dashboard at the slider, which in turn changes the variable value and is sent to the home alarm.
* **[0]** Home alarm is disabled/Off, when the button is pressed the LoPy4 LED shine yellow which indicates that it is off.
* **[1]** Home alarm is on silent, which means it do not make any sound but sends a trigger to **ubidots**. When the button is pressed LoPy4 LED shine green which indicates that it is on.
* **[2]** Home alarm is fully armed and plays a super mario sound when the alarm is triggered and a trigger is sent to **ubidots**. When the button is pressed LoPy4 LED shine green which indicates that it is on.
### Finalizing the design
For my home alarm I made a cardboard box which is not ideal but it works for now, if I had some extra time I would probably want to make a 3D case to put my home alarm in. I could also add some more modes with different sounds or connect more sensors to get more data.
The project went overall pretty smoothly, I just had some issues setting up the connection with ubidots. It was a fun project and I learned a lot.
<img src="https://i.imgur.com/BZy9sgG.jpg"
alt="Connectivity"
style="height:40%; width:40%;
display: block;
margin-left: auto;
margin-right: auto;
width: 50%;" />
<img src="https://i.imgur.com/fTkuOH5.jpg"
alt="Connectivity"
style="height:40%; width:40%; float:right" />
<img src="https://i.imgur.com/UbsYN5Y.jpg"
alt="Connectivity"
style="height:40%; width:40%;" />