By Linus Norberg Thörn (ln223jx)
## Project Overview
In this project I connected a Raspberry Pi Pico W to a DHT11 to measure temperature and humidity, and sent it via wifi to Ubidots for visualizing the data.
This project can be done in about 1 hour with previous experience of IoT projects, but can take as much as 10+ hours for a beginner.
## Objective
The goal was to create a simple device that can read the temperature and humidity of a room with a small delay between readings. This is to be able to see fluctuations in both temperature and humidity over certaing periods. Large fluctuations can indicate that a home needs maintenance to regulate temperatures and humidity. This device can for example be used to help settle disputes between landlords and tenants. I chose this project because a temperature and humidity sensor was included in the standard package from Electrokit, and because I myself live in a small appartment with large fluctuations in temperature, so it would be interesting to find out exactly how much this changes in a day.
## Material
In this tutorial you will need:

*Fig 1.Raspberry Pi Pico W*
The Raspberry Pi Pico W is a microcontroller with built-in Wi-Fi. It's designed for wireless communication and IoT-projects. It uses the RP2040 chip and can be programmed using MicroPython or C/C++. The Pico W is an affordable and beginner-friendly microcontroller for IoT applications and wireless projects.

*Fig 2. DHT11*
The DHT11 is a digital humidity and temperature sensor, and needs a library to communicate with it.

*Fig 3. Breadboard 840 connections*
This is used to connect the Pico with the sensor.

*Fig 4. USB A (male) to micro USB B (male)
The USB A to micro USB B is used to connect the Pico to your computer. Important that it is a data transer cable and not just a charger cable.

*Fig 5. Jumper Wires male/female*
The jumper wires are used to connect the Pico, DHT11 and breadboard.
| Device | Link to store | Price |
| ---------------------------------- | --------------------------------------------------------------------------- | ------ |
| Raspberry Pi Pico W | https://www.electrokit.com/produkt/raspberry-pi-pico-w/ | 98 SEK |
| DHT11 | https://www.electrokit.com/produkt/digital-temperatur-och-fuktsensor-dht11/ | 49 SEK |
| Breadboard 840 connections | https://www.electrokit.com/produkt/kopplingsdack-840-anslutningar/ | 69 SEK |
| USB A (male) to micro USB B (male) | https://www.electrokit.com/produkt/usb-kabel-a-hane-micro-b-5p-hane-1-8m/ | 39 SEK |
| Jumper Wires 40 pin 30cm male/female | https://www.electrokit.com/produkt/labbsladd-40-pin-30cm-hona-hane/ | 49 SEK |
## Computer Setup
For this tutorial I used an HP laptop with Windows 11.
First you will need to download and install [Visual Studio Code](code.visualstudio.com/) and [Node js](https://nodejs.org/en)
(choose the recommended version since the current might have unfixed bugs)
The next step is to download the Pymakr 2 plugin to VSC.
To do this: Open VSC -> Go to extensions -> Search for Pymakr -> Install (see Fig 6.)

*Fig 6. Pymakr 2 in VSC*
You will also need to update your Pico for it to function. To do this:
Remove the black sponge from the Pico's pins -> Download the latest uf2-file from [here](https://micropython.org/download/rp2-pico-w/) -> Connect your micro USB B to the Pico (important to hold the back of the female connector so it won't be bent) -> While holding the Bootsel button down on you Pico, insert the USB A part of your cable to your PC. Release the Bootsel after the insertion -> When the Pico's drive named "RPI-RP2" opens, copy/paste the uf2 file to it -> The board will automatically connect, then reconnect to you computer.
Next I accessed the Pico in VSC, following the steps in Fig 7:
Click on the Pymakr extension -> Hover the USB Serial Device -> Click the lightning button -> Click Create Terminal

*Fig 7. Accessing the Pico in VSC*
## Creating a New Project
Go to the Pymakr extension in VSC -> Click the plus icon (+) -> Click "Create Project" -> Choose a folder to save the project in -> Next you'll be asked 3 questions, you can just press enter to have the default settings -> Add your device to the project by clicking "ADD DEVICES" -> Select your device & click OK.
## Putting Everything Together
I started by connecting the DHT11 to the breadboard, then connecting jumper wires from the same vertical connections as the 3 DHT pins. The first wire from the DHT's left pin (signal) directly to the Pico's 32:nd pin. The second wire went from the DHT's middle pin (3.3V) to a "+" connection (VCC) and the another jumper wire from another of the "+" connections on the same horizontal row as the 3.3V pin, to the Pico's 36:th pin. The last wire went from the DHT's right pin (GND) to a "-"(GND) connection, and another wire from a "-" connection on the same horizontal row as the GND pin, to the Pico's 38:th pin. See Fig 8.

*Fig 8. Hand drawn circuit diagram
## Platform
To visualize my data I used Ubidots locally with a free subscription. Ubidots is a great platform for beginners to visualize data because it has a user-friendly interface and lets you create interactive dashboards without coding. You can see your sensor data in real-time and choose from various visualization options like charts and maps. It's easy to connect your Pico to Ubidots, and they provide helpful documentation and tutorials to get you started.
## The Code
``` ```
I created a file called secrets.py where I put my wifi credentials. This was to ensure that it's separated from the main program for security reasons. Like this:
``` python
secrets = {
'ssid' : 'My_Wifi_SSID',
'password' : 'My_Password',
}
```
To connect to the wifi i wrote this code in the boot.py. The do_connect() establishes a Wi-Fi connection using network credentials from a my secrets.py file, and the http_get() sends an HTTP GET request to a specified URL:
``` python
def do_connect():
import network
from time import sleep
from secrets import secrets
import machine
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(secrets["ssid"], secrets["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='')
sleep(1)
# Print the IP assigned by router
ip = wlan.ifconfig()[0]
print('\nConnected on {}'.format(ip))
return ip
def http_get(url = 'http://detectportal.firefox.com/'):
import socket # Used by HTML get request
import time # Used for delay
_, _, host, path = url.split('/', 3) # Separate URL request
addr = socket.getaddrinfo(host, 80)[0][-1] # Get IP address of host
s = socket.socket() # Initialise the socket
s.connect(addr) # Try connecting to host address
# Send HTTP request to the host with specific path
s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
time.sleep(1) # Sleep for a second
rec_bytes = s.recv(10000) # Receve response
print(rec_bytes) # Print the response
s.close() # Close connection
# WiFi Connection
try:
ip = do_connect()
except KeyboardInterrupt:
print("Keyboard interrupt")
# HTTP request
try:
http_get()
except Exception as err:
print("Exception", err)
```
In the main.py is where the measuring of the temperature and humidity is done, and sent to Ubidots.
First import necessary modules for sensor interfacing, network management, HTTP requests, and time handling.:
``` python
import dht
import machine
import network
import urequests as requests
from time import sleep
```
Then we need to define variables and credentials for the wifi and Ubidots, and also the delay time between readings:
``` python
TOKEN = "BBFF-dI4g9jjFSbfHMUdkJxNvfMj1ZbvX4C" #Put here your TOKEN
DEVICE_LABEL = "linus-pico" # Assign the device label desire to be send
TEMPERATURE_LABEL = "temperature" # Assign the variable label desire to be send
HUMIDITY_LABEL = "humidity"
WIFI_SSID = "My_Wifi" # Assign your the SSID of your network
WIFI_PASS = "My_Password" # Assign your the password of your network
DELAY = 5 # Delay in seconds
```
The connect() function is used to connect to a Wi-Fi network. It activates the Wi-Fi on the device, enters the SSID and password of the network, and waits until the connection is established. Once connected, it returns the assigned IP address.
``` python
def connect():
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)
```
``` python
def connect():
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(WIFI_SSID, WIFI_PASS) # 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='')
sleep(1)
# Print the IP assigned by router
ip = wlan.ifconfig()[0]
print('\nConnected on {}'.format(ip))
return ip
```
The build_json() function is used to store data. It takes a variable and a value and structures them into a JSON object, which can then be stored or transmitted as needed.
``` python
def build_json(variable, value):
try:
data = {variable: {"value": value}}
return data
except:
return None
```
sendData() sends the data to Ubidots:
``` python
def sendData(device, variable, value):
try:
url = "https://industrial.api.ubidots.com/"
url = url + "api/v1.6/devices/" + device
headers = {"X-Auth-Token": TOKEN, "Content-Type": "application/json"}
data = build_json(variable, value)
if data is not None:
print(data)
req = requests.post(url=url, headers=headers, json=data)
return req.json()
else:
pass
except:
pass
```
connect() connects to Wi-Fi, and tempSensor = dht.DHT11(machine.Pin(27)) sets up a temperature sensor on pin 27 of the Pico.
``` python
connect()
tempSensor = dht.DHT11(machine.Pin(27))
```
The last part of main.py creates an infinite while loop that measures and sends the temperature and humidity to Ubidots every 5 seconds(DELAY)
``` python
while True:
tempSensor.measure()
temperature = tempSensor.temperature()
humidity = tempSensor.humidity()
returnValueTemp = sendData(DEVICE_LABEL, TEMPERATURE_LABEL, temperature)
returnValueHum = sendData(DEVICE_LABEL, HUMIDITY_LABEL, humidity)
sleep(DELAY)
```
## Transmitting the Data / connectivity
The data is measured and sent every 5 seconds, which can be seen in the infinite while loop (DELAY = 5).
The data is transmitted wirelessly with Wi-Fi to Ubidots using the HTTP protocol.
## Presenting the Data
I used two Gauge Widgets to visualize the temperature and humidity data as seen in Fig 9.

*Fig 9. My Ubidots Dashboard*
The data is saved every 5 seconds.

*Fig 10. Temperature graph*

*Fig 11. Humidity Graph*
I did a comparizon between my apartment and my mothers apartment which feels very similar. It turns out that my apartment gets a few degrees warmer that hers, but she had over 10 percentage points more humidity. So finally I have an answer to why my plants die much quicker than hers ;^)
## Finalizing the Design

*Fig 12. My Pico, DHT11 and Breadboard connections *

*Fig 13. The obligatory 1000 tabs open when doing an IoT project.
Since I did not have any previous experience of IoT projects I think it went alright, though there are some things I would have changed if I had to do it again:
1. Start earlier. Since I had left over from an earlier course that had to be done, the first week went to completing that.
2. Update myself with Canvas and Discord. In the beginning I had no idea how the course worked, mostly because I was not up to date with Canvas and Discord which led to me missing most Workshops.
3. Go to workshops and get help from TA instead of watching recorded lectures. I started by watching the recorded lectures, but they were not nearly as useful as getting 1 on 1 help from a TA.
4. Do not work full time when studying!!! I have a full time summer job which takes up most of my time. This is not good for neither study productivity nor mental health. Next summer i will either work part time while studying or focus 100% on my studies.
All in all, this has been a great learning experience, and also a fun project!