*Name: Hampus Kraft
Student ID: hk223bz*
# Short Project Overview
This project is about monitoring temperature and humidity with alerts. Raspberry Pi Pico W will be connected to a cloud service called Adafruit, which is monitoring the sensor data.
**Estimated time to follow this tutorial**
1-3h
# Objective
Reason for choosing this project is to help regulate the temerature of my apartment in the hot summers.
With alerts that reminds me when it's too hot and needed to ventilate the apartment.
This project will provide insights of simple iot circuits and programming in micropython.
# Material
| Component | About | Price |
| -------- | -------- | -------- |
| Raspberry Pi Pico W | Microcontroller board with 2 cores and a built in wifi module. This is the systems "brain" that collects data from the sensors and communicates. | 98 SEK |
| DHT11 | Temperature and Humidity Sensor | 49 SEK |
| Jumper wires | 40pin Male/Male jumper wires to connect the components together | 49 SEK |
| Breadboard | Breadboard with 840 connections | 69 SEK
| Micro-USB cable | USB type A to USB type MicroB. Used to connect Raspberry Pi Pico W |39 SEK|
The prices are based on electrokit.com, where I also made my purchase.
# Computer Setup
**IDE Setup**
The IDE i've chosen to code on is Visual Studio Code together with Pico-W-Go plugin.
Visual Studio Code can be downloaded and installed from [here](https://code.visualstudio.com/download).
When Visual Studio Code is installed, head to the left menu and look for "Extentions". Then search for "Pico-W-Go" and install. As shown in the following figure:

Then you should be able to press the settings icon in the left down corner and select "Command Palette...", then you can search for "Pico-W-Go" and use the plugins commands.
**Pico Setup**
The Raspberry Pi Pico W will be flashed with the newest MicroPython firmware. This is done by holding down the BOOTSEL button on the Raspberry Pi Pico W while connecting it to the computer via the USB Cable. You should then be able to find the storage of the Pico in file explorer, which is where you should drag your MicroPython firmware to. The firmware can be found [here](https://micropython.org/download/rp2-pico-w/).
You are now setup to develop scripts for your Raspberry Pi Pico W. Open a new project in Visual Studio Code and make a "main.py" file and then use the command palette to "Configure Project", this will add necessary files for the script to run. Then again use the command palette to "Upload Project" to the Pico, then you can run it directly from Visual Studio Code.
**Putting everything together**

This picture shows everything when it's put together. Every component is placed on the white breadboard, where the green board is the Raspberry Pi Pico W and the blue module the DHT11 sensor. I will show the electric circuit bellow:

The DHT11 Sensor has 3 pins, where the first pin is a Signal/Data pin, and therefore connected to a GPIO on the Raspberry Pi Pico (in this case GP13). The second/middle pin of the DHT11 is VCC, which require power, therefore is connected to the 3v3 output pin on the Pico. The third and last pin of the DHT11 is ground and is connected to one of the ground pins on the Pico(in this case pin 38).
# Platform
The Cloud service used in this project is Adafruit, which is a simple, but good alternative for smaller iot projects like this. It can also be used for slightly bigger projects, but requires a paid plan for that. In this case the free plan was enough to host our service.
Adafruits delivers a stable cloud connection with a customizeable dashboard and up to 10 data feeds with a total of 30 requests per minute on the free plan.
# The code
**Library and declaration**
Let's start with importing the required libraries for this project, but also declare the pins that are going to be used on the Pico. The machine.Pin('LED') is the built in led on the Pico board. Pin 13 is the sensoring pin which will recieve a data from the DHT11 sensor. This is shown in the snippet below.
```python
import time
import network
from machine import Pin
from dht import DHT11 #dht.py in project folder
from simple import MQTTClient #simple.py in project folder
import _thread
led=machine.Pin('LED', machine.Pin.OUT)
pin = Pin(13, Pin.OUT, Pin.PULL_DOWN)
sensor = DHT11(pin)
```
**Wi-Fi**
Now we're going to setup the Wi-Fi connection between the Pico W and your router. For this you will need to know your SSID and Password to replace "MY_SSID" and "MY_PASSWORD" to be able to establish a connection to your Wi-Fi using wlan.connect as such:
```python
# Connect to Wi-Fi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("MY_SSID", "MY_PASSWORD")
i = 0
while wlan.isconnected() == False:
print('Waiting for connection...',i)
i = i + 1
time.sleep(1)
print("Connected to WiFi.")
```
Your device will wait in the while-loop as it waits to be connected to the wlan, and if the connection was established successfully it will say "Connected to WiFi" and you are ready for the next step!
**MQTT**
We're now going to use our wlan connection to send and recieve messages from our cloud server, which in this case is Adafruit.
```python
# MQTTClient and connect to the MQTT server
mqtt_client = MQTTClient(
client_id="MY_CLIENT_ID",
server="io.adafruit.com",
user="MY_USERNAME",
password="MY_PASSWORD")
mqtt_client.connect()
print("Connected to Adafruit.")
```
You setting up a connection between the MQTT Client and Server, which is pretty straight forward. You will have to fill in the "MY_CLIENT_ID","MY_USERNAME" and "MY_PASSWORD" with the information you will be provided by Adafruit.
**Setting an alert threshold**
We will now be setting an alert threshold, this variable will be customizable from the cloud dashboard. This means that our Pico will have to listen to changes in that feed/"topic" as such:
```python
# Define the variable to store the latest value
threshold = 30.0 #default start value
# Define the callback function to handle incoming messages
def callback(topic, msg):
global threshold
threshold = float(msg.decode('utf-8'))
print("Threshold changed to ",threshold)
mqtt_client.set_callback(callback)
mqtt_client.subscribe("MY_USERNAME"/feeds/"YOUR_FEED"")
print(f'Subscribed to feed: slider')
```
The defined starting value of the threshold is 30 degres celcius but can be changed later on by the slider. The "callback" function is listening to the topic that is set by the subscription the second last row, and is decoding the message to just contain the sliders value. That value is now the new threshold and will be printed in the console.
**The Loop - Core 0**
In the following code snippet is the loop that runs on core 0, which does the most of the work. It gathers the data from the DHT11 sensor and then publish the data to the specified feed. Then it compares the temperature reading of the sensor to the latest set threshold, if the threshold is passed it displays a "WARNING" in the console, but also light up a warning/alert led on the onboard Pico.
```python
def core0_thread():
i=0
while True:
time.sleep(3)
try:
t = float(sensor.temperature)
mqtt_client.publish("YOUR_USERNAME""/feeds/"YOUR_FEED"", str(t))
except:
print("Error: temperature reading failed.")
time.sleep(1)
continue
time.sleep(3)
try:
h = float(sensor.humidity)
mqtt_client.publish("YOUR_USERNAME""/feeds/"YOUR_FEED"", str(h))
except:
print("Error: humidity reading failed.")
time.sleep(1)
continue
print("- - - - Loop:",i," - - - -")
i=i+1
if t >= threshold:
print("----------------------------")
print("WARNING - Threshold reached!")
print("----------------------------")
led.value(1)
else:
led.value(0)
print("temperature:", t)
print("humidity: ", h)
print("threshold: ", threshold)
```
**The Loop - Core 1**
The loop for core 1 constantly listens for a new output from the threshold feed.
```python
def core1_thread():
while True:
mqtt_client.wait_msg()
```
By having 2 separate loops running simultaneously you never have to wait for the other loops delays and processes to be done before running a certain line. This way you can change the threshold slider at anytime with an instant effect.
**Starting the loops/threads**
```python
second_thread = _thread.start_new_thread(core1_thread, ())
core0_thread()
```
# Transmitting the Data / connectivity
**How often is data sent?**
Every 3 seconds is planned to send a data feed to the cloud, switching between temperature and humidity each time.
**How often is data recieved?**
Data is recieved instantaneously when the threshold slider has been changed on the cloud. Too many quick changes can lead to the API to throttle since the free plan only supports up to 30 updates per minute.
**What protocols are used?**
The communication between the Raspberry Pi Pico and the router is done via a WiFi protocol.
The data transportation between the Pico and the cloud server was done via a MQTT protocol, which is a "publish-and-subscribe" messaging model and are therefore very lightweight and perfect for iot devices.
# Presenting the data
The Adafruit dashboard contains of 5 segments, which is:
* Real-time temperature reading
* Real-time humidity reading
* Past 24h temerature reading
* Past 24h humidity reading
* Interactable threshold slider for the alert

Data is saved to the database as often as it recieves feed from the Pico. Though it does only keep the data stored for 30 days with the free plan.
# Finalizing the design

I'm satisfied with how the project turned out and learned quite a bit on the journey. Though if I could continue to work on it, I'd probably try to connect it to a relay with some form of cooling equipment (AC, Fan etc). Instead of just giving a alert, it is automated to try to regulate the temerature to stay under the set treshold.