---
# System prepended metadata

title: Untitled

---

           Measuring and visualising temperature and humidity
            
Name: Daniel Lidén
Lnu name: dl222tz

*Overview:*
The purpose of this project is to measure temperature and humidity and to visualise the data on the internet. 
To finish this project, it won't take any longer then 1 hour if there are no major setbacks. 
My plan for the course was to go for a little bit higher grade, maybe C. But because elektrokit cannot deliver on what they promise, I never got all the gear that I ordered. All I got was a FiPy device, PySense, battery, and an antenna. And I got this with less then a week left to finish the project. With a full time work I simply didn't have the time or recources to do something more complicated. Therefore I just went with the most basic of project you could imagine. 
For me the purpose of this project was to learn how to send data using LoRaWAN and visualise that data. This will also give me insight in how the temperature and humitidiy fluctuate in my room.

*Materials:*
1 FiPy ∼600kr
1 PySense ∼600kr
1 Antenna ∼140kr
1 USB cable 
1 Computer
1 battery (not necessary)
(maybe a LoRaWAN gateway, dragino for example)

*Computer setup:*
The IDE I have chosen to work with is Atom. Simply because I am familiar with it sense I use it when I program C language. 

Install pymakr plugin to atom and install node.js to your computer. 
Download the PyCom Firmware Updater to make sure the PyCom device has the latest firmware. This guide can be followed to to that: https://docs.pycom.io/updatefirmware/device/
Also the PySense has to have the latest firmware, to do that, just follow this great video tutorial:
https://www.youtube.com/watch?v=FkycTZvj-ss&t=602s&ab_channel=CoreElectronics

*Putting everything together:*
Since I did not have any external sensors or breadboard. All I could do was to connect the FiPy directly to the PySense. And connect the antenna:
![](https://i.imgur.com/TaGUtaK.jpg)

*Platform:*
From what I have heard, The Things Network (TTN) is a great server to send data to via LoRaWAN. That's why I decided to go with TTN. Then I linked TTN with Datacake to be able to visualise the data that the FiPy had sent. Also great news, both platforms are "free", atleast you can do some basic stuff with free accounts. 

*Code:*
boot.py file:
```python=
from network import LoRa
import time
import binascii

lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)

dev_eui = binascii.unhexlify('DDDDDDDDDDDDDDDD')
app_eui = binascii.unhexlify('0000000000000000')
app_key = binascii.unhexlify('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')

lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)

# wait until the module has joined the network
while not lora.has_joined():
    time.sleep(2.5)
    print('Not joined yet...')

print('Network joined!')
```

First I imported all the needed libraries and then selected that I want to activate LoRa with EU868 region. This is to make sure that I send with the correct frequency for my region. 

After this, what I did was to convert dev_eui, app_eui and app_key from hex to binary and put the results in each variable. 

Then I specified that I wanted OTAA (Over The Air Activation) and sent dev_eui, app_eui and app_key as parameters. While waiting for connection to the network, every 2 and a half second I printed "Not joined yet..."". And when that while loop was finished, I let the user know it has successfully joined the network. 

main.py:
```python=
import machine
import socket
import time
import pycom

from pycoproc_2 import Pycoproc
from SI7006A20 import SI7006A20

s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
s.setblocking(False)

pycom.heartbeat(False)

while True:
    py = Pycoproc()
    si = SI7006A20(py)

    temp = round(si.temperature(), 2)
    humidity = round(si.humidity(), 2)

    tempAndHumidity = int(temp*1000000+humidity*100) # combine both in an int
    bytes_to_send = tempAndHumidity.to_bytes(4, 'big') # convert to bytes in big endian order
    s.send(bytes_to_send) # send
    print('sent temperature:', temp)
    print('sent humidity:', humidity)
    time.sleep(1500)     # wait 1500 seconds before sending again
```
This code was taken from from the TTN tutorial in the roadmap. 

As always, the needed libraries are imported. 

When I was finished with the project I wanted the FiPy to measure in my room at night. But the led was blinking very strongly so therefore I used turned of the LED. 

In a while loop i first activated the PySense and with the SI7006A20 library I could get the temperature and humidity values. I only wanted two decimal places, therefore I used the round function. 

Then I combined the temperature and humidity values into one integer. Because it is a integer. I had to make sure that there was no decimal places. Therefore I multiplied both values with a big 10-fold number. Then I could just divide it when I decode the payload later on. This code I got my hands on in the Datacake tutorial in the roadmap. 

Then I converted it to Big Endian order. This is a storage way were the most sigficant value in a byte is stored first. 

After that I sent the temperature-humidity value to TTN, printed that they had been sent and made it sleep for 1500 seconds before sending again. 

Payload decoder:
```python=
function Decoder(payload, port) {
    // we extract the bytes and save them into an integer
    var payload_integer = 0 
    for (var i = 0; i < payload.length; i++) {
        payload_integer = (payload_integer << 8) | payload[i];
    }
    
    // we convert the integer to a string to more easily split it up
    payload_string = payload_integer.toString()
    
    // we split the values up and store them in a list
    values = [payload_string.slice(0,2) 
              ,payload_string.slice(2,4)
              ,payload_string.slice(4,6)
              ,payload_string.slice(6)]
    
    // we put them together and convert to a float
    temp = parseFloat(values[0]+'.'+values[1]) 
    humidity = parseFloat(values[2]+'.'+values[3])
    
    // Finally return the values to be stored in the data fields
    return [
        {
            field: "TEMPERATURE",
            value: temp
        },
        {
            field: "HUMIDITY",
            value: humidity
        }
    ];
}
```

*Transmitting the data / connectivity:*
As mentioned the data is transmitted every 1500 seconds (25 minutes) and it is sent using LoRaWAN. 

A problem that I had was that there were no open LoRa network close to me. Therefore the "Not joined yet..." just kept coming forever. But since I work at Elsys, a sensor developer with LoRaWAN technology, I could quite easily get my hands on a Dragino gateway. 
![](https://i.imgur.com/OSQOncX.jpg)

What I did was to let the gateway connect to my wifi. Then the sensor could send data to my gateway. And then the dragino sends it to my router. The router then sends it to TTN which means the information is now online. 

To visualise the data, Datacake was used. This was very simple to do. All I had to do was to create a webhook on TTN. This requires a Token from Datacake which I can generate there. Done! I could now get my hands on the data in Datacake.

But as we remember, the data is in ones and zeroes. It therefore has to be reverted back to readable data. I used the code from the Datacake tutorial in the roadmap to decode the payload. 

*Presenting the data:*
![](https://i.imgur.com/FrM9Bkz.png)
The dashboard shows the actual value of temperature and humidity. And it also shows how it changes over time. The data is saved every 25 minutes to Datacake. 

The reason I chose Datacake was because it was very easy to connect it to TTN to get my data. Datacake also has a very userfriendly layout which was very customisable. 

*Finalizing the design:*
![](https://i.imgur.com/TaGUtaK.jpg)
![](https://i.imgur.com/ezhmKuh.png)
![](https://i.imgur.com/1mxAxsO.png)
I do not think the temperature sensor of the PySense device is correct. When I had it in my room it reported a temperature of about 35 degrees. And well, it was quite hot in my room. But I definitely do not believe in that number. The temperature clearly went down when I put it in the window, shown in the visualisation. I think one reason for this could be the design of the PySense. When the board is running it produces heat. I think the temperaturesensor is affected by this heat. When I get my hands on an external temperaturesensor I will compare that result with the internal one to see if there are any differences
