---
title: '1DT305 Project - Sebastian Neuhaus'
disqus: hackmd
---
Temperature monitoring using Adafruit IO
===
**Author**: Sebastian Henriksson Neuhaus (sh225bb)
## Table of Contents
[TOC]
## Introduction
This is my report for the summercourse Applied IoT at Linnaeus University and will function as a tutorial that will show you how to make a modular IoT temperature monitor using Raspberry Pi Picos and DHT11 sensors. We will gather data from the sensors and send them to Adafruit IO via the MQTT protocol.
**Time Requirement: 2-6 hours** (depending on customization, how many modules and previous experience)
## Project background
This course gave me the chance to realize an idea I've had for a while. Since moving into our new home last year I've wanted a way to monitor the temperatures in the different areas including the (non-insulated) garage and the (hot and insulated) utility room, to see temperature fluctuations during the day due to us only having windows in the east and west directions. When the sun shines, the home gets very hot due to the modern building materials and techniques used during construction.
Having tinkered with Arduinos for a while, trying to learn about electronics with the goal to smarten up my home and also to build "button boxes"/home cockpit modules for my simulator games, I always wanted to make a temperature monitor for my home, with graphs so I could see temperature changes in different rooms over time in an intuitive way.
I hope and expect to see a pattern, and plan to log the unreasonably warm temperatures during the spring, summer and autumn so I have proof when I discuss solutions for the high temperatures with my landlord. If nothing else, this lets me quantify my suffering during the sunny months.
The Applied IoT summer course gave me a chance to learn how to use the MQTT protocol and Adafruit IO which has built-in support for logging and graphs, which was a hurdle that had previously made me put off starting this project.
### The original idea
A simple sketch of my original plan:

This does not reflect how the project turned out, but shows my initial ideas of using a few Picos (one without built-in WiFi support) around the home, instead of each sensor having its own Pico W. I wanted to do this to keep costs down and to use what I already had laying around. Due to reasons like me not being able to get the NRF24L01 or other RF-transmitters working properly, not getting my ESP-01s in time and the fact that my girlfriend probably would not appreciate wires going between different rooms in the house to save on microcontrollers, I bought another WiFi-supported Pico and settled on having two different Picos gather readings from two different rooms and sending it to the same dashboard, to gain experience and to get this project finished on time.
## Material
Below are the materials used in this project, with prices as of 2024-06-30. I didn't necessarily buy everything from these links (had some, used Amazon, Wish and Temu for others), but this is where they can be reliably bought in Sweden. This is for one room, so for every room, you would need an additional DHT11, Raspberry Pi Pico WH and breadboard (207 SEK).
| Module | Description | Link | Price* |
| ------ | ----- | --- | ----------- |
| Raspberry Pi Pico WH | The microcontroller unit used in this tutorial, with built-in WiFi | [Electrokit](https://www.electrokit.com/raspberry-pi-pico-wh) | 109 SEK
| DHT11 on PCB | Low-cost temperature and humidity sensor | [Electrokit](https://www.electrokit.com/digital-temperatur-och-fuktsensor-dht11) |49 SEK |
| 0,96" 128x64 OLED display|**(Optional)** One or two-color OLED display used to display the readings, uses SSD1306 | [Electrokit](https://www.electrokit.com/lcd-oled-0.96128x64-spi/i2c) | 279 SEK
| 400 pins breadboard | Simple breadboard for connecting the prototype project | [Electrokit](https://www.electrokit.com/kopplingsdack-400-anslutningar) | 49 SEK
| M-M 10 cm DuPont wires | Male-to-male wires to connect the modules together on the breadboard | [Electrokit](https://www.electrokit.com/labbsladdar-100mm-hane/hane-30-pack) | 39 SEK
M-F 15 cm DuPont wires | **(Optional)** Male-to-female wires to connect the DHT11 to the breadboard without mounting them (for flexible placement) | [Electrokit](https://www.electrokit.com/labbsladd-20-pin-15cm-hona/hane) | 29 SEK
| Project box 100x68x50 mm IP65 | Project box with moisture protection for the Pico in the bathroom. No longer available. | ~~Wish~~ | 13 SEK
|||Total:|259-567 SEK|
## Computer setup
1. Prepare your computer
1.1 Download and install [Node.js LTS](https://nodejs.org/en/).
1.2 Download and install [Visual Studio Code](https://code.visualstudio.com/Download).
1.3 Open Visual Studio Code, go to the Extensions manager (```Ctrl+Shift+X```),
search for and install PyMakr.
2. Flash your Raspberry Pi Pico
2.1 Download the [MicroPython firmware](https://micropython.org/download/rp2-pico-w).
2.2 Whilst holding the ```BOOTSEL```-button on your Pi Pico, connect it via USB to your computer.
2.3 The Pi Pico should appear as a storage device on your computer.
2.4 Place the firmware (.uf2-file) on said storage device.
2.5 The storage device will disappear. Reconnect your Pi Pico *without* holding the ```BOOTSEL```-button to begin programming.
3. **(OPTIONAL)** Download the library for the [SSD1306 OLED driver](https://github.com/miketeachman/micropython-rotary/blob/master/rotary.py) if you plan on using it in this project. After creating a project in VS Code, you will have to place the supplied ```ssd1306.py```-file in your project folder, in a subfolder called ```lib``` (create it if it does not exist).
## Putting everything together
[](https://datasheets.raspberrypi.com/picow/PicoW-A4-Pinout.pdf)
Supply power to the breadboard by connecting the ```+```-row to ```3V3(OUT)``` and the ```-```-row to ```GND```.
On the DHT11, connect ```VCC``` and ```GND``` to ```+``` and ```-``` on the breadboard respectively. Connect ```DATA``` on the DHT11 to ```GPIO22``` on the Pico Pi. If you prefer another pin that's fine, I chose 22 because it is on the right side of the Pico and has no other special features. Remember to adjust the code if you change the pin.
If you are using the OLED screen, repeat the above procedure to supply power to the display, but connect ```SCL``` to ```SDA``` and ```GPIO17``` to ```GPIO16``` on the Pico Pi. This is because these pins support I2C which we will use to communicate with the display.

I have only used the OLED display on my first unit that is meant for the living room, for my bathroom unit I want to make it as moisture-proof as possible and have therefore opted for a project box, where I have drilled holes to connect the wires and then used a hot glue gun to make a seal around the wires entering the box, as shown below:

## Platform
I chose MQTT as the transport protocol, and [Adafruit IO](https://io.adafruit.com/) for both the MQTT broker and the dashboard, since it has a free version and is easy to set-up and begin using. The free version allows up to 10 feeds, which will allow us to expand the project to up to 5 rooms if we gather both temperature and humidity-readings. As I expand this project, I plan to either use their subscription service to get more features, or set up my own platform on a home server. I am connecting to Adafruit using WiFi connections from both my Picos, since I have good WiFi coverage throughout my house. If coverage was lacking and range extenders were not an option, one could use the LoRa wireless protocol to be able to place sensors in WiFi dark-spots.

The dashboard displays the current temperature and humidity, as well as graphs of the past 24 hours. It can be easily expanded as seen at the bottom, I have already prepared feeds and blocks for a third room (Utility room), it is only waiting for data to be sent to the correct feeds (due to time constraints and testing a new even lower-cost MCU, I have not yet expanded into these rooms).
Data is sent once a minute, since right now I'm using USB chargers to power my Pi's I don't care about uncessary power being drawn due to low intervals between action and prefer to get data more frequently. Adafruit accepts 30 transmissions per minute, so even if I expand to use all 10 feeds it shouldn't be a problem. The data points are stored in Adafruit IO's system for feeds.
The only "sensitive" data being transmitted as I see it is you can tell by the bathroom humidity if someone is taking a shower, indicating the house is occupied. This is pretty useless information were someone to encounter it.
The "test connection" block uses the LED ```lights``` feed from the course tutorial, since I had some connection issues I wanted a quick way to see if my Pi's were still connected to Adafruit or not.
## The code
**For the full code, see my [GitHub repository](https://github.com/SebNeuhaus/IoT2024/).**
:::info
If downloading the code from my GitHub, make sure to edit ```lib/keys.py``` with your own WiFi and Adafruit info!
:::
The code is based on the code from the course tutorial, modified to measure the readings from a DHT11-sensor and send them on two feeds as well as display it on an OLED. I will present a brief overview of the code for the OLED display:
### OLED display
```python
from ssd1306 import SSD1306_I2C
from machine import I2C
i2c0 = I2C(0, sda=Pin(16), scl=Pin(17))
display = SSD1306_I2C(128, 64, i2c0)
```
We need to import the downloaded library for the OLED-driver as well as the built-in I2C class to utilize the OLED display. We then make an I2C object called ```i2c0``` and an SSD1306-object called ```display```. 128 specifies how many horizontal rows pixels we have and 64 how many vertical pixels.
```python=
# Function to display measured temperature & humidity-values on SSD1306 OLED display
def display_temperature(temp, hum):
try:
display.fill(0)
display.text("Temperatur: {} C".format(temp), 1, 20)
display.text("Fuktighet: {} %".format(hum), 1, 40)
display.show()
except Exception as e:
print("DISPLAY FAILED")
```
Here I opted to define a function to send values to the display. The function will be called right before publishing the values to Adafruit IO. By using ```display.fill(0)``` we clear the display by turning off all the pixels, before sending new values. An issue I encountered was that I could not seem to display the degree-sign properly before the "C".
The ```1``` in the ```display.text()```-function specifies the text should be colored (white), and the ```20``` and ```40``` decide the position on the display. I chose these to get the text somewhere in the middle of the display.

### VS Code and PyMakr
I've been using Visual Studio Code with PyMakr to upload my code. To get started I followed this [tutorial](https://hackmd.io/@lnu-iot/rkFw7gao_) which explains how to get started. After making significant changes, I connect to the Raspberry Pi Pico and upload the new build through the development mode setting. I found that it would sometimes stop uploading or responding altogether - disconnecting in the software, restarting it, and reconnecting the Pi Pico solved this.
By using ```print()``` I could test the sensors and my code before connecting to Adafruit. This helped troubleshoot when Adafruit wouldn't receive my data. When ```print()```-ing I could see if the sensor/my code was bad, or there was something wrong with the connectivity-part of the program.
## Final results
| Raspberry Pi Pico WH | Raspberry Pi Pico WH |
|:------------------------------------------------------------:|:------------------------------------------------------------:|
|  |  |
| Living room Pi Pico, enclosure not finished | Bathroom Pi Pico, with moisture-proof(?) enclosure |
In the future, I intend for the living room Pi Pico to have a sleek enclosure to hide away the components, and only show status-LEDs and the OLED with the current temperature and humidity. The bathroom Pico Pi is complete, although I am not sure how well the DHT11 handles 90-100 % humidity which can exist in such an environment (sometimes I take really long showers..). I had intended to use a different sensor, but it would not play nice with the Pi Pico and sent erroneous data, so for now the DHT11 will do. I did not want to place it inside the enclosure for protection, since the Pi generates a little bit of heat which (okay, compared to the error range of the DHT11 it might not matter) might affect the readings, and the humidity readings would be worthless (and I think it's fun to see the humidity shoot up when the shower is on).

I think I'm happy with the dashboard for now, I would prefer more customization options and might therefore move away from Adafruit at some point, I would also like to figure out a way to get multiple feeds on one graph (to compare ie. living room and outside temps).
### Future improvements
My plans for future improvements:
* Sometimes it loses connection, so I would (1) like a way to be notified if connection is lost, and (2) either an automatic reset function, a reset button or both.
* More rooms!! I want to get my other MCUs working as cost efficiently as possible, to send data from the other rooms to a hub Pi Pico, and on to the dashboard.
* Outside measurements, I want a way to get reliable outside measurements without radiation from the sun interfering. Maybe I need to build a Stevenson box or something with a similar function. I would prefer local, up-to-date measurements from my backyard rather than downloading weather data from eg. SMHI.
* A weather station-like display in the house, that displays all different readings in a format that is legible even when standing a couple of meters away. The 0,96"/2,44cm display requires you to be pretty close to it to read the text.
* More types of measurement. I have a gas sensor and barometric pressure sensors I would like to hook up to get readings of gas levels in the utility room/garage and the local barometric pressure outside. I can see myself adding new and different sensors forever and ever.
* Error-logging and automatic reconnections if the connection is interrupted. Currently you often have to cycle the power to the unit for it to reconnect.
* Notifications when certain thresholds are passed, for example humidity or temperature in the utility room which can affect pipes (freezing), the boiler for the house or the electrical components I have stored there. Either via E-mail/Discord or via SMS.
## Reflection
As I mentioned in [Project background](#project-background) I originally had higher amibitions for this project and had finally received some ESP01s to function as small remote temperature sensors. I ordered them to enable WiFi on my non-WiFi Pico after first mistakenly ordering a set of NRF24L01's thinking they were the same. Turns out, that’s like thinking a cat and a dog are the same because they both have four legs (or in this case, 8 pins). This wasted a couple days, especially as I tried to get the NRF24L01 to work (still not sure if mine were duds or I'm just too stupid!). As I realized the potential - the ESP01 having its own ESP8266 - I in the last minute started trying to get it to work. In the future I plan on probably using a couple of these out in the utility room and garage, as they were very cheap and I managed to solder on a DHT11. So far I've successfully hooked it up to Adafruit IO and ran it for a couple days, but the values are sometimes erratic and thus I don't consider it functional.

Speaking of soldering, after (somewhat impulsively) buying a proper [soldering station](https://www.amazon.se/dp/B0987H26KP) to replace my passed-down soldering iron, I spent a while trying to learn how to solder properly (with mixed, but functioning(!), results). After practising I'm more confident now when it comes to soldering pins.
I also wanted to fit my main Pico sensor into an old VoIP modem that I had stripped out, but need to buy M2 screws and nuts and more wire to make everything fit properly. I intend to use the LED indicators on the modem for power, connection and transmission status. The modem can then stand on a shelf and look somewhat better than a breadboard with a bunch of wires sticking out.
