owned this note
owned this note
Published
Linked with GitHub
# Remote temperature log with local alarm
Mikael Johannesson, mj224pb
This document is submitted as a project report in the course 'Introduction to Applied Internet of Things', 1DT305, S21 at LNU.
{%youtube 8txhGYXtOMk %}
*My presentation is now available at [YouTube https://youtu.be/8txhGYXtOMk](https://youtu.be/8txhGYXtOMk)*
*00:00 Presentation part 1, finding a problem, defining a solution, device, Pybytes*
*05:08 Azure for IoT*
*10:10 Presentation part 2, challenges, limitations and lessons learned*
On estimated time consumption - supposing that all parts are well known and in working order, like verified libraries, no name conflicts, well known platforms etc., a project like this is suggested to be planned for 30.5 h in total (see below).
## Objective
The goal of this IoT project is to build a node that measures temperature. This node will have local alarms set that will indicate too high and too low temperature. Read data will be transported to a remote IoT server for storage and presentation.
This project has been chosen for the pure reason of learning IoT systems in practice. I chose to measure temperature and humidity as they are easy to manipulate and also, one of the sensors I happen to have available.
Insights I had hoped to get from this project was mainly practical knowledge in how different IoT parts can be put together and a better understanding of all parts and alternatives in a chain from sensors to big data.
A suprising insight is that public LoRa nets are now available almost anywhere in bigger cities!
## Material
The task has been built up mainly by development boards and discrete components as a mockup for a future more permanent implementation in case approved by anyone wanting such a system for a production environment.
### Lab equipment used
* A DC power supply unit, HQ 1503SB (for power supply)
* A DMM, Agilent U3401A (for current consumption measurements)
* A soldering station
* An anti-static mat
* An USB cable
* A battery cassette
### Development cards and components
* Pycon Expansion board
* Pycon lopy4 development board
* Breadboards
* 1 LED, blue
* 1 LED, red
* 2 BC547 NPN transistors
* 2 R 33
* 2 R 1k
* 1 R 4k7
* HW-061 I2C to parallel development board
* 1602 LCD display development board
* DHT11 temperature and humidity development board
* An antenna tuned to 868 MHz
* Dupond wires
* Coaxial wire (for lopy4 - antenna)
### Development costs
#### Laboratory
As always with development kits, components etc., you need an assortment in your lab. As an estimate, a total of 5000 kr has been spent building up a lab with assorted discrete components like leds, transistors, capacitors, voltage regulators as well as different development cards with sensors, communication or microcomputers. Approximately 10000 kr to buy lab equipment like DMMs, cables and power supplies.
As always when buying components, prices consist of handling costs and component costs, thus ordering 100 or 1000 items will render a considerably less unit price than while ordering 1 item. Being able to trace a component to a specific batch and producer will typically also render higher prices.
Components, sensors and development cards have been collected over time from numerous delivers - Mouser, Elfa Distrelect, Wish, Amazon, Ebay, Electrokit, Digi-Key, Kjell & Co et.c.
Costs of components, sensors and development cards actually used on this project is shown below. Prices are for low volume orders:
* Pycoms development kit LoPy4 incl antenna, 849 kr
* DHT11 temperature sensor, 45 kr
* LCD-display kit, 80 kr
* Discrete components, 5 kr
* Dupond wires, 10 kr
* Wireboard, 50 kr
In total, 1039 kr + freight for components and development cards needed to build this project!
#### Licenses
IoT platforms need to be paid. For test- , learning and evaluation most platforms seem to be free for a limited time of usage.
An Azure account has been set up for this project. For evaluation and learning, no costs so far!
#### Time consumption (and cost)
Setting up a new development environment, learning how to use it, learning all features and how to use a never before used development kit (pycom) and to that, finding micro python libraries that actually works with pycom, setting up accounts and learning to use a couple of IoT platforms like Azure IoT as building and installing a new computer will render hours equivalent to several weeks of work.
However, when all MicroPython libraries are evaluated, development environment and IoT platforms have been set up properly and all interfaces for all desired design choices are well known, hours can be calculated:
* Communicating with customer / group, 4 h
* Design phase (decisions, choices, sketches, models), 8 h
* Hardware - ordering, handling, finding and mounting, 4 h
* LoPy4 firmware update, 0.5 h
* Writing and testing LoPy4's Python code, 4 h
* Setting up and testing communication, 2 h
* Setting up storage, PyAzures IoT environment, 8 h
In total, 30.5 h
Labor cost? Suggesting a monthly salary of 40 kkr, 65% overhead costs and 169 h/month, an hourly cost excl vat of 390 kr/h over 30.5 h = 11900 kr.
## Computer setup
The plan was to use my Windows 10 Workstation but due to name- and library conflicts with earlier installed development tools, I had to abandon that idéa. An old Intel i3-based desktop workstation was found in parts in my basement storage and together with a small SSD disk and after quite a bit of boot order and usb port identification problems, I finally managed to install Ubuntu 20.04 LTS Desktop on this hardware. No sound card so Discord discussions and Youtube films need to be handled using my Windows 10 Workstation. Setting my Ubuntu 20.04 LTS up for remote desktop from my Windows 10 Workstation I finally had a computer to use for Pycoms development environment!


I chose to go with Visual Studio Code for my development environment.
Plugins needed for Visual Studio Code to communicate with Pycoms development boards were installed:
* NodeJS
* Pymakr VSCode Extension
A few other programmes were installed as well
* Discord (without sound card)
* Emacs (for editing, no fan of vim)
### Pycom Firmware Installer
Getting Pycom's firmware update software to run properly after installation on a Ubuntu 20.04 LTS turned out to be hard and I finally abandoned that idea. It turned out that I was able to install and run Pycom's firmware updater on my Windows 10 Workstation without any conflicts so by that, my LoPy4 firmware could be properly updated using my Windows machine!
### Where files are stored (when not on my LoPy4)
For some reason, pycom projects are stored in the hidden folder .config on a standard Ubuntu installation, thus making the files a bit harder than necessary to find.
~/.config/Code/User/{project}
A github account has been set up for version control of my ~/.config/Code/User/{project} folder.

### Timeout when uploading main.py
Getting timeout when trying to upload code to my development board is quite time consuming. Several hours of trying to understand why! I still do not know why this happens and restarting my development board obviously won't solve the problem as a new time out will occur when making a new try.

.. alternatively the code failed to read pybytes_config.json

I hope that these problems were for me only and not common for all of you using Pycoms development environment. I spent most of my time programming my LoPy4 on blockers like the ones above!
### Pymakr Console to upload code
Pymakr is a plugin available for Visual Studio Code, it provides a way to send data between Visual Studio Code and any Pycom device using a USB connection.
## Putting everything together
### A development setup
This is obviosly a development setup.
### LED drivers
Recommended output current on a LoPy4 GPIO pin is 6 mA and as I wanted to show some warning signals using LEDs (typically 20 mA) a driver unit is needed.
#### Design
Using a transistor as a switch, the plan is that my LoPy4 GPIO pin should only be loaded with the base current of the transistor, thus well within the 6 mA (12 mA max) LoPy4 current limit. Based on my assortment I chose to go with a small signal NPN transistor, 2BC547.

Circuit diagram showing switched led for 2 mA GPIO current, calculations see below!
#### Electrical calculations
2BC547 is a small signal transistor that can be used as a switch.
$U_{ce}$ sat is 0.6V, 2.1V over my LED and $V_{cc}$ = 3.3V, thus 0.5V left for the current limiting resistor $R_c$. Choosing $I_c$ to 20 mA, $R_c = U_{Rc} / I_c = 0.6 / 20m = 30 \Omega$. From E12 we choose $33 \Omega$ rending a slightly lower LED-current.
Between the GPIO pin and transistor base, we add a 1k resistor as a voltage divider and current limiter between 3.3V 'on' and U_be sat 0.2V.
Building this on a breadboard and measuring power consumption, the load on the GPIO pin is now typically 2 mA which is well within margin.

### DHT11
A simple sensor that uses serial (digital) data for communication with a microcontroller (LoPy4). It measures temperature and humidity.
More in [DHT11 temperature sensor](https://https://components101.com/sensors/dht11-temperature-sensor)
Needs a pull-up resistor for data communication, thus adding a 4k7 resistor from E12 to serial data pin.
### I2C bus
The idea was to locally present current reading using a back-lit lcd display.
Still working on finding a micro python library that actually supports 16x2 lcd displays over I2C for Pycom devices, no luck so far!
### Physical stand
Lacking a 3D printer and a prefabricated Pycom box I decided to go with a traditional mockup solution with the main goal to be able to mount my antenna in a secure way.

A wooden plate, a self made bracket for the antenna and some wood screws later, I solved that problem for my mockup!
### My setup

A photo of my complete setup, now powered by a USB power bank and still sending temp and humidity every 20 seconds. Currently the alarm for too cold (blue led) is active!
#### Circuit diagram

A circuit diagram of my complete setup. Everything is powered using a USB power bank.
#### Power consumption
Microcontrollers like ESP32 (what LoPy4 is based on) typically can be set in a deep sleep mode to be woken up by a timer when work is needed. Such code is reasonable to apply if low power consumption is needed.
This project is not optimized for low power consumption.
An intial estimate of power consumption is 100 mA over 5V (powered over USB, thus not 3.3V).


Connecting a DMM to a modified USB-cable to find out the actual power consumption of this setup, it turned out to be 125 mA, as expected more or less!
Our 5 Ah USB power supply (the red unit) will thus be able to power this device in 5/0.125 h = 40 h.
#### How to reduce power consumption
How often do you need to measure temperature and humidity? Do you really need to activate the I2C bus? The main thing to add to this project is deep sleep mode between measuring and sending data. All together, considerable less power will be consumed using these steps and making the very same power supply power this device for 1000 h would probably be feasible after a low power optimization. Using LoPy optimized for low power consumption over WiFi will obviously also be a good choice.
## Platform
### My grounds for my choices
There are a several different IoT platforms available out there so not an easy choice. Micrsoft do have big development resorces and in recent years, Azure have been a populare place to host servers. Learning how to use Azure in an IoT aspect will be valuable for me as I expect this will be a tool that many companies will be working with for IoT too very soon.
### Pybytes
An account has been created on Pycoms platform making it possible to use Pybytes to collect data from my LoPy4 development board.
The device was added and identified and signals were identified, numbered and labeled.
In the process of adding Pycom development boards to Pybytes, a new firmware that keeps the communication with Pybytes is uploaded to connected development boards.

From pybytes, a MQTT rule to send everything forward to our Microsoft Azure IoT Hub MQTT broker has been set up

### Microsoft Azure
For data storage, we will use Microsoft Azure and a SQL databse! Reasons are mainly due to that it is, in practice, an industry standard today and by that, tools I need to learn to work with.
Three Microsoft Azure products are needed:
* An IoT Hub - a MQTT Broaker more or less
* A SQL database - for storage, shared server version
* A Stream Analytics job - to move data from our MQTT broaker to our database
#### IoT Hub
A Azure IoT Hub has been set up that do recognize my Device. Pybytes has been set up to push data to Azure IoT using MQTT.

#### Do Pybytes relay data to my Azure IoT Hub broker?

Using the built in statistic tool, we can see that 481 MQTT packages has been received so far, thus data is recieved!
#### A Stream Analytics job
Using a Microsoft Stream Analytics Job to fetch data from our Microsoft IoT Hub and deliver it as sql questions to our SQL server!
Setting up a Stream Anlytics job and feeding it with our IoT Device, we finally can se what our Azure IoT broker receives:

#### Database
A Microsoft SQL RDBM has been set up in our Azure cloud for storage. Free for 30 days, 131 kr/month thereafter..
mtjattdb1.databse.windows.net
In this, a database iotdatabase has been set up
Further, using db console and SQL, our storage table can be created with, mostly, nvarchar fields:

```sql=
create table data1 (
signal int null,
payload nvarchar(200) null,
EventProcessedUtcTime nvarchar(200) null,
PartitionId int null,
EventEnqueuedUtcTime nvarchar(200) null,
IoTHub nvarchar(200) null
)
```
By default, my resorces in Azure cannot access my database in Azure, a firewall rule needs to be set to allow this!
When setting up a SQL Database, default is not to allow this. Several hours later, this setting was found! Do set it to [Yes]!

#### Using three Azure objects - data will now be stored!
By that, our Stream Analytics Job can now send data recieved by Azure IoT Hub broaker to our Azure Database. A simple SQL question for results from signal 2 renders the table below
```sql=
select
payload as temperature,
EventProcessedUtcTime as received
from data1
where signal = 2
```

## The code (for our LoPy4)
### Connecting to the world
Using Pybytes as a platform and thus selecting Pybytes 1.6.1 as my LoPy4 firmware plugin, all connections to the world will be made through the settings in my pybytes account for this connected development board.
Thus, while Pybytes 1.6.1 is active, you cannot also connect manually to LoRa or WiFi in boot.py or main.py, this will render conflicts!
Setting up Pybytes as a platform and there registering my LoPy4 development board and when adding credentials for my local SSID of choice, I found that after this, my development card will access internet without me writing any code for wifi or lora in boot.py or main.py! Makes sense in a way I guess!
#### The Things Network
Looking at TTNs covering map, I found that a gateway is available approx 2 km away so I chose to go with this as a backup for WiFi. Using Pybytes, my device will be automatically created and connected to their TTN account.
Reference [Pybytes LoRa](https://docs.pycom.io/pybytes/networks/lora/)

The Things Network covering map, yellow = the location of my LoPy4 device!
#### pybytes_config.json
Using pybytes, my project configuration file will look s below:
```json
{
"networks": [
"wifi",
"lora"
],
"wifi": {
"ssid": "Intranet",
"password": "****"
},
"loraType": "loRa OTAA",
"loraServer": "TTN Server"
}
```
### Included libraries (github links)
A big problem turned out to be finding micro python libraries that actually works with a LoPy4 card. It seems there is no official Pycom code validation plan for libraries with code for different third party development cards, a bit of a drawback!
#### DHT11 temperature and humidity sensor
A working library written by Zoltan Szarvas for this development card works great with LoPy4 and is available at the repository below:
* https://github.com/JurassicPork/DHT_PyCom
#### LCD 16x2-display I2C driver
Several trials to find a working library for this set of development boards connected to Pycom have failed. While writing this, my best choice is to write my own driver but that will be a couple of days so maybe for the final presentation? Still not working but I hope to write my own class later on!
### main py
Below the main.py file that runs on my LoPy4 development board. Obviously a bigger span than 2 degrees between T_MIN and T_MAX would be set in a real situation, for testing in 27 degrees, it's perfect though!
Data is sent to Pycoms platform using, first choice WiFi and second choice LoRa as json packages. The protocol is MQTT.
```python
# Mikael Johannesson, mj224pb
# 2021-08-01
# Remote temperature log with local alarm
# Introduction to Applied Internet of Things, 1DT305, LNU
import pycom
import time
import machine
from dth import DTH
# constants
T_MAX = 28 # high temperature alarm
T_MIN = 26 # low temperature alarm
# led test and initiation
p_too_cold = machine.Pin('P8', mode=machine.Pin.OUT)
p_too_warm = machine.Pin('P4', mode=machine.Pin.OUT)
p_too_warm.value(1)
p_too_cold.value(1)
#i2c bus test
i2c = machine.I2C(0, pins=('P9','P10')) # P9=SDA, P10=SCL
i2c.init(machine.I2C.MASTER, baudrate=100000)
i2c.scan()
#sensor hct-11 initiation
th = DTH(machine.Pin('P23', mode=machine.Pin.OPEN_DRAIN),0)
#2 s to validate that leds will light up as expected!
time.sleep(2)
# main loop 20s
while True:
result = th.read()
if result.is_valid():
temperature = result.temperature
if temperature >= T_MAX:
p_too_warm.value(1)
else:
p_too_warm.value(0)
if temperature <= T_MIN:
p_too_cold.value(1)
else:
p_too_cold.value(0)
pybytes.send_signal(2, temperature)
pybytes.send_signal(3, result.humidity)
else:
pybytes.send_signal(1, "DHT11 error")
time.sleep(20)
```
## Transmitting data / connectivity

Data will flow according to the diagram above. Protocols for communication are written on the arrows. Note that only one communication layer has been written for each arrow!
My Pybytes IoT Broker above could have been avoided and data sent directly from my LoPy4 to my Azure IoT Hub. I did include it as I wanted to understand what it could do but also for convenience as it was easier to have it in between due to nice interfaces.
By chosing both Wifi and LoRa over TTN for my LoPy4, the range is good and I will be able to move my device within any densely populated area and still expect it to be able to communicate with my IoT Broaker.
Obviously, LoRa has been designed for low power consumption and my MQTT packages are quite small so LoRa will be the choice over WiFi if power consumption is to be reduced. Setting a LoPy4 in deep sleep between readings (and transmittings) will also have dramatical effects on power consumption.
### Sensor -> Pycom
A physical one-wire bus with serial data on.
### Pycom -> Pybytes
MQTT over either WiFi or LoRaWAN (over LoRa). WiFi is prioritized
### Pybytes -> Azure IoT Hub
MQTT over Ethernet and Internet
### Azure IoT Hub -> Azure SQL DB
SQL over Internet set up as Azure Job
## Presenting data
### Pybytes
I set my Lopy4 development board to send data to my Pybytes account, showing it as line charts. One can argue that the vertical scale is a bit rough thus needs more work to be easily readable!
Data is sent every 20s. For a production environment less frequent samples are probably a better choice but for this test, it's also valuable to see that data actually is received thus waiting several minutes is impractical!
Pybytes store received data for 30 days. For a test, this is sufficient. For real data, we probably want to store data for longer periods.
#### Received temperatures, line chart

#### Received humidity, line chart

### Azure
Azure is chosen for storage. An SQL database has been set up and do now recieve and store data pushed from our Pycom device.
As a bonus, Azure IoT Hub do provide us with statistics of how our data collection works:

### Choice of database
A Microsoft SQL Database has been set up in my Azure cloud for long time storage and data collection from my sensor.
Using a Microsoft SQL Database was the easyest way for me to solve the problem of making my Stream Job talk to the database. Other RDBMs would have been possible but would have been more time consuming!
### Automation/triggers of data
Triggers are coded in my LoPy4 device for too low and too high temperatures. They affect pin P4 and pin P8 respectively.
## Finalizing design
The task so far has been to set up a mockup using development cards and breadboards.
To finalize this design in a hardware perspective a printed circuit board and housing is needed. Pycom do offer OEM modules for PCB-mounting, their L04 OEM Module seems to be the best choice here!
* https://pycom.io/product/l04-oem-module/
For the front end, work needs to be put towards security to ensure that only authorized people are are able to see the collected data. Maybe data needs to be integrated into an existing customer interface? Microsoft do have a tool for presentation that seems interesting, Microsoft Power BI.
Deep Sleep mode needs to be implemented on the L04 board if low power consumption is an issue.
Azure solutions can be kept as they are set up although licences and server plans needs to be evaluated and optimized.
### Final results
I managed to get sensor data from my sensor to my database, as the plan was!
Working with Azures IoT tools turned out to be a bit tricky in two ways, security settings and that they have a big variety of apps to choose from.


I would have loved finding time to write my own LCD I2C class or finding the 'error' in the existing one and then printing temperature and humidity data locally to this. Due to my problem with my instable computer - LoPy4 connection, this was however not an option as one single upload can take hours of trials.
### Pictures
My breadboard (except LCD driver and display)

My physical mockup battery powered sending data (currently) over WiFi
