Author: Egil Elenius (ee224cn)
# 1. Overview
IoT has many potential usages. One of them is for municipalities to give their citizens the possibility to check the state of halting places before going there. In this project, the temperature and humidity of a place will be monitored and uploaded to an online dashboard, so the potential visitors know what to prepare for..
After a brief introduction and explanation of what material is to be used, the tutorial will give a step-by-step guide. First, the necessary programs will be installed and the microcontroller prepared. Then, the physical setup will be shown. After this, a brief introduction to the IoT platform Thingsboard is given, followed by the code necessary to make the microcontroller connect to and send data to Thingsboard. Finally, a bit about how the data is transmitted and presented, and some reflections, are given.
Estimated time to set it up: 3-4 hours.
# 2. Objective
As I will take an internship this autumn in which I will expand a rural municipality's usage of IoT, this project, as well as the course, was chosen as a basic preparation.
The municipality in quesiton uses Thingsboard as its IoT platform, and the purpose of this project is to get a basic understanding of how that platform is used.
Apart from teaching the basics, the project can also give time for reflections and ideas ahead of the internship.
# 3. Material
All material was contained in the [LNU Standard Kit](https://www.electrokit.com/en/product/lnu-1dt305-standard-kit-2023/) (399.00 SEK) sold by the website Electrokit. From this kit, the following materials have been used:
| Name| Function | Amount |
| ------- | ----- | --- |
| Raspberry Pi Pico WH | Micropython-programmable development board with wi-fi connectivity | 1 |
| Breadboard | Facilitates connecting multiple sensors | 1 |
| USB-cable | Used to connect the development board to the computer | 1 |
| Jumper wires 30cm male/male | Used for connections on the breadboard | 2 |
| Jumper wires 30cm female/male | Used to connect the Pico WH with the breadboard | 3 |
| Digital temperature and humidity sensor DHT11 | Monitors temperature and humidity | 1 |
# 4. Computer Setup
First, an IDE, an integrated development environment has to be downloaded, and the Pico W has to be prepared. The operating system used was Windows 10.
* [Download Visual Studio Code](https://code.visualstudio.com/)
* In VSC, go to `Extensions` and install `Pymakr`.
* [Download UF2 bootloader](https://micropython.org/download/rp2-pico-w/)
* Connect the USB-cable to the pico W. While holding down the bootsel button, connect the cable to your computer.
* When a window appears, drag the UF2 file into the window. This will prepare the Pico W for the coding. It might take a while.
After this, it's time to create the project.
* Dis- and reconnect USB-cable.
* Open VSC.
* Click on PyMakr on the pane to the left.
* Click the device under Devices.
* Click on the plus right of `Projects` to create a new project.
* Create and name a folder in your preferred placement, then confirm.
As an extra step, to see that the Pico W is functioning, move the mouse to the button on the same row as the connected device called `Create terminal` and click it. In the terminal, click right to the `>>>`, write `print(1+1)` and press enter. If the answer 2 is printed on the screen, then the Pico W works.
We will come back to downloading the code unto the Pico W later.
# 5. Putting everything together
Now, it's time to connect the electronics.
* Disconnect the device from VSC, and the USB-cable from the computer.
* Connect the Pico W with the breadboard and the sensor in the following way:

As previously mentioned, male-female wires are used between Pico W and breadboard, while male-male ones are used between the connections of the breadboard.
# 6. Platform
The platform, Thingsboard, is an open-source IoT platform for data collection, processing, visualization, and device management. It enables device connectivity via industry standard IoT protocols - MQTT, CoAP and HTTP and supports both cloud and on-premises deployments.
As previously mentioned, the platform was chosen to match that of the municipality. The free cloud version is used for the project, and is meant to give a basic understanding of IoT and Thingsboard.
**Prerequisite: cUrl will need to be installed. Starting by Windows 10 b17063, cURL is available by default.**
First, you need to [create a free account on Thingsboard.](https://thingsboard.cloud/signup) You can use Facebook, Google or GitHub accounts if you want to. When that is done, it's time to add the first device.
## 6.1. Add device
* Login to your ThingsBoard instance and navigate to the "Entities". Then click the "Devices" page
* Click on the "+" icon in the top right corner of the table and then select "Add new device"
* Input device name. For example, "My New Device". No other changes required at this time. Click "Add" to add the device
* Click on the device row in the table to open device details. Note that the device state is "Inactive".
* Click "Copy access token". Token will be copied to your clipboard. Save it to a safe place.
* Open the terminal and write `curl -v -X POST -d "{\"temperature\": 25}" $https://demo.thingsboard.io/api/v1/$ACCESS_TOKEN/telemetry --header "Content-Type:application/json"` with your corresponding access token, and then send it. This will send a first temperature reading to your device.
* Analogously, write `curl -v -X POST -d "{\"humidity\": 25}" $https://demo.thingsboard.io/api/v1/$ACCESS_TOKEN/telemetry --header "Content-Type:application/json"` with your corresponding acces token, and send it.
If you click on the device on the webpage, you can access these telemetry readings under the tab "Latest telemetry".
## 6.2. Dashboard
Then, it's time to create a dashboard. In the dashboard, widgets can be added to visualize the data.
* Open the "Dashboards" page. Click on the "+" icon in the top right corner. Select "Create new dashboard".
* Input dashboard name. For example, "My New Dashboard". Click "Add" to add the dashboard.
## 6.3. Alias
After that, it's time to create an alias. An alias is a reference to a single entity or group of entities that are used in the widgets. Alias may be static or dynamic. It is possible to configure an alias that references multiple devices. For example, devices of a certain type or related to a certain asset. For now, a single entity alias will suffice.
* Click the "Assets" page.
* Enter edit mode. Click on the pencil button in the bottom right corner.
* Click the "Entity aliases" icon in the top right part of the screen.
* You will see an empty list of Entity aliases. Click "Add alias" button.
* Input alias name, for example, "My Device". Select the "Single entity" Filter type. Select "Device" as Type and type "My New" to enable autocomplete. Choose your device from the auto-complete and click on it. Click "Add".
* Click "Save".
* Finally, click "Apply changes" in the dashboard editor to save the changes.
## 6.4. Widget
Entity Table widget displays the latest values with list of entities that matches selected alias and filter with ability of additional full text search and pagination options.
To add the table widget we need to select it from the widget library. Widgets are grouped into widget bundles. Each widget has a data source. This is how the widget “knows” what data to display. To see the latest value of our “temperature” data that we sent, we should configure the data source.
* Enter edit mode. Click on the "Add new widget" button.
* Select the "Charts" widget bundle.
* Select the "Timeseries Line Chart" widget.
* The "Add Widget" window will appear. Click "Add" to add the data source. A widget may have multiple data sources, but we will use only one in this case.
* Select "My Device" entity alias. Then click on the "Latest data key" field on the right. The auto-complete with available data points will appear. Select "temperature" data point and click "Add".
* Resize the widget to make it a little bigger. Just drag the bottom right corner of the widget. Apply changes.
After this first widget is added, you may also add a Radial Gauge from the Analogues Gauges bundle, and set it to measure humidity.
# 7. The code
Now we go back to VSC. Make sure that it is set up properly and that the Pico W is connected.
* In the previously created project folder, create one file called `main.py`, and one called `secrets.py`.
* Most of the code is in the `main.py`. The `secrets.py` file is primarily to avoid showing the credentials, but also to not hardcode the url and access token in the primary file.
Here is the code for `secrets.py:`
secrets = {
'ssid' : 'SSID',
'password' : 'PASSWORD',
'url' : 'https://demo.thingsboard.io',
'token' : 'ACCESS_TOKEN'
}
Note that in `secrets.py`, you have to add your own ssid, password and access token.
And here is the code for `main.py:`
import dht
import network
import urequests
import utime
from machine import Pin
from secrets import secrets
tempSensor = dht.DHT11(Pin(27))
def connect_to_wifi(ssid, password, max_attempts=1000):
wlan = network.WLAN(network.STA_IF) # Put modem on Station mode
if not wlan.isconnected(): # Check if already connected
print('connecting to network...')
wlan.active(True) # Activate network interface
# set power mode to get WiFi power-saving off (if needed)
wlan.config(pm = 0xa11140)
wlan.connect(ssid, password) # Your WiFi Credential
print('Waiting for connection...', end='')
# Check if it is connected otherwise wait
while not wlan.isconnected() and wlan.status() >= 0:
print('.', end='')
utime.sleep(1)
# Print the IP assigned by router
ip = wlan.ifconfig()[0]
print('\nConnected on {}'.format(ip))
return
raise RuntimeError("Failed to connect to WiFi after multiple attempts.")
def read_sensor_and_send_telemetry(tempSensor, secrets):
while True:
#Read sensor
try:
tempSensor.measure()
temperature = tempSensor.temperature()
humidity = tempSensor.humidity()
print("Temperature is {} degrees Celsius and Humidity is {}%".format(temperature, humidity))
except:
print("Error in reading sensor values")
#Send telemetry
telemetry_data = '{{"temperature": {}, "humidity": {}}}'.format(temperature, humidity)
url = "{}/api/v1/{}/telemetry".format(secrets["url"], secrets["token"])
response = urequests.post(url, data=telemetry_data)
print("Response status:", response.status_code)
response.close()
connect_to_wifi(secrets["ssid"], secrets["password"])
read_sensor_and_send_telemetry(tempSensor, secrets)
When this code is written, it is time to download the code to your device.
* Connect the USB-cable to the computer.
* Go to PyMakr and under `Devices` and click `Connect device`.
* Open a terminal.
* Then press the `</>` icon on the same row as the project name. This will start Development mode, where the code is downloaded everytime you save it.
* Click the editor window and press `Ctrl + s`, first in `secrets.py`, then in `main.py`.
If everything is done correctly, your device should now be sending data to the server, and the widgets be updated every few seconds.
# 8. Transmitting the data / connectivity
The wireless protocol used has been WiFi, and the transport protocol used in the terminal, aswell as in the code, is HTTP. These have been chosen from their ease of usage: this is only a first version, to quickly get things up and going.
Mind that I did not set the time for how frequently the data is to be sent; adding a line of `utime.sleep(x)` in the read_sensor_and_send_telemetry() function, where x is set to the preferred interval in seconds, is possible.
# 9. Presenting the data

*Figure 1.*
Figure 1 above is what the finished dashboard looks like.
The devices only save the latest telemetry sent to them. For the widgets, it varies for how long the data is preserved. Whereas the timeseries line chart can be adjusted for how long it shows, the gauge only shows the last reading sent to it.
# 10. Finalizing the design
Apart from the previously shown dashboard, there is not much to add when it comes to picturewise. Below is a picture of the "Devices" page, and one of VSC sending data.

*Figure 2. The dashboard*

*Figure 3. Visual Studio Code in action*

*Figure 4. The physical setup*
The project has been a good introduction to IoT. Many minor difficulties lead to it taking longer than expected, but the end result is a solid one, though modest.
Looking back, more sensors could have been added, forcing me to do more advanced wiring.
This would also have opened up for comparing the types of data, delving into the territory of data analysis. Using what already is being sent, temperature and humidity, the [heat index](https://en.wikipedia.org/wiki/Heat_index) could be calculated.
Another posibility would be to send an alarm whenever the temperature exceeds a certain threshold. Reapplying this for other kinds of sensors, like a distance sensor measuring water level, can tell when there is a draught or a flood.
All in all, I see this project as a good first step.