# Tiny weather station
*Maja Åstrand - ma226fk*
This tutorial will demonstrate how to set up a tiny weather station with a LoPy4. Temperature, humidity and rain will be measured and sent over Sigfox and be presented on Ubidots.

Figure 1: Tiny weather station
The estimated time without any major obstacles will be around **4 hours** and the cost for the project around **900 sek**.
---
### Objective
When I decided on this project I was aiming for learning the basics in the field of Internet of Things (IoT). The purpose of the project is for you to learn a little bit of everything and in the meantime get information of the weather which we Swedes loves to talk about.
In this project I have used both analog and digital sensors and connected two different sensors to the microcontroller which will give you an understanding of the basics for setting up and exploring your device.
This project is very easy to make even more complex with more sensors that could be useful for measuring weather, for example wind speed. So hopefully with this tutorial, you will gain a bigger understanding and confidence in setting up your own IoT project!
### Material
| Item | Link | Price (sek) |
| -------------- | ------------------------------------------------------------------------------------------------------------------ | ----- |
| LoPy4 | [Pycom](https://pycom.io/product/lopy4/) | 392 |
| Expansionboard | [Pycom](https://pycom.io/product/expansion-board-3-0/) | 180 |
| Antenna | [Pycom](https://pycom.io/product/lora-868mhz-915mhz-sigfox-antenna-kit/ ) | 92 |
| Micro USB | [Kjell.com](https://www.kjell.com/se/produkter/mobilt/ladda-koppla/kablar-adaptrar/micro-usb-kablar/micro-usb-kabel-1-m-p68687) | 100 |
I have used the LoPy4 microcontroller together with the 3.0 expansion board which includes one year of Sigfox, a wireless connection platform, but it's also suitable for connection with Wi-Fi, Lora and Bluetooth. I have also used an antenna which can connect with Sigfox and Lora and as you will be using Sigfox in this project the antenna is needed. To connect the microcontroller to the computer through the expansion board a micro-USB is needed.

Figure 2: Items
| Item | Link | Price (sek) |
| --------------------- | ----------------------------------------------------------------------- | ----- |
| Humidity senor, DHT11 | [Electrokit](https://www.electrokit.com/produkt/temp-fuktsensor-dht11/) | 39 |
| Rain sensor | [Electrokit](https://www.electrokit.com/produkt/regnsensor/) | 39 |
| Wires | [Electrokit](https://www.electrokit.com/produkt/labbsladdar-100mm-hane-hane-30-pack/) | 33 |
| Breadboard | [Electrokit](https://www.electrokit.com/produkt/kopplingsdack-400-anslutningar/) | 59 |

Figure 3: Items
As mentioned above you will be measuring the temperature, humidity and rain. For measuring the temperature (Celsius) and humidity (Relative humidity (RH) %) I have used the DHT11 which is a digital sensor with a accuracy of +/-5% for the humidity and +/- 2 C for the temperature. As for measuring the rain I have used a rain sensor which is both analog and digital. I encountered a few problems with the analog part which I will explain more in section *Finalizing the design*. To connect everything male wires are needed and a breadboard will make everything easier.
### Computer setup
Now it’s time to get your computer ready!
**Step 1: Updating the expansion board**
You might need to update the expansion board. I did not have to do that but if you do follow [this](https://docs.pycom.io/updatefirmware/expansionboard/) guide.
**Step 2: Update the firmware of your LoPy4**
A firmware update will be needed sometime during the project. Download the firmware updater from [here](https://docs.pycom.io/updatefirmware/device/) and follow the guide. Remember to close down your atom when updating! I used to do this update at anytime I had some problems I couldn’t solve (as I am a bit of a beginner myself I don’t know if it’s the 'school-books' way of solving issues but it worked almost every time! :) .
**Step 3: Install IDE and start to give your device some code!**
As for IDE for this project I have used Atom mainly because it was recommended by teachers and it seemed simple to use. Download Atom from [here](https://atom.io/). And also download the latest python from [here](https://www.python.org/). Next step is to install pymakr on Atom, follow the steps below. After that you are ready to start a new project!

Figure 4: Install pymakr
**Note:** I am using Windows 10 and did have some problems with this step. I got an error message that Atom couldn’t find Python. If you get the same issue follow the tips on [this](https://hackmd.io/@lnu-iot/rk4qNlajd#2-Setup-on-your-computer) page under "Known issues". Now everything should be ready to run! I recommend trying out the program on [this](https://hackmd.io/@lnu-iot/rk4qNlajd#2-Setup-on-your-computer) page under "Make LED blink" to see that everything is running smoothly.
### Putting everything together
Now it's time to connect the sensors with your LoPy4. For both the sensors there are good datasheets that explain how to connect them. [Here](https://www.electrokit.com/uploads/productfile/41015/41015744_-_Rain_Sensor_Module.pdf) is the datasheet for the rain sensor and [here](https://www.electrokit.com/uploads/productfile/41016/DHT11.pdf) is the datasheet for the DHT11. In general, all sensors need to be connected to a voltage source to power the sensors and additionally be connected to ground for allowing the current to run through. For both the DHT11 and the rain sensor 3V3 is used for voltage and GND as ground. As for getting some data out of the sensors the methods differ a bit.
**Rain sensor**
The sensing pad can measure the resistance that varies depending on the amount of water it is sensing. From reading the resistance an output voltage is produced. **Low resistance represents more water and vice versa.** The analog output reads the voltage level and gives a value between 0 and 1023 (depending on how many bits you are using). Where 0 represents very wet. 1023 is supposed to represent dry but in my experience 500 represented very dry. The digital output will give the value 1 or 0 which is dependent on whether the voltage is high or low according to the threshold. **0 represents low and means that water is detected and 1 represents high where no water is detected.**

Figure 5: Rain sensor module
**DHT11**
The DHT11 is a digital sensor. As for measuring the humidity it reads the resistance between electrodes inside the sensor which varies with the humidity. It is the same principle for the temperature part where the resistance decreases with higher temperature. I recommended [this page](https://howtomechatronics.com/tutorials/arduino/dht11-dht22-sensors-temperature-and-humidity-tutorial-using-arduino/) to learn more about this sensor.

Figure 6: DHT11 sensor
For connecting everything please follow the picture below. I have used this color scheme:
GND - Green (ground)
VCC - Red (power)
DO - Blue (digital output)
AO - Black (analog output)

Figure 7: Picture created with Fritizing
I would say that this set up is only for non-commercial use.
### Platform
Now you want to store your data somewhere and there are loads of options! During this project I tried out two different set ups.
**Pybytes**
Pybytes is very easy to set up with your pycom device as it's pycom's own platform. I think it was a great beginner platform and I could experiment a bit about how to visualize the data but I didn’t fully enjoy the aesthetics of it and I also wanted to explore more options. If you want to use Pybytes [this](https://docs.pycom.io/pybytes/gettingstarted/) is a good tutorial.
**Ubidots**
For this project I choose to use the cloud based platform Ubidots mainly because of it's layout and aesthetics and also because it worked easily with Sigfox. There is a free option if you are student, choose the STEM version. It allows you to connect **3 devices** and is for **non-commercial use.** If you'd like to scale your project it works fine for non-commercial use but there is an extended version if you want to upgrade. I also liked the idea of being able to create alerts and alarms through email (although I did not end up setting that up). I will explain more below in section *Presenting the data* how to set up Ubidots together with Sigfox.
### The code
The code for this project is fairly easy and you can easily adjust it for your liking or add commands.
This is how I have structured my files:

Figure 8: File structure
* Inside my **lib folder** I have the library for the DHT11 sensor which I have got from [here](https://gitlab.lnu.se/1dt305/sensor-libs/-/blob/master/DHT11%20&%20DHT22%20-%20Humidity%20&%20Temperature%20Sensor/lib/dht.py).
* Inside my boot.py file I got configuration set up for Ubidots with code used from [here](https://help.ubidots.com/en/articles/694725-connect-a-pycom-sipy-to-ubidots-using-sigfox-over-http):
``` python
from machine import UART
import machine
import os
uart = UART(0, baudrate=115200)
os.dupterm(uart)
machine.main('main.py')
```
* And the rest of the code is inside the main.py file where it starts with importing the device and other packages:
```python
from network import Sigfox
import socket
import struct
import time
from machine import Pin
from dht import DHT # https://github.com/JurassicPork/DHT_PyCom
```
* Followed with set up of Sigfox with code used from [here](https://hackmd.io/@lnu-iot/SyUxJU7puhttps://).
```python
# init Sigfox for RCZ1 (Europe)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1)
# create a Sigfox socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
# make the socket blocking
s.setblocking(True)
# No downlink - set FALSE
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False)
```
* Next is code for the sensors, getting the output signals and adapting them to get useful information.
``` python
#DHT sensor
dth = DHT(Pin('P23', mode=Pin.OPEN_DRAIN), 0)
#rainsensor
adc = machine.ADC(bits=10) #AO analog read 12 bits
apin = adc.channel(pin='P16') #ADC1
pin_input = Pin('P15', mode = Pin.IN) #GIPO
# Program starts
print('Program has started')
while True:
#DHT11
result = dth.read()
#Rain
isRaining = pin_input.value() #gives 0 or 1
max = 2**10
level = 100 - (apin()/(max)*100)
if(isRaining==0):
resultat = 100
else:
resultat = 0
#print outs
print('Temp:', result.temperature)
print('RH:', result.humidity)
print('Water detected:', resultat)
print('Rain level:', level)
```
* Finally (inside the while loop) I am sending data to Ubidots from the variables I have stored the data in. I am sending data every 11th minute according to the limit of Sigfox:
```python
# send values as little-endian and int to UBIDOTS
s.send(struct.pack("<f", result.temperature)+struct.pack("<B", result.humidity)+struct.pack("<B", resultat)+struct.pack("<f", level))
time.sleep(11*60)
```
### Transmitting the data / connectivity
As for transmitting data I tried Wi-Fi which uses MQTT as transport protocol where the device connects to a platform through their broker. Since I wanted to explore more, I discovered the different options for transmitting data. I went for Sigfox. Sigfox is a low power wide area network where you can send data through the Sigfox network to Sigfox gateway. It was a good coverage in my area and I liked the idea of not have to rely on my not very good Wi-Fi.
**Set up of Sigfox**
Firstly, you want to check if you have coverage for using Sigfox, you can find the coverage map [here](https://www.sigfox.com/en/coverage).
Next thing to do is to connect your antenna, it should look like this:

Figure 9: Connecting the antenna
**Note:** Make sure it is connected before you move on!
To set up Sigfox I followed this [tutorial](https://docs.pycom.io/gettingstarted/registration/sigfox/), make sure to set the right region. After the set up you should be able to login to your [backend](https://backend.sigfox.com/device/list) where you should be able to see your device like this:

Figure 10: Backend Sigfox
Accordning to regulations in EU to occupy the bandwidth I am sending data every 11th minute which I think is enough for this project.
### Presenting the data
As I have mention above, I have used **Ubidots** as platform for presenting my data. I have used this [tutorial](https://help.ubidots.com/en/articles/694725-connect-a-pycom-sipy-to-ubidots-using-sigfox-over-http) to set it up. As for setting up the callbacks I have set it up like this:

Figure 11: Callback set up
**I advise you to set up your callbacks the same and not as it says in the tutorial.** This will correspond to the code which is sending the data to Ubidots which I have shown above.
And this is how I set up my Dashboard:

Figure 12: Dashboard
* Live demonstration of temperature and humidity.
* Weekly average of rain level.
* Graphs which shows the data over time.
* Table where you can see what time water was detected or not, where 100 = water detected and 0 = no water.
*The data in Ubidots is saved for 30 days.*
### Finalizing the design
I think this project went very well and I am happy I got to try different connectivity and platform options as well as different types of sensors. I do think it would fun to make a 3D printed case and put it outside but that is for next project!
As I mention above, I had some difficulties with the analog output of the rain sensor where my "rain level" is not corresponding to the actual value. This might be that I have configured it wrong or that the sensor is broken so if you do use this tutorial maybe have an extra check on this.

Figure 13: Final set up

Figure 14: Final set up
Thanks for reading this tutorial and good luck if you give it a try!