# Climate measurement using sensors
[toc]
# Introduction
IoT project by Andreas Granbäck (ag224eu), summer 2022.
This guide will show you how to use different sensors to build an IoT device to measure some common weather parameters. The information will then be sent via wifi to a virtual server that captures the measured values, sends them to a database to finally be presented online. With troubleshooting, varying degrees of headaches and a good interest, it would take approximately 6-8 hours to put the project together.
# Objective
The reason it became a weather station was because I wanted to combine usefulness with pleasure. Firstly, it is fun to build the unit, then it is convenient to have a mobile weather station that can be moved between different rooms. The purpose is to get a better idea of the indoor climate and to learn more about the field of IoT. I think this project will be the start of a long journey of fun and new learnings.
# Material
Below is a list of all the components needed to build the device.
| Object | Function | Price | Retailer|
|:--------|:--------:|------:|---------:|
| Fipy | Microcontroller | 706,12 SEK | [Digikey.se](https://www.digikey.se/sv/products/detail/pycom-ltd/FIPY/7721849?s=N4IgTCBcDaIGYEsAOBPEBdAvkA)
| Pysense | Development board | 28,53 EUR |[Mouser.com](https://eu.mouser.com/ProductDetail/Pycom/Pysense?qs=EU6FO9ffTweZdgO1RoTWIg%3D%3D)
| Battery | Power | 99,90 SEK|[Kjell.com](https://www.kjell.com/se/produkter/el-verktyg/arduino/arduino-tillbehor/luxorparts-li-po-batteri-37-v-med-kontakt-1200-mah-p87924?gclid=Cj0KCQjwntCVBhDdARIsAMEwAClGMlJEQg0ae5Yn4tDKljxaLaXJkgs1aRJU3wipwh4Q8Oyp3QeVc_IaAveGEALw_wcB&gclsrc=aw.ds)
| Device box|Housing | 69,90 SEK | [Kjell.com](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklador/inbyggnadslada-140x110x35-mm-p89064)
| Cables| Connections| 69,90 SEK| [Kjell.com](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/delbar-kopplingskabel-40-pol-15-cm-hane-hane-p87077)
| Breadboard|Simplifies connections| 99,90 SEK| [Kjell.com](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/luxorparts-kopplingsdack-400-anslutningar-2-pack-p36283)
|Antenna|Network access| 80,20 SEK| [Digikey.se](https://www.digikey.se/sv/products/detail/microchip-technology/RN-SMA-4/1643295?utm_adgroup=RF%2FIF%20and%20RFID&utm_source=google&utm_medium=cpc&utm_campaign=Shopping_Supplier_Microchip_0150_Co-op&utm_term=&productid=1643295&gclid=Cj0KCQjwntCVBhDdARIsAMEwACmLTPPzvmT_R5C6CsQ6bo3Z5iq97SFYdB0I_MgYe3EZaQ0IWk4YxvEaAnPfEALw_wcB)
This project uses a microcontroller from Pycom. The model is called Fipy and supports five different networks; WiFi, LoRa, LTE, Sigfox and Bluetooth. The controller is programmed with Micropython, which is a software implementation of a programming language and optimized to run on a microcontroller.

A development card is used to transfer the written code to the microcontroller. This work uses a model from Pycom called Pysense. The reason for this is that the card has five built-in sensors that is able to take in different weather observations that fit well in a weather station.
:::info
:information_source: Temperature, humidity, air pressure and light.
:::

# Computer setup
Before using the hardware, the manufacturer recommends that you upgrade its firmware. A complete guide on how to flash a microcontroller from pycom can be found [here](https://docs.pycom.io/updatefirmware/device/) and the corresponding guide for the development card can be found [here](https://docs.pycom.io/updatefirmware/expansionboard/)
When the hardware is updated, it is ready to receive code. To send code to a microcontroller, you most suitably use an IDE that is capable of connecting to a device via USB. This guide uses [Atom](https://atom.io/) atom and is running on Ubuntu 22.04

To be able to connect to the controller and send code to it, we need to do a few things.
1. In Atom we need to install a plugin called Pymakr. Pymakr installs a REPL (Read-Eval-Print-Loop), which acts as an interactive shell where you can write code directly or upload entire projects to your microcontroller.

2. Your user must belong to the dialout group. This is necessary for you to be able to connect to the controller and is most easily done with the usermod command. Keep in mind that you will need sudo rights to do this.
:::info
:information_source: sudo usermode -a -G dialout username
:::
When you are connected to the microcontroller, you will come to a prompt consisting of '>>>', this means that you are connected. To see that everything works as it should, you can test a simple addition to see that the controller can perform calculations

If you want to run more durable code on your microcontroller, you must create and upload a project catalog in atom. In the project directory you create a subdirectory named lib and two .py files, boot.py and main.py. The lib directory will contain the various libraries that will be needed. When the hardware boots, the microcontroller reads files in a certain order. The first file that is read is boot.py and contains code to run at boot, such as network settings. When the boot process is complete, it continues reading code contained in main.py. This file contains all the code that does not need to be run at boot and is your main code.


# Putting everything together
The microcontroller could be attached directly to the pysense. That way we wouldn't need any cables at all. A problem with that solution is that the microcontroller generates a certain amount of heat which affects the temperature sensor in the board. So another approach is to attach the microcontroller to the breadboard and add cabling to be able to communicate with it. This way not only have we separated the fipy from the pysense, but we also made it possible to add extra sensors. The antenna can be connected to two places, on each side of the board. Connect the antenna to the connector on the bottom left, looking at the picture, for wifi connectivity. The top left antenna connection can be used if you want to connect using, for example LoRa.

# Platform
I have chosen to run my platform on my own virtual machines. I chose this alternative as I already had a virtual environment up. Below is a description of a platform based on TIG with MQTT. TIG is a combination of three applications. Telegraf, Influxdb and Grafana.
* **Telegraf**
[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/) is an agent for collecting and sending data from various systems and devices, such as sensors. It is this application that captures the measured values from the sensors.
* **InfluxDB**
[Infludb](https://www.influxdata.com/) is a database that is adapted to store data in time series. Telegraf sends the current measured values to the database together with a timestamp.
* **Grafana**
[Grafana](https://grafana.com/) is the tool we use to visualize the results. It is based on open source and draws colorful graphs in all different shapes. Grafana has a connection to the database where the measured values are located and updates the graphs automatically.
* **MQTT**
[MQTT](https://mqtt.org/) is a lightweight publish / subscribe messaging protocol that is widely used in low bandwidth environments, such as in IoT. It consists of a broker (server) and clients (sensors). In order for the measured values to reach the telegraph and the database, they are sent with this protocol. Both the sensors and telegraph thus communicate with the broker.
This project uses [mosquitto mqtt broker](https://mosquitto.org/).
To set up your own broker server, try this [guide](https://appcodelabs.com/introduction-to-iot-build-an-mqtt-server-using-raspberry-pi)
:::info
[Here](http://www.steves-internet-guide.com/mqtt-works/) is a guide if you want to learn more about MQTT
:::
:::info
[Complete](https://onlyoneaman.medium.com/how-to-install-tig-stack-telegraf-influx-and-grafana-on-ubuntu-405755901ac2) guide for setting up the TIG-stack on ubuntu.
:::
# The code
:::info
The complete [code](https://github.com/granback/IoT) can be found on github!
:::
| Libraries used | Note |
|----------------:|--------------------:|
|[pycoproc_2.py](https://github.com/pycom/pycom-libraries/blob/master/shields/lib/pycoproc_2.py)|Expansion board|
|[MPL3115A2.py](https://github.com/ControlEverythingCommunity/MPL3115A2/blob/master/Python/MPL3115A2.py) |Pressure sensor|
|[mqtt.py](https://github.com/pycom/pycom-libraries/blob/master/lib/mqtt/mqtt.py) |mqtt|
|[SI7006A20.py](https://github.com/brocaar/pycom-examples/blob/master/pysense-example/lib/SI7006A20.py) |Temperature sensor|
As mentioned before, the first file parsed is boot.py In this file we keep out wifi settings.
First we import the necessary libraries, in this case WLAN, since were running wifi.
This network is configured with a static ip address.
```python:
import machine
from network import WLAN
wlan = WLAN()
if machine.reset_cause() != machine.SOFT_RESET:
wlan.init(mode=WLAN.STA)
wlan.ifconfig(config=('192.168.10.50', '255.255.255.0', '192.168.10.1', '192.168.10.1')) # (ip, subnet_mask, gateway, DNS_server)
```
When boot.py has been run the code in main.py is read.
We also have a few necessary imports in this file:
```python:
import time
import machine
import pycom
from pycoproc_2 import Pycoproc
from mqtt import MQTTClient_lib as MQTTClient
from network import WLAN
from SI7006A20 import SI7006A20
from MPL3115A2 import MPL3115A2,ALTITUDE,PRESSURE
```
Defines the client id and the addess to the broker server
```python:
def sub_cb(topic, msg):
print(msg)
client = MQTTClient("sensor", "192.168.10.30", port=1883, keepalive=300)
client.set_callback(sub_cb)
client.connect()
```
Below is the code for creating variables for the different functions.
The main code of the program is run in an endless loop.
```python:
while True:
temperature = si.temperature()
pressure = mpp.pressure()
humidity = si.humidity()
battery_left = py.read_battery_voltage()
client.publish(topic="Temperature", msg=str(temperature))
client.publish(topic="Pressure", msg=str(pressure))
client.publish(topic="humidity", msg=str(humidity))
client.publish(topic="Battery", msg=str(battery_left))
time.sleep(300)
```
The first 4 lines reads the sensors and stores the values in the variables and the 'client.publish' sends the data to the MQTT broker for telegraf to scrape. The last line pauses the loop for 5 minutes before is restarts.
# Presenting the data
Access your grafana instance by typing in the ip address of the grafana server with the port 3000.
Grafana uses dashboards to present the data. To create a dashboard we first have to establish a connection to the database.
To do that we need to set up a new datasource. Keep the mouse over the configuration tab to the left, click **data source -> add data source -> InfluxDB**
Fill in ip address and port to the database

My database is called telegraf and the username to access it is admin.

When you have entered your credentials, Press 'Save & test' to verify connectivity.

When you have established a connection to the database you can create your first dashboard.
Click the plus sign on the bar to the left and click dashboard.

Click 'Add new panel' to create a graph.

On the 'FROM' line, select the database table that contains the data you wish to visualize

Select the correct value

Grafana is very versatile and and comes with many options.
Blow is the dashboard showing the metrics from the weatherstation created in this project.
This dashboard shows data for the past 6 hours and updates every 10s. The database witht the current configuration stores the data forever.

# Finalizing the design
So, here's the result. It works fine. But in the future it would be nice to change the casing to a box where you can attach the cards. That would also make it possible to make a hole for the USB cable, if i need to change the code, without having to open it. Also to get a more correct reading from the sensors, some ventilation holes have to be drilled. The code can also get improvements, for example to add the functionality that the microcontroller resets when there is an error, or add some triggers in grafana to generate messages to a discord server. Sky's the limit.

