### Tutorial on how to build a system to prevent that a dog is taken from its owners
# Dog Protection Against Stold
## Maria Manuela de Queirós Ramos
### md223ah
En App i mobilen för att få meddelande om hundens positionen har ändrats och/eller hunden har gått över gränsen för en area centrerad i den position hunden har lämnats.
En alarm ska startas ifall koppeln dras eller tas bort eller om gränsen ovan överskrids.
Temperatur och Relativ Fuktighet används för att se om hunden är ut eller in.
PyMakr eller GPS sensor kan användas.
WiFi används för att koppla till min mobils Internet.
Ifall hunden ändå skulle tas från området som täcks av min telefon, så kan man ge GPS kredentialer till polisen.
Via min telefon kan jag se vilken position (Lat, Long) som jag lämnar min hund på... sätter det som center på area ovan med att skicka positionen till programmet som körs i mikrokontrollen.
Om man har alla komponenter, FiPy, Pycom Board 3.0 samt sensorerna Temp, RH, GPS, Vibration, Knock samt Alarm, Transistor, Button och sätt att få GPSens data skickade till min telefon eller nåbar från polisen, så tar det bara någon timma att montera. Programen tar kanske några timmar att skapa, testa följde av att löda och testa. Kopplingen till t.ex. Ubidots, som har den area alarm som jag berättade om ovan tar kanske en timma med test.
Så kanske 5 timmar totalt om det är första gången.
Objective
Why: Har haft problem med att inte kunna lämna min hund utanför t.ex. affärena. Någon har gjort så att min hund blev lös och kanske även blev tagen av någon. Han är gammal och blev lämnade på en park.
Purpose: Så tänkte att jag kunde skapa ett system med olika sensorer och alarm för att undvika att det händer igen.
Det berättats att det hade hänt flera gånger på samma områd.
ICA har redan skapat en bur som ger alarm om någon försöker vidröra den. Jag tänkte göra en mindre lösning.
Insights: Man kan se hur mycket man vidrör hunden. Och se om man hittar någon som försöker ta hunden.
Material
I detta projekt valde jag att använda mig av FiPy mikrokontroller från Pycom som man ser i Fig 1.
Jag ville testa LTE och valde då FiPy istället för LoPy.
Man programmerar den med Micropython. Den har bägge analoga och digitala input och output och man kan koppla den på flera sätt: Bluetooth, LTE, Sigfox, LoRa, WiFi (inbyggd) och man kan använda sig av MQTT.
Fig 1
Använde mig av DHT11 (se Fig 2) sensor för att mätta Temperatur och Relativ Fuktighet vid hundens placering. Man kan infira om den finns in eller utanför en bygnad.
Använde mig av Vibration Sensor (se Fig 2) för att mätta vibration av systemet kopplade till hunden.
Använder Summer 75 DB som alarm (se Fig 2). Triggs av vibration värden i Vibrations sensorn.Info: Summer med 75 dB-ljudstyrka och konstant ton. Frekvens: 0,4 kHz. Drivs med 7-15 V (DC). Hålavstånd för montering: 27 mm (CC). Mått: 33x15x16 mm.
För positioning av hunden om någon skulle ändå ta honom eller om han skulle fria sig själv och istället för att komma till mig bestämer sig för att ta en runda, så köpte jag en GPS sensor från Elektro:Kit.
Fick den igår onsdag. Har nu studerat datasheet och flera tutorialer för ESP32 och u-blox.
Fig 2

List of material
| IoT Thing | Beskrivning |Pris |
| -----------| -------------------------- | ---------- |
| FiPy | Mikrokontroller från Pycom | 54 EUR |
| Expansion Board 3.0 | Board från Pycom | 16 EUR |
| LTE-M Antenna Kit | Från Pycom | 9 EUR |
| LoRa (868MHz/915MHz) Sigfox Antenna Kit | Från Pycom | 9 EUR |
| Alarm Summer 75 DB | Från Kjell Company | 89.90 SWE |
| Lora Gateway | Från Connected Things(69 Pounds + ...) | 1150 SWE |
| Vibrationssensor | Från Electrokit (kom i 25 kittet) | 29.00 SWE |
| Digital temperatur- och fuktsensor DHT11 | Från Electrokit (kom i 25 kittet) | 49.00 SWE |
| Sensor Kit -25 moduler | Från Electrokit (kom i 25 kittet) | 348.00 SWE |
| GP-735 GPS-mottagare 56 kanaler TTL | Från Elektrokit + kabel | 523.00 SWE |
| Anslutningskabel för EM401 och EM406 30cm | Electrokit 29kr transport | 39.00 SWE |
| LiPo batteri 3.7V 500mA | Kjell & Company | 149.00 SWE |
| Batterihållare 3xAAA med strömbrytare och JST-kontakt | Electrokit 29 kr transport | 29.00 SWE |
# Dator setup
Min FiPy från Pycom programs igenom USB kabel kopplad till en Expansion Board 3.0 från Pycom var man pluggar in mikrokontrollern FiPy.
Har använt bägge Atom och Visual Studio Code som IDE. PyMakr och Python installerade jag i bägge IDE. PyMakr lägger till en REPL som är en kommand rad i IDEs Terminalen.
För att få allt att fungera ihop behövde jag, förutom at uppdatera Node.js jag hade, installera den sista firmware för Expansion Board 3.0 (efter råd i Pycoms tutorialen). För det använd jag mig av Zadig först och efteråt pycom_firmware_update_1.16.2 och sist pycom_firmware_update_1.16.3.
*: https://docs.pycom.io/gettingstarted/installation/firmwaretool/
*: https://docs.pycom.io/gettingstarted/connection/fipy/
*: https://docs.pycom.io/gettingstarted/registration/
Från IDE kan man förutom att använda REPL, köra programmet som är valt i editorn, lada upp programmet till mikrokontrollern (flasha) eller lada ner programmet från mikrokontrollern. Man kan koppla eller koppla av koppling till mikrokontrolern som finns kopplade till datorn via USB kabeln (COM4, i mitt fall, är porten).
PyMakrs REPL är en kommand rad i IDEs Terminalen, var igenom man kan exekvera kod som skrivs på Terminalsraden, direkt in i mikrokontroller. På REPL kan man t.ex. importera kod från en bibliotek och därefter exekvera kod från något program från detta bibliotek.
Kabling - se Fig 3a nedan.
I Fig 3 kan man se olika delar: Fipy mikrokontroller, de två sensorer DHT11 (in blåt) och Vibrationssensor till höger och Alarm Summer 75 DB på nedre delen.
Fig 3
### Kretsdiagram (can be hand drawn)
I Fig 3a nedan kan man se hur jag kopplade alla element:
GND- FiPy <------> GND- DHT11 <----> GND- Vibr
3V3- FiPy <------> Vin- DHT11 <----> Vin- Vibr
P23- FiPy <------> Data- DHT11
P16- FiPy <------> Data- Vibration
P22- FiPy <------> Vin Summer(Alarm)
GND- DHT11 <------> GND Summer(Alarm)
Fig 3a
Jag använd inte än någon resistor eftersom de inbyggda i FiPy och i Expansion Board 3.0 räcker.
Tänkte använda mig av en npn transistor för att koppla Vin- FiPy(Colector), 3V3- FiPy (Bas) och Vin- Summer(Emitter) och få ca 5V till Summer när then ska köras, istället för 3.3V som nuvarande koppling. Det var för att få högre ljud från Summer. Men det räcker som det är eftersom det ska vara på hunden och det skulle inte vara bra för honom med högre ljud.
Med npn transistor behövs två resistans: en mot basen,ca 1k ohm och en annan mot collector, ca 100 ohm (enligt exempel). Har en BC547 transistor. Då ska det vara:
Vin- Fipy <----> 100 ohm <----> Collector- npn Transistor
GND -FiPy <----> GND- Summer
3V3- FiPy <----> 1k ohm <----> Bas- npn Transistor
Vin- Summer <----> Emitter- npn Transistor
Detta kan användas om man inte behöver ha hela systemet på en liten volym.
Om man ska ha systemet i en liten volym, så måste man löda några delar för att unvika den vita board, och lägga till allt in i en kontainer som tillåter luft att gå in till DHT11 och ett sätt att ladda batteriet.
# *Electrical calculations
The Vibration sensor är bara en switch som stänger när systemet vibrerar. Den har en 10k ohm resistans mellan power och output. När den är öppen blir I = V / R = 3.3 V / 10 k ohm = 0.3mA. När den stängs går det hela till ground och värdet man får är på väg till 0. Men däremellan kan det ta flera värden. Det blir som om inget finns där i kretsen på platsen Vib sensor finns.
DHT11 sensor har en min 3V och max 5.5V (DC) och min I 0.5mA och 2.5mA max. Då blir det med 3.3V som man får från 3V3 pin på FiPy:
P min = 0.5mA x 3.3V = 1.45mW
P max = 2.5mA x 3.3V = 7.26mW
när man skickar de 40 bitar som varje komplet transmission består av.
Standby I min = 100uA och standby I max = 150uA.
# Platform
Jag använd mig av bägge Atom och Visual Studio Code. Kunde göra allt på båda.
När jag ville ändra inställningar för projektet så fick jag inte det bra på Atom. frågade en lärare men den hade inte en bra förklaring för att göra det. Han sa till mig att gå till VSCode.
Eftersom jag brukar ha olika projekt öppna hela tiden så blev de VSCode vad jag använt sista tiden. Hade gjort Atom med light bakgrund men har vänt mig nu att använda mig av den mörka jag har på VSCode.
Just nu handlar bara om prototyp(er). Men visst, om någon idé skulle gå fram till att säljas i kvantiteter eller antal kopplingar och data trafik, då blir det betald subscription för att undvika att nå gränserna.
De båda är lokala installationer.
# Node-Red - IBM i Cloud
Det jag har i cloud är Node-Red som just nu kopplar sig vid MQTT noder, så väll in som ut, från och till mitt program. Där, Node-Red, får jag använda InfluxDB, vilken package jag installerade (från pallete i Node-Red). Och då skulle jag kunna programmera i Node-Red det mesta och få data från InfluxDB som något program själv får från sin inläsning av data och placerar in till en InfluxDB.
Det finns också versioner av Node-Red för Mobilen.
Fig 4
# TIG - Telegraf/InfluxDB/Grafana (lokal)
TIG system jag använder är lokalt. Men jag har även en registration i Grafana-Cloud. Men behöver en databas som jag/Grafana kan nå från Cloud. Man kan öppna sin lokal InfluxDB till cloud tillgång, med vissa risker.
Fig 5
# Ubidots
Ubidots finns i cloud och erbjuder både fri och betal varianter. Har just nu bara den fria variant och det tillåter bara ett samtal/dag för avisering av gränsöverskrid, när man har valt samtal kopplade till ett larm. Har dess App i min telefon och kan där även lägga till nya värden. Valde att också använda mig av Ubidots bland annat eftersom de har kontrol över gräns överskridning av ett område som man definierar på en map.
Fig 6
Fig 6a
Fig 6b
# MQTT
MQTT Explorer visar vad som finns i en broker/server (t.ex sjolab.lnu) vart man kan skicka sin data via MQTT. Där kan man se olika grafer med en variabel i varje. Man kan öppna många sådana grafer, och blanda de från de olika kataloger som finns i servern. Användbart!
Fig 7
# PyBytes
Har testat PyBytes från PyBytes Debug och från min dator. Bägge fungerade bra. Data sparas i 30 dagar men man kan begär att det sparas i ett annat databas.https://docs.pycom.io/pybytes/
Fig 8
Fig 8a
Fig 8b
# Thinger.io
Har också studerat Thinger.io och registrerar mig i den. Man använder Node-Red där vad jag tyckte om. Har den också ladade i min telefone. Man kan ha data från en databas eller buckets som man skapar och fyller på något sätt. Hade inte en databas jag kunde koppla mig till.
Fig 9
Fig 9a
Fig 9b
Fig 9c
# InfluxDB
Men hade inte en databas, som jag sa ovan, förutom en lokal, och då har jag studerat hela InfluxDB Database API och tutorialen (@Fredrick, denna IoT kursens lärare, hade en länk i Slack).
Försökte det i VSCode, men det gav fel, att den inte hittade influxdb och då fick jag inte InfluxDBClient som behövs för att skapa client som används i alla operationer mot databasen. Versionen av Pyton som jag installerade från Internet, enligt instrutioner från tutorialen, har version 3.8. Versionen som finns i VSCode var inte samma eller det är Micropython som man har där och den har inte det som behövs. Någon sa att kanske det inte finns plats i FiPy:n och liknande.
Vad jag försök:
from influxdb import InfluxDBClient
import sys
print(f"Python version: {sys.version_info.major}. {sys.version_info.minor}")
(version_info.major finns inte i sys på Micropython)
# *Explain and elaborate what made you choose these platforms
Jag har försökte lära mig och testa så många platformer som möjligt.
Har försökte med LoRa men fick ingen kontakt från hos mig. Just nu har jag köpte en LoRa Gateway med 8 kanaler. Fick den igår före presentationerna efter 7 dagar väntan. Så kanske kan jag äntligen använda min koppling till TTN och alla mina projekt registrerade där. Kan testa med att ha bägge Lora och WiFi delar i samma program. Om det inte går att få Lora, så testar man WiFi. Vice-versa i vissa fall.
Testade då med WiFi. Använde såväl min hem Internet och den i mobilen, och testade att gå runt med min mobil och hela systemet och allt gick bra.
Thinger.IO ser intressant ut eftersom man kan använda Node-Red som jag tyckte om. Och man kan använda buckets som jag lärt mig i NoSQL kurs. För att skapa i en InfluxDB måste man skapa olika saker. Från Node-Red kan man göra det och såväll skapa som läsa ifrån alla serier av data.
Kod nedan finns i: https://github.com/MQR/IOTLinneusKurs/blob/master/TutorialCode.txt
Där finns alla Lib filer och kod delar som jag hittat i följande länkar.
DHT11 Kod: https://github.com/iot-lnu/applied-iot-20/tree/master/sensor-examples/DHT11-22
Vibration sensor code: https://github.com/iot-lnu/applied-iot-20/tree/master/sensor-examples/DEMO6%20VibrationSensor
Ubidots: https://github.com/iot-lnu/applied-iot-20/tree/master/network-examples/ubidots
MQTT, : https://github.com/iot-lnu/applied-iot-20/tree/master/network-examples/ccs811-bmp180-dht22-MQTT
# Explain your code!
```python=
#import i2c_read
global pybytes
from network import LoRa
#from network import WLAN
from struct import *
import socket
import json
import time
import read_dht
import pycom
import _thread
from mqtt import MQTTClient
import ubinascii
import hashlib
import machine
from machine import Pin
from machine import ADC
#pycom.pybytes_on_boot(False)
# Ubidots
TOKEN = "BBFF-Htx1sTiobwGzbhFRNAfjl2o17hs9zV" # Put here your TOKEN from ubidots
# The code for MQTT transport protocol
lora = LoRa()
print("DevEUI: %s" % (ubinascii.hexlify(lora.mac()).decode('ascii')))
# Getting the LoRa MAC
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
print("Device LoRa MAC:", binascii.hexlify(lora.mac()))
# Create en OTAA authentication parameters (för LoRa)
THE_APP_EUI = '70B3D57ED0030891' #
THE_APP_KEY = '6D2F91297FBC9C30EAA0C121F23FC1A0' # app key
# End Lora code
# Alarm
Alarm1 = 'P22' # sensor connected to P22.
alrm = Pin(Alarm1, mode=Pin.OUT) # set up pin mode to input
alrm.value(1)
time.sleep(4)
alrm.value(0)
#Vibration sensor
VibSensorPin = 'P16' # sensor connected to P16. Valid pins are P13 to P20.
Pin(VibSensorPin, mode=Pin.IN) # set up pin mode to input
adc = ADC(bits=10) # create an ADC object bits=10 means range 0-705 the lower value the more vibration detected
apin = adc.channel(attn=ADC.ATTN_11DB, pin=VibSensorPin) # create an analog pin on P16; attn=ADC.ATTN_11DB measures voltage from 0.1 to 3.3v
with open('config.json') as f:
config = json.load(f)
##### MQTTClient callback funktion
def sub_cb(topic, msg):
if msg == b'{"Command":"Red"}': pycom.rgbled(0xff0000)
if msg == b'{"Command":"Blue"}': pycom.rgbled(0x0004ff)
if msg == b'{"Command":"Green"}': pycom.rgbled(0x00ff04)
if msg == b'{"Command":"Yellow"}': pycom.rgbled(0xe5ff00)
if msg == b'{"Command":"White"}': pycom.rgbled(0xe5ff00)
if msg == b'{"Command":"Off"}': pycom.rgbled(0x000000)
if msg == b'{"Command":"AlarmOn"}': alrm.value(1)
if msg == b'{"Command":"AlarmOff"}': alrm.value(0)
print((topic, msg))
def interval_send(t_):
while True:
send_value()
time.sleep(t_)
def interval_send_alarm(t_):
while True:
send_alarm(t_)
time.sleep(t_)
def send_alarm(t_):
if apin() < 500:
print(' ****************** Alarm on: 14 seconds - value: ', apin()) # one byte
alrm.value(1)
valtxt = str(apin()) if (apin() < 600) else "0"
c.publish(topic_pub,'{"mqr_office": {"vibration":' + str(apin()) +
',"alarm":' + valtxt +
'}}')
##### Här försöker jag göra så att om man är med hunden och det rycks och larmet startar, så kan man rycka starkt för att stoppa larmet.
time.sleep(6)
#if apin() < 300:
# alrm.value(0)
time.sleep(3)
if apin() < 300:
alrm.value(0)
time.sleep(3)
if apin() < 300:
alrm.value(0)
time.sleep(3)
alrm.value(0)
print('Alarm off: ', 0) # one byte
time.sleep(t_)
def blink_led():
for n in range(1):
pycom.rgbled(0xfcfc03)
time.sleep(0.5)
pycom.rgbled(0x000000)
time.sleep(0.2)
def send_value():
try:
# co2, voc, bmp_P, bmp_T = i2c_read.value()
dht_Tm, dht_RHm = read_dht.value()
val = apin() # read an analog value
time.sleep(1) # wait 1 sec
##### Här skapar jag den sträng som ska publiceras via MQTTClient. Det är en json formaterade data
c.publish(topic_pub,'{"mqr_office": {"temp":' + str(dht_Tm) +
',"rh":' + str(dht_RHm) +
',"vibration":' + str(val) +
',"alarm":' + str(1 if (val < 600) else 0) +
'}}')
print('Sensor data sent ..')
blink_led()
##### Send data to PyBytes
# pybytes.send_signal(1,result.temperature) # optional, sends data to pybyes
# pybytes.send_signal(2,result.humidity) # optional, sends data to pybyes
##### Send data to UBIDOTS
res1 = post_var("fipy-pycom2", result.temperature, 1, result.humidity) # send data to UBIDOTS
##### Send data med LoRa med sockets
payload = struct.pack(">fff", t1, rh1, val)
s.send(payload)
##### Exception behandling
except (NameError, ValueError, TypeError):
print('Failed to send!')
# Builds the json to send the request (för Ubidots)
def build_json(variable1, value1, variable2, value2, variable3, value3):
try:
lat = 57.806209 # latitude # Hemma
lng = 12.065140 # longtitude
# data array creation
data = {variable1: {"value": value1},
variable2: {"value": value2, "context": {"lat": lat, "lng": lng}}, # value - main information, context - additional
variable3: {"value": value3}}
return data
except:
return None
# Sends the request. Please reference the REST API reference https://ubidots.com/docs/api/ (för Ubidots)
def post_var(device, value1, value2, value3):
try:
url = "https://industrial.api.ubidots.com/"
url = url + "api/v1.6/devices/" + device
headers = {"X-Auth-Token": TOKEN, "Content-Type": "application/json"}
data = build_json("temperature", value1, "position", value2, "humidity", value3)
if data is not None:
print(data)
req = requests.post(url=url, headers=headers, json=data) # include data as JSON object
return req.json()
else:
pass
except:
pass
pycom.heartbeat(False) # Disable the heartbeat LED
##### Create a LoRa socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 0)
s.setblocking(True)
##### Här definierar jag broker och topic inom server vart datat ska skickas (För MQTT)
topic_pub = 'mqr/office-sensmqr'
topic_sub = 'mqr/office-sensmqr/control'
broker_url = 'sjolab.lnu.se'
##### Här definierar jag clienten och topic inom server vart datat ska skickas. Det är MQTT transport protocol som definieras här
client_name = ubinascii.hexlify(hashlib.md5(machine.unique_id()).digest()) # create a md5 hash of the pycom WLAN mac
c = MQTTClient(client_name,broker_url,user=config['user_mqtt'],password=config['pass_mqtt'])
c.set_callback(sub_cb)
c.connect()
c.subscribe(topic_sub)
##### Här definierar jag functionen som väntar på att ett meddelande (msg) kommer in. Då exekveras callback funktionen sub_cb
def listen_command(i_):
while True:
c.check_msg()
time.sleep(i_)
# Tidsinterval för att skicka data till
# server när det inte är ett larm är 60s.
# Larm tillstånd verifieras varje sekond och
# data skickas till servern bara med
# Vibrations sensors värde och att larmet ska
# vara 1. Funktionen som väntar på
# inkommande meddelande körs tio gånger per sekond
_thread.start_new_thread(interval_send,[60])
_thread.start_new_thread(listen_command,[0.1])
_thread.start_new_thread(interval_send_alarm,[1])
```
##### The code for Ubidots skickas via HTTP request med POST (Webhook) via WiFi
Data skickas varje 60s i Jason format med setet av par variabel:värde, samt namnet på device som man vill koppla och som definierats inom Ubidots.
##### The code till TTN skickas med Lora och sockets
Man måste definiera Applikationen och den device man vill använda för att skicka data. Man får App-EUI, ApplikationKey och måste ge device nummer för att få en DeviceKey.
Man kan skicka fler gånger än med de andra sättet eftersom Lora använder mindre energi och då håler bateriladdningen längre.
Lora kan också nå längre.
Data i databaserna kan stanna länge och man kan definiera tidsgränserna. Med MQTT Explorer kan man se bara någon tid interval beroende på tiden mellan data punkterna.
##### Till server sjolab.lnu.se skickas da via MQTTClient och publish via WiFi
##### Choice of Database
Grafana och TIG system använder InfluxDB. Den har en tidseries vad som är passande för IoT tidsindexerade datasamlingar.
##### Triggers/Automation
Har trigger i Ubidots för areagränsöverskridande. Gräns för CO2 i Grafana. Automation av alarm ON/OFF i Node-Red från data via MQTT Från/till programmet.
##### Slutresultat och tankar samt möjliga förbättringar eller alternativ.
Det blev en relativ intressant slutresultat. Tänkte höja ljud styrka men det skulle vara dåligt för hunden. Måste försöka reducera volymen den yttersta. Och lägga till GPS som jag redan köpte.

*Video presentation Gjorde presentation live.