---
title: 'IoT Tutorial'
disqus: hackmd
brake: false
---
# Tutorial on how to build an IoT Dog-Watcher
**Author:** Alexander Pennerup Nilsson
**Student credentials:** ap22kr
This tutorial aims to present how you can create an active listening and sensing device, to monitor if a dog is barking in the hallway. Using Ubidots for our dashboard and triggering events notifying you by email. All packaged in a 3d-printed case.
**Time:** 18h (3D-printing included)

Fig.1 Front of Dog-Watcher IoT-Device
## Objective
I recently moved into a new apartment and my dog was quite anxious of all the new sounds coming from the stairwell. So i wanted to create a device that could monitor if he was barking in the hallway, and notify me if that was the case. The project presents a great way of how if-conditions can create a chain of events that is only transmitted when a user needs to be notified under certain conditions.

Fig.2 The dog in question
### How will this work?

Fig.3 Project overview.
1. The Pycom device will communicate with the microphone module checking for barking.
2. If there is a loud sound, the ultrasonic sensor module will check if the dog is in the hallway.
3. If there is a presence (Dog), The Pycom will send a set value to Ubidots IoT platform.
4. The platform will check the value through a set trigger value.
5. If the value is equal to the trigger value, we will receive an email notifying us that the dog is in the hallway barking.
## Material
### List of materials
**Device:**
| Material |Amount | Price | From|
| :--------:|:------: | :--------: | :--------:|
| Lopy4 | 1 | €35.00 |Pycom [Lopy4](https://pycom.io/product/lopy4/)
| Expansion Board 3.0| 1 | €16.00 |Pycom [Expansion Board 3.0](https://pycom.io/product/expansion-board-3-0/)
| Ky-038|1| €53.00 | Playknowlogy [Small microphone module](https://www.kjell.com/se/produkter/el-verktyg/arduino/moduler/playknowlogy-stora-modul-paketet-for-arduino-p87291) <br> (Part of a set of sensors)
| Hy-srf05|1| In the same set as Ky-038 | Playknowlogy [Ultrasonic sensor module](https://www.kjell.com/se/produkter/el-verktyg/arduino/moduler/playknowlogy-stora-modul-paketet-for-arduino-p87291) <br> (Part of a set of sensors) |
| Breadboard|1 | €6.00 | Elektrokit [Breadboard](https://www.electrokit.com/produkt/kopplingsdack-400-anslutningar/) |
| Micro-usb cable|1 | €13.00 | Kejll o Company[ Micro-usb cable](https://www.kjell.com/se/produkter/mobilt/kablar-adaptrar/micro-usb-kablar/micro-usb-kabel-18-m-p68688)
| 5W power adapter|1 | €26.00 | Apple 5W usb[ power adapter](https://www.kjell.com/se/produkter/mobilt/mobilladdare/usb-laddare/apple-usb-stromadapter-pa-5-w-p99719?gclsrc=aw.ds&&gclid=CjwKCAjwxev3BRBBEiwAiB_PWNATE5Xs-JhMba-kP91aua1QpUE4JDbc5Q9P9TuId07k-xJPnFPiPRoCUNsQAvD_BwE) |
| Jumper Wire male-female|7 wires | €8.00 | Kjell o Company <br> jumper wire [ male - female](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/delbar-kopplingskabel-40-pol-15-cm-hane-hona-p87076) |
| Jumper Wire male-male|4 wires| €8.50 | Kjell o Company <br> jumper wire [ male - male](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/kopplingskablar-hane-hane-65-pack-p87212)
<br>
**Case:**
| Material |Amount | Price | From|
| :--------:|:------: | :--------: | :--------:|
| Flashforge Adventurer 3 <br> 3D printer | 1 | €400.00 |[Flashforge Adventurer 3](https://www.flashforge.com/consumer/detail/Adventurer%203?id=3)
| Add:North e-pla <br> Glitz grey filament | 1 | €26.00 |3D printer filament [add:north glitz grey](https://addnorth.com/sv/shop/product/ANEP17GLG) <br> (Approx. 45 meters needed to print the whole case )
### Material descriptions
### Device:
**Lopy4**
For the Wifi connectivity and communication in this project, a Lopy4 from Pycom is used. It's a smart micropython-programmable board that can connect to Wifi, Sigfox, LoRa, and Bluetooth. A nifty little device for IoT projects.
Fig.4 Pycom [Lopy4](https://pycom.io/product/lopy4/)
**Expansion Board 3.0**
The Expansion Board 3.0 from Pycom gives the project the ability to connect the Lopy4 to an IDE. With plenty of connections to choose from, we can connect our sensors and power supply, giving us all we need to create our project.
Fig.5 Pycom [Expansion Board 3.0](https://pycom.io/product/expansion-board-3-0/)
**KY-038**
Small microphone module that is actively listening for sound above a set threshold. Making it possible to detect barking.
Fig.6 Playknowlogy [Small microphone module](https://www.kjell.com/se/produkter/el-verktyg/arduino/moduler/playknowlogy-stora-modul-paketet-for-arduino-p87291)
**Hy-srf05**
Ultrasonic sensor to measure the distance from the device to object. Making it possible to detect if the dog is near.
Fig.7 Playknowlogy [Ultrasonic sensor module](https://www.kjell.com/se/produkter/el-verktyg/arduino/moduler/playknowlogy-stora-modul-paketet-for-arduino-p87291)
**Breadboard**
Breadboard 400 tie-Points with 4 power rails for connection between Expansion Board 3.0 and sensors.
Fig.8 [Breadboard](https://www.electrokit.com/produkt/kopplingsdack-400-anslutningar/)
**Micro-usb cable**
Used to connect Lopy4 and Expansion Board 3.0 to PC and as a cable for the usb power adapter to the device.
 Fig.9 [ Micro-usb cable](https://www.kjell.com/se/produkter/mobilt/kablar-adaptrar/micro-usb-kablar/micro-usb-kabel-18-m-p68688)
**5W usb power adapter**
Used for connecting device to the wall socket.
Fig.10 5W usb[ power adapter](https://www.kjell.com/se/produkter/mobilt/mobilladdare/usb-laddare/apple-usb-stromadapter-pa-5-w-p99719?gclsrc=aw.ds&&gclid=CjwKCAjwxev3BRBBEiwAiB_PWNATE5Xs-JhMba-kP91aua1QpUE4JDbc5Q9P9TuId07k-xJPnFPiPRoCUNsQAvD_BwE)
**Jumper wires**
Used for connecting pins to breadboard and sensors. Male - Female go directly to sensor pin, and Male - Male from board to breadboard.
Fig.11 Jumper wire [ male - female](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/delbar-kopplingskabel-40-pol-15-cm-hane-hona-p87076)
Fig.12 Jumper wire [ male - male](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/kopplingskablar-hane-hane-65-pack-p87212)
<br>
<br>
### Case (not necessary):
If you want to print the case you need a 3D-printer and filament. I used a flashforge adventurer 3 and add:north e-pla. The files for the case made by me can be found [here](https://www.thingiverse.com/thing:4511890) on thingiverse.
**Flashforge Adventurer 3**
 Fig.13 3D printer [Flashforge Adventurer 3](https://www.flashforge.com/consumer/detail/Adventurer%203?id=3)
**Add:North e-pla**
Fig.14 3D printer filament [add:north glitz grey](https://addnorth.com/sv/shop/product/ANEP17GLG)
## Computer setup
**Flashing device:**
To get started working on the project you need to install the right drivers and update the firmware to the latest version. To do this you need to follow these two guides:
[Drivers](https://docs.pycom.io/gettingstarted/installation/drivers/)
[Firmware](https://docs.pycom.io/gettingstarted/installation/firmwaretool/)
**Atom IDE:**
This project will use Atom, which is a free and open-source code editor. It features a lot of plugins and GiTHub integration. This is the software i used to write all the code to program the device.
Get it [here](https://atom.io/), and install on preferred platform. I am using a PC with Windows 10.
**Pymakr plugin:**
The Pymakr plugin enables Atom to communicate with your Pycom board using the command line. You can easily execute command directly or upload your project.
 Fig.15 Atom, an overview of installing Packages
In Atom click on install package and then search for pymakr to install the plugin.
**Uploading code in Atom with pymakr:**
Once you have installed everything mentioned above (drivers, firmware, atom and pymakr) you can start to work on your project.
To upload your project on to the Pycom device, make sure the device is connected to your computer (I am using the micro usb cable connected to my PC) and press the upload button in Atom.

Fig.16 Uploading to Pycom device
## Putting everything together
The device is easy to set up and is mostly suited for a development setup, because of no soldering and usage of the breadboard.

Fig.17 Circuit diagram
### Power, GND and 3v3:
From the micro usb connector on the Expansion Board 3.0, we connect a micro-usb cable to a usb power adapter.
As a standard USB is giving us a voltage of 5v. So the power adapter connected via the micro-usb cabel is giving us sufficient amount of voltage, but not too much because of the max voltage for Lopy4 being 5.5v.
****Using jumper wire male - male****
* Connect GND pin to ground (-) in the breadboard.
* 3v3 on board to + on breadboard. (
### Ultrasonic Sensor:
****Using jumper wire male - female****
* Connect GND to - on the breadboard.
* Echo to G2 on the breadboard.
* Trigger to G20 on the breadboard.
* Vcc to + on the breadboard
****Using jumper wire male - male****
* Connect F20 to P20 on the Expansion Board 3.0
* Connect F20 to P21 on the Expansion Board 3.0
### Small microphone module:
****Using jumper wire male - female****
* Connect AO to P14 on Expansion Board 3.0
* Connect G to - on breadboard.
* Connect + to + on breadboard.
### Calibrating microphone sensor
For the microphone sensor module to work correctly and to find what value to put in for the threshold, please watch this video:
<iframe width="560" height="315" src="https://www.youtube.com/embed/CbovaHqvdsM?start=210" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Platform

This project is using [Ubidots STEM](https://ubidots.com/stem/) as its IoT platform. I am using their free alternative, but you can add balance to unlock extra capacity and features such as SMS. I find this platform to suit my needs the best when looking for an alternative that offers easy setup and data-management.
A good thing to know is that Ubidots also offers paid subscriptions, letting you scale your project easily if you want.
**Functions:**
* The platform offers a **free** alternative for non-commercial projects, with up to 3 devices.
* The platform is **cloud-based**, letting you send data from any internet-enabled device.
* It offers the ability to create actions, alerts, dashboards, and it can both **write** and **recive** data using their API.
* The platform **supports Pycom devices** and you can use wifi, LoRa , and SIgfox to connect to the service.
## The code
 Fig.18 My project folder
**main.py** (To read microphone value and trigger event to read distance value using the ultrasonic sensor)
```python=
from network import WLAN # Connecting to Wifi
import urequests as requests # Library for Ubidots, see guide for Ubidots setup
import machine
import pycom
import time
from machine import ADC # Analog reading of pins
from machine import Pin # To initialise Pin reading
from machine import Timer
import math
# Read Ubidots guide, and input necessary code for ubidots setup and variables here!
# Initialize `P14` in gpio mode and make it an Input
adc = ADC()
mic = adc.channel(pin='P14', attn = ADC.ATTN_11DB) # Setting microphone pin
echo = Pin('P20', mode=Pin.IN) # Setting echo pin for ultrasonic sensor
trigger = Pin('P21', mode=Pin.IN) # Setting trigger pin for ultrasonic sensor
trigger(0)
chrono = Timer.Chrono()
pycom.heartbeat(False) # No heartbeat LED
pycom.rgbled(0x00007f) # Set led blue
# Reading microphone value and reducing output value to 0 decimals
def read_mic():
return min(max(int(round(mic.value()/15.0)) - 44, 0), 127)
def bark():
# if statement setting threshold for ultrasonic sensor readings
if read_mic() <= 78:
return int(0) # Giving output value 0 when there is no sound over set value
time.sleep_ms(1)
elif read_mic() >= 79:
# Calculating distance from sensor when microphone pick up sound over set threshold
def distance_cm():
chrono.reset()
trigger(0)
time.sleep_us(2)
trigger(1)
time.sleep_us(10)
trigger(0)
while echo() == 0:
pass
chrono.start()
while echo() == 1:
pass
chrono.stop()
chrono.read_us()
pulse_time = chrono.read_us()
cms = (pulse_time) / 58 # converting to distance in cm, can be used as exact value from sensor
return cms
def distance_guard():
# initialise the list
distance_samples = []
# take 10 samples and append them into the list
for count in range(10):
distance_samples.append(int(distance_cm()))
# sort the list
distance_samples = sorted(distance_samples)
# take the center list row value (median average)
distance_true = (min(distance_samples))
# apply lowest value for threshold
if distance_true < 20:
return int(10) # if dog is close enough to set threshold, send 10 as value output
elif distance_true > 20:
return int(0) # if dog is not close enough to set threshold, send 0 as value output
return int(distance_guard())
while True:
print(read_mic()) # Showing output microphone reading for calibration
Dogo = bark() # Setting function value to variable
post_var("pycom", Dogo) # Sending variable output from sensor chain
time.sleep(15) # Pausing process, making device send data every 15s = 4 times a minute
```
**Additional** **main.py**, **boot.py**, and **urequests.py** (Connecting to Ubdidots)
To enable the connection between the readings from our sensors to the Ubidots platform, we need to connect our Pycom device to the service and add additional code to our main.py, boot.py, and create urequests.py.
Follow [this guide ](https://help.ubidots.com/en/articles/961994-connect-any-pycom-board-to-ubidots-using-wi-fi-over-http) on the Ubidots website to set up the connection.
Keep in mind that the preset code from ubidots adds additional variables in the main.py. I changed it into:
```python=
# Builds the json to send the request
def build_json(variable4, value4):
try:
lat = 6.217
lng = -75.567
data = {variable4: {"value": value4}}
return data
except:
return None
# Sends the request. Please reference the REST API reference https://ubidots.com/docs/api/
def post_var(device, Value4):
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("Dogo", Value4)
if data is not None:
print(data)
req = requests.post(url=url, headers=headers, json=data)
return req.json()
else:
pass
except:
pass
```
## Transmitting the data/connectivity
The program is written so that it sends data from the Pycom device to Ubidots **4 times** a minute ( every 15 seconds). The value output is set to either **0** or **10** to make a clear difference between if the conditions are met or not in the dashboard.
The dog-watcher is never meant to be anywhere except in my apartment. This opens up the ability to rely on **WiFi** as my wireless protocol. To communicate between my pycom device and Ubidots platform I use **HTTP** as my transport protocol, as stated in [this guide ](https://help.ubidots.com/en/articles/961994-connect-any-pycom-board-to-ubidots-using-wi-fi-over-http) we used for setting up Ubidots connection in the code chapter.
## Presenting the data
### Dashboard:

Fig.19 Line chart as my Ubidots dashboard
For my dashboard I setup a line chart presenting triggered events from my program. Because I have set the output value to either **0** or **10**, the dashboard will only present **highs** or **lows** in the line chart. This makes it really easy to read when and how many times the dog barked in the hallway. This is sent, saved to the dashboard **4 times a minute**, and is **preserved for a month** on the Ubidots platform.
The main reasoning behind using Ubidots was not the real need of a good dashboard, even if it provides a nice touch and lets me share the info with my girlfriend. I am mostly using it for the ease of use when it comes to triggering events to **notify me when the dog is barking.**
<br>

Fig.20 Email alert from Ubidots notifying me
I set the ubidots email as a VIP in my phone and activated notifications to alert me when the dog is barking.
### Setup dashboard and events:
**Dashboard and widgets:**

Fig.21 Dashboard setup
* 1. On the ubidots website click Data - dashboard and then the + to create a new one.
* 2. Input general information such as name, etc.
* 3. Once created we add a new widget.
* 4. Select preferred widget (I used a line chart).
* 5. Add a variable
* 6. Select the created variable from the code ( In my case Dogo), and accept.
<br>
**Events and triggers:**

Fig.22 Trigger setup
* 1. On the ubidots website click Data - events and then the + to create a new one.
* 2. Set triggers to liking ( In my case when "Dogo" is equal to the set value of 10)
* 3. Click to add a new action.
* 4. Continue and pick the desired action ( I use email).
* 5. Provide your email and what you want as your message.
* 6. Set timespan and accept.
## Finalizing the design
### Final results:
I have been testing the device for a couple of days, and the dog-watcher does succeed in what it is supposed to do. No errors have been found yet.I am impressed on how fast the Ubidots platform is reacting to triggers and sending emails to notify. It is easy to alter the code and change its threshold for different volumes and distances, making it possible to change the purpose or adapt to different sized rooms. Overall it is an easy-going and fun project using if-statements to trigger notifications based on its surroundings.
I am happy with the result and I hope you enjoyed reading this tutorial!
### Things that could be improved upon:
* Implementing an on/off switch for using the device only when not at home (without unplugging the device).
* Trying other sensors more fitted for this type of project? (PIR sensor, etc.).
* Using a battery to power the device. Making it easier to move around and not dependent on a socket.
* Experimenting with trigger email frequency.

Fig.23 Overview of the final result

Fig.24 Front of dog-watcher

Fig.23 Open dog-watcher case