---
# System prepended metadata

title: Smart home temperature analyser

---

**Name:** Villiam Strandh
**Student Credentials:** vs222wg
**Short project overview:**
A IoT project to measure the temperature, humidity and light in the room. Connects with wifi to the internet and sends data via REST. Visualisation happens in low-code solution ubidots and a self-build website.
**Approximate time to complete:**
- Without experience = 10 hours
- With experience 3-4 hours


## 🎯 Objective
My objective with this project is to learn more about IoT solutions and how it works in general. The best way for me to learn is always to do something that is useful in my own life. So, I came up with the idea of building a gadget that keeps track of the temperature, humidity, and light in my home. Why? Well, I'm getting a dog soon, and I want to make sure she stays comfy, especially on those scorching hot summer days. By creating this IoT device, I can monitor the conditions in real-time and make sure my furry friend stays cool and cozy, as well as gather insights in how the temperature and humidity changes during day and night. Plus, it's an awesome way for me to learn all about IoT and have a handy tool for taking care of my new companion.



#### Main goals
- Real-time data should be easily available and presented in a easily digestable way
- Saved in a database for future analysis


Since I have some experience with web development, I had the idea to combine some new techniques I've learned in this course with som web technologies. That is why I will also create a website to visualise the data.


## 🧩 Material
I choose to work with the Rasberry Pi Pico W as it was recommended by LNU and included in the starter kit from ElectroKit where the rest of materials also comes from.

Most of the items may be changed with other brands or sensor types depending on your needs, but this is the following I used.

| Product | Link | Price | Why |
| ------- | ---- | ----- |-----|
| Rasberry Pi Pico W | [ElectroKit link](https://www.electrokit.com/produkt/raspberry-pi-pico-w/) | 98 SEK | Tiny computer, the heart of the device.
| Solderless Breadboard | [ElectroKit link](https://www.electrokit.com/en/product/solderless-breadboard-840-tie-points-2/) | 69 SEK | Easily connect sensors to microcontroller |
| 12 Jumper Wires | [ElectroKit link](https://www.electrokit.com/produkt/labbsladdar-100mm-hane-hane-30-pack/) | 39 SEK | Establish connections between different components on the breadboard | 
| DHT11 Sensor | [ElectroKit Link](href=https://www.electrokit.com/produkt/digital-temperatur-och-fuktsensor-dht11) | 49 SEK | Digital sensor for measuring temperature and humidity |
| LDR Sensor CdS 4-7 kohm | [ElectroKit Link](https://www.electrokit.com/produkt/fotomotstand-cds-2-5-kohm/) | 49 SEK | Analogue sensor for measuring light |
| 2x LED 5mm Red | [ElectroKit Link](https://www.electrokit.com/produkt/led-5mm-rod-inbyggt-motstand-12v/) | 24 SEK | LED indicator |
| 2x LED 5mm Yellow | [ElectroKit Link](https://www.electrokit.com/produkt/led-5mm-gul-inbyggt-motstand-12v/) | 24 SEK | LED indicator |
| 2x LED 5mm Green | [ElectroKit Link](https://www.electrokit.com/produkt/led-5mm-gron-inbyggt-motstand-5v/) | 24 SEK | LED indicator |
| USB Micro B Cable | [ElectroKit Link](https://www.electrokit.com/produkt/usb-kabel-a-hane-micro-b-5p-hane-1-8m/) | 39 SEK | LED indicator |
| 6x Resistor carbon film 0.25W 330ohm | [ElectroKit Link](https://www.electrokit.com/en/product/resistor-carbon-film-0-25w-330ohm-330r/) | 6 SEK | To manage the current to the LEDs |


I chose to use the digital sensor DHT11 for temperature and humidity measuring, and an analog Photo Resistor sensor to measure the level of light in the room.

For the Microcontroller, make sure it is **possible to connect with wifi** since this is the connectivity we will use in this project.


## ⚙️ Setting up the development environment

**To upload code**
To upload the micropython code, you will need a computer with an IDE setup connected to the microcontroller with a usb cable that is able to send data.

**Node JS - javascript runtime environment**
[NodeJS](https://nodejs.org/en) is required for the environment to work. Make sure it is installed and added as a PATH variable.

**IDE / Text editor**
You may choose a text editor of your choice. But I used (and would recommend) [VSCode](https://code.visualstudio.com/) since it has good extension for IoT. Make sure the editor is installed and working.


**PyMakr**
1. Install PyMakr VSCode extension
2. Connect your Device: Connect your IoT device  to your computer via USB
3. Select your Device in the PyMakr panel,  make sure it is properly connected and recognized by your computer.
4. Create a new python project in VS Code.
5. To Upload Code to Device, click on the "Upload" button in the panel to transfer your code to the device.
6. You can now monitor the device output in the output tab or terminal

**Micropython project**
Make sure python is installed on your system for easier time coding.

Create an `boot.py` and `main.py` files for the python code. These will be uploaded to your device

## 🖥️ Platform

**Ubidots**
Make sure you have an [Ubidots](https://ubidots.com/) account, since this will be used for the main data visualisation. This is the main and easy way to visualise the data in this project.

**Supabase** (optional)
As an extra step to save data in a database, I use the Backend as a Service: [Supabase](https://supabase.com/). You can use any other service you want or a docker container. Make sure you have a Supabase account. This will allow the hosting service to upload data to database and transmit to the website

**Vercel Hosting** (optional)
To host the website I use as secondary visualisation I decided to use [Vercel](https://vercel.com/), since they have great integration with NextJs framework and can easily host api functions that connect to supabase.

**NextJS/React** (optional)
To build the website I used [NextJS](https://nextjs.org/) with React, which is a good framework for building web applications. You may use any tech you want for this.


## ⚡️ Putting everything together

1. First we have to install the firmware. Connect the microcontroller to your computer and download the appropriate firmware from https://micropython.org/download/rp2-pico-w/. Ensure that your computer recognizes the Pico W as a removable drive.

2. Flash the Firmware: 
    - Open the file explorer on your computer and navigate to the location where you downloaded the firmware file.
    - Copy the firmware file to the Pico W microcontroller. Paste it into the removable drive corresponding to the Pico W.
    - Wait for the file transfer to complete. Do not disconnect the Pico W during the process.
    - Once the firmware file is successfully copied to the Pico W, safely eject the Pico W from your computer.
    - Disconnect the USB cable from the Pico W, and then reconnect it to power up the microcontroller.
    - After the firmware installation is complete, the Pico W microcontroller should be running the new firmware. Now you can integrate it with your development environment.


**DHT11 Sensor**
- Connect leftmost pin (S) to Pico W pin GP27
- Connect middle pin to Pico W pin 3v3 (or + line on breadboard)
- Connect rightmost pin (-) to Pico W pin GND (or - line on breadboard)
    
**LDR Sensor**
- Connect one pin to GND (or - line on breadboard)
- Connect the other pin to Pico W pin GP26

**LED Lights**
- Connect one pin to GND (or - line on breadboard)
- Connect the other pin to GP0 through GP6 pin on board

![](https://hackmd.io/_uploads/SJ9_SaK_h.png)



## The Code

**Connecting to wifi**
```python
def do_connect():
    wlan = network.WLAN(network.STA_IF)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.active(True)
        wlan.config(pm=0xa11140)
        wlan.connect(WIFI_NAME, WIFI_SECRET)
        while not wlan.isconnected() and wlan.status() >= 0:
            time.sleep(1)
    print('network config:', wlan.ifconfig())
    ip = wlan.ifconfig()[0]
    return ip
```

**Main loop**
The main loop has two sleep to delay between each request to send, as well as make sure garbage collection is happening between each request to make sure there is enough ram.

Basically this is the loop that will run indefinetly and in intervals send data to each visualisation after gathered the data from each sensor.
```python
while True:
    time.sleep(3)
    gc.enable()
    gc.collect()
    tempSensor.measure() # measure the DHT11 values
    temp = tempSensor.temperature()
    hum = tempSensor.humidity()
    ldrValue = ldr.read_u16() # read the analogue photo resistor current
    send_website_req(temp, hum, ldrValue) # sends HTTP request with GET
    time.sleep(3)
    send_ubidots_req(temp, hum, ldrValue) # sends HTTP request with POST
    set_led_by_temp(temp) # toggles LEDs dependinch on temperature
```

**Website and Supabase integration**
The website is built with React and NextJS framework. I won't present any code for those, but any web based framework or language should work to recreate a similar result.


## 🌐 Transmitting the data / connectivity

I decided to use REST connectivity as *transport protocol* to communicate between the device and clients. The motivation was mostly with the idea to easily integrate a self-built website with the data, and easily integrate Ubidots as well. And since the device will only be used at home, for *wireless protocol* I used WiFi.

The microcontroller script sends the data twice. Each with 3 seconds between with a total of **6 seconds between each same type of transmission**

**Ubidots path**
- Post request with JSON data.
- Ubidots receives data and presents sensor data in useful widgets

**Website path**
- Sends GET request with values as query-params
- The api service connects with supabase and sends the json
- Supabase DB inserts the data in Postgres table and emits event to all subscribers.
- The website gets event from publisher and requests the new sensor data and updates the website accordingly.

![](https://hackmd.io/_uploads/SkYpjjdd2.png)

## 🖼️ Presenting the data

**Ubidots**
The primary way to visualise the data is using Ubidots. Here we have three values to see from two sensors. The humidity and temperature sensor (DHT11) and the LDR sensor. 

To create the widgets. Make sure you have the correct token in your python code that you can find on your ubidots profile. Choose the widgets that you want to show and in the dashboard, connect the to your device. When you send POST requests to the ubidots endpoint, the connected widgets will show the data from your device in realtime.
![](https://hackmd.io/_uploads/BkC2iViOn.png)

An extra step I decided to do is to save the data in a database. There are many ways to do it. You can do a self hosted docker container with a db image, a db as service solution as I did here or any other database solution. Every approximate 6th second, json data is transmitted to supabase from the vercel endpoint that handles the data received from the microcontroller. Here all data is saved and accessed via the cloud if just logged in to your account. The data is saved everytime it is transmitted, every **6th second as of now.**
There are clear examples on their documentation on how to implement with javascript (not shown in this report).
![](https://hackmd.io/_uploads/S1UuhViO2.png)

Finally, as an extra step the data is represented in a website that is updateed in realtime. Now what can be the best way to show the temperature at a quick glance? Well emojis of course! Depending on the temperature sent, the emoji will update from 🥶 (coldest) to 🥵 (hottest). The humidity is display as a number and the date. The background color indicates if it is day or night depending on displaying in dark mode or light mode.
![](https://hackmd.io/_uploads/Hkrj2Vj_n.png)


## ✅ Finalizing the design

![](https://hackmd.io/_uploads/S11vB30_h.jpg)


**What could have been done better**
There are probably many ways to improve the project, but one could be an estetic one. Where as of now to be honest, the device is pretty ugly with lots of wires everywere. Shorter wires would do the trick, and to encase the breadboard and microcontroller with wires would be good while keeping the sensors exposed to the outside of course.

**Issues along the way**
My biggest hurdle in the project was an ENOMEM error in python code. It arrived after running the device for a few minutes, then would persist with restarts all until i rebooted it.

I quickly realised that it was some sort of memory issue. So naturally I made sure the garbage collector was run every iteration. This made it better, but I still got ENOMEM error after a while. So then I found that post requests with urequest library sometimes takes up more memory than the get request (for some reason), so I just made the API endpoint accept GET request with queryparameters.

Still no avail.

Until...

![](https://hackmd.io/_uploads/rJkBNG0_h.png)

This comment made me realise the silly error. The sockets were not getting released after reuploading the code in dev mode with pymakr! By doing a warm boot, the sockets that were occupying memory where closed and I could continue as normal.


**In the future?**
It is great to have the temperature of my room anyware I go, on any device as long as I have internet connection. But how do I act on this? A possible improvement might be to integrate this sensor data and program with a home assistant system that manages the heating and air-conditioner depending on the data for the sensor.




