**My project tutorial**
# How to build my IoT AirSense monitoring solution
| Project name | Project photo |
|:------------:|:--------------------------------:|
|Simple AirSense monitoring solution |  The final project |
| Student name | Credentials | Photo |
|:--------:|:--------:|:--------:|
| <div style="width: 180px">Sara Sjödin Scolari</div> | <div style="width: 150px">ss266ud</div> |  Sara|
**Short project overview:**
AirSense is an IoT solution designed to monitor air quality and environmental conditions using a Pico WH board, a DHT-22 (which is a temperature and humidity sensor). The plan was to also include a MCU-81 gas sensor, but the data pin never revealed any data.
The collected data has been visualized using Adafruit.
The additional goal was to connect with a LoRa WAN module for long-range communication, integrating with LoRaWAN networks like The Things Network (TTN) or Helium. However, I chose to prioritize a **well-documented project and a thorough learning process** over rushing to achieve this goal.
**Total project time:**
Approximately 80 hours. A significant portion of this time was dedicated to troubleshooting the MCU-81 data pin and developing this detailed instruction guide.
## Objective
**Why I chose this project:**
This project was chosen to explore environmental monitoring using IoT technologies, providing a hands-on experience with sensors, data visualization, and a low-code IoT platform.
**My purpose with the project:**
Living in Milan, Italy, where air pollution is a significant concern, has motivated me to monitor air quality and environmental conditions to better understand and manage their impact on my daily life. As a former STEAM teacher for young learners, I am passionate about creating clear, straightforward instructions that even IoT beginners can easily follow to successfully start their first project.
**My expected insights:**
Real-time data capturing gas, temperature and humidity levels and trends and patterns in environmental conditions.
## List of material
| Item | Store | Price | Photo |
|:--------:|:--------:|:--------:|:--------:|
|<div style="display:block">GeeekPi Raspberry Pi Pico WH Ultimate IoT kit, including: Breadboard and jumper wires, Power supply (USB cable), Breadboard </div>| Amazon Italy | 79,99 EUR |  An IoT kit with a Pico WH board |
|DHT-22 temperature and humidity sensor with breakout board (3 pins) | Amazon Italy | 11.96 EUR |  DHT-22 temperature and humidity sensor |
|MCU-81 gas sensor| Amazon Italy | 28.79 EUR |  MCU-81 gas sensor |
|LoRa node module (excluded from the project)| Amazon Italy | 22,50 EUR |  LoRa node module with antenna |
|Soldering iron I bought some time ago| Amazon Italy | 26,93 EUR |  A soldering iron |
|Some additional materials I’ve accumulated at home over time from various Arduino kits and projects| - | - | N/A |
| Additional sensor | Photo |
|:--------:|:--------:|
| Additional sensor a push button from one of my Arduino sets |  </br>A push button
|
## Computer setup
### 1. Choose your IDE
:::info
:information_source: IDE means Integrated Development Environment. It’s a software application that provides tools and features for writing, testing, debugging, and managing code. IDEs typically include a code editor, compiler or interpreter, debugger, and other development tools, all integrated into a single environment. Developers use IDEs to streamline their workflow and enhance productivity.
:::
| Pros using Thonny  |
| -------- |
| **Beginner-Friendly:** Thonny is designed for beginners, with an easy-to-use GUI. It opens quickly, allowing you to start typing code right away. |
| **Basic Python Tools:** Thonny comes with all the basic Python tools built-in, so you don’t need to install additional software. |
| **Low Learning Curve:** It’s straightforward to find where to run, pause, and stop Python scripts. The Shell is also visible at the bottom. |
| So why choose Visual Studio Code?  |
| -------- |
| Visual Studio Code is a **powerful programming IDE** with extensive capabilities, but it has a steeper learning curve compared to Thonny. |
| **A specific advantage:** You can enable development mode, allowing changes to be uploaded immediately to the Pico board while programming. |
In the end I chose Thonny, even if I've been programming with Visual Studio Code many years and I wanted to utilize the neat "development mode" function. Why? Because of it's semplicity.
### 2. Installation of Thonny 
* Always download the **lastest** [Thonny installation file](https://thonny.org/) for your operating system from the Official Website.
* Execute the downloaded file by double clicking it.
* Open Thonny after installation and choose Tools / Option / Interpreter and select: "MicroPython" and "Try to detect port automatically"
* When you can see your board connected in the bottom right corner of the Thonny Shell window, the board is correctly connected. 
:::success
My Thonny installation has been verified.
:::
### 3. Installation of Python and node.js  
If you're using Thonny, there's no need to install Python separately as it comes bundled with the required Python environment. However, if you prefer to use Visual Studio Code with the PyMakr extension, you will need to install Python, as well as node.js on your system.
### 4. Check the Device Manager
The Device Manager helps identify issues with driver installation and board recognition. You can find the Device Manager by searching "Device Manager" in the search menu.

How to open the Device Manager.
See next step.
### 5. Connect the Pico board to the computer 
* Before connecting the Pico with the computer, open the Device Manager by searcing for "Device Manager" in the search menu.</li>
* Take a note of the ports being used.

Fig.16 - The ports information in Device Manager.
* Connect the Pico WH to the computer with the USB cable.

Connect Pico and computer with USB cable.
* After connecting check once again the Device Manager to view the additional, newly added USB port. This is the USB port being used by the Pico board.

The ports information in Device Manager.
If the Pico board isn’t detected, checking the Device Manager can reveal missing drivers or connection problems.

Device Manager without problems.
:::success
I have verified that my computer is using the COM4 for the Pico board and that my USB Serial Device COM4 is working.
:::
### 6. Firmware installation 
:::info
:information_source: The Pico board, like any microcontroller, comes with factory firmware initially installed. This firmware typically provides basic functionality or a bootloader. The bootloader enables the device to accept new firmware files (via USB).
Always ensure that you update to the latest MicroPython firmware. Keep in mind that the firmware is specific to each microcontroller, so choose wisely.
:::
When flashing the board, it will overwrite the previous firmware with the new MicroPython firmware.
* Always download the **latest** [MicroPython Pico W firmware](https://micropython.org/download/RPI_PICO_W/) (for the Pico WH board).
* When I did this project the following version was the latest: **v1.23.0 (2024-06-02).**

Firmware files.
* Click the "bootsel button" on the Pico, while connecting the Pico WH to the computer with the USB cable.

Bootsel button placement on board.
* The above action prepares the Pico hardware for flashing and makes it visible in the Windows Explorer.

The Pico WH hardware is visible in the Windows Explorer tree
* Drag and drop the firmware file (also called "flashing") directly in Windows Explorer by dragging the recently downloaded uft-file onto the device in Microsoft Explorer.
* After flashing, eject the device if necessary.
:::info
:information_source: We only need to press down the bootsel button, when we need to update the firmware.
:::
### 7. Verify the board and firmware installation from the Thonny Shell window
```python=1
import sys
sys.implementation
```
* Run each row of the above code in the Shell window. It will provide details about the interpreter itself, such as the version and platform.
* Below you can see the output:

* But even by looking at the command line, or by restarting it by pressing the STOP symbol  of the Thonny IDE the follwing information is visible:

:::success
The latest MicroPython has been installed and verified for my Pico WH board.
:::
### 8. Simple test to run a MicroPython test in the IDE
Let's write a short print statement test, to get more confortable with the IDE and MicroPython:
```python=1
print("Good luck with your studies, from LNU!")
```
After pressing "Run current script"  the following text is visible in the Shell window:

A short print statement test with MicroPython.
### 9. Connecting the Pico WH to the Wi-Fi network 
```mermaid
graph LR
Pico_hardware --> WiFi_Connection --> End_Point:_No_further_actions_so_far
```
To connect the board to Wi-Fi the following files need to be installed to the Pico board:
**Reference to files and file structure:**

- [Simple boot setup with two files](https://github.com/sarasjodin/pico-wh/tree/master/002_wifi/simple_boot_test) from my GitHub repository including:
- [boot.py](https://github.com/sarasjodin/pico-wh/blob/master/002_wifi/simple_boot_test/boot.py)
- [keys.py](https://github.com/sarasjodin/pico-wh/blob/master/002_wifi/simple_boot_test/lib/keys.py)

Showing a successful Wi-Fi connection.
:::success
My Pico WH has been connected correctly to my Wi-Fi network.
:::
Another way to verify if the board is connected to Wi-Fi run the following code in the IDE (which is a typical "Python if-else statement"):
```python=1
import network
if hasattr(network, "WLAN"):
print("WiFi (WLAN) is supported.")
else:
print("WiFi (WLAN) is not supported.")
```
Below you can see the output: "WiFi (WLAN) is supported".

A terminal print out of the if-else statement.
:::success
My Pico WH has been connected correctly to my WiFi network.
:::
## Additional sensors tested before starting the project

Before testing with different sensors and actuators, I decided to connect all the ground pins together, effectively creating a common ground reference for my circuits. This ensures a stable and consistent ground for all components in the tests.
The U-Shaped Jumper Wires came from an Arduino set I had laying around at home.
Before starting with the AirSense monitoring project, I initially wanted to experiment with additional sensors. However, I encountered challenges in finding the right timing to accurately register button presses with this push button and decided to focus on the main project to ensure I had enough time to complete it successfully.
Here is the code showing that for this push button sensor it wasn't necessary to add a 10Ω pull-down resistor:

## Solder the gas sensor
I have experience with both soldering and welding, although it’s been many years since I last did it. Now, I finally got to use my soldering iron, which I bought quite some time ago.

Before soldering I decided to watch an instruction on YouTube, just to get some last minute tips. This one is quite good: https://youtu.be/uVdRDWuIn1Y?feature=shared
### Preparation before soldering:
- Pre-heat the soldering iron for a few minutes before soldering to ensure it reaches the proper temperature. **It needs to be fully hot.**
- When a circuit board needs to be soldered on only one side, it's important to support the other side to ensure that the board remains level and horizontal also after soldering.

### Soldering Steps
> - Heat the Joint: Place the iron tip on the pin and pad simultaneously to heat both.
> - Apply Solder: Touch the solder to the joint, not the iron, so the solder melts and flows into the joint.
> - Remove the Iron: Once the solder flows, remove the iron and let the joint cool naturally.
### Soldering result

| Before | After |
| -------- | -------- |
|  |  |
## Installing the sensor for the actual project
### Microcontroller setup
I started to install the DHT22 Temperature Humidity Sensor Module.

Wiring the DHT22 Sensor to a PICO WH:
- All the **PICO WH ground pins** (no. 3, 8, 13, 18, 23, 28, 33 and 38) are all connected to the **breadboard's ground rail**, effectively creating a common ground reference for my circuits. This ensures a stable and consistent ground for all components in the tests.
- **DHT11 GND pin** is connected to the **breadboard's ground rail**.
- The **3V3(out) pin** from the PICO WH is connected to the **breadboard's positive voltage rail**. This provides a stable 3.3V to power the sensor.
- **DHT11 VCC pin** is connected to the **breadboard's positive voltage rail**.
- **DHT11 DATA pin** is connected to **PICO W pin 19**, which corresponds to GPIO14.
### DHT22 standalone software
**Reference to file and file structure:**

- [main.py](https://github.com/sarasjodin/pico-wh/blob/master/001_standalone_components/dht22/main.py) from my GitHub repository

:::success
The functionality of the DHT22 sensor has been verified (standalone test, no Wi-Fi).
:::
### DHT22 connected to Wi-Fi software
**Reference to file and file structure:**

- [main.py](https://github.com/sarasjodin/pico-wh/blob/master/002_wifi/simple_boot_DHT22_test/main.py) from my GitHub repository
- [boot.py](https://github.com/sarasjodin/pico-wh/blob/master/002_wifi/simple_boot_DHT22_test/boot.py) from my GitHub repository
- [keys.py](https://github.com/sarasjodin/pico-wh/blob/master/002_wifi/simple_boot_test/lib/keys.py) from my GitHub repository
NB! Add your specific keys.

:::success
The functionality of the DHT22 sensor has been verified with Wi-Fi connection.
:::
After the Temperature and humidity sensor I started to wire the gas sensor MCU-81. Unfortunately I never received any datasheet when I bought it and it has created some problems for me getting the data registrations from the sensor. I even tried to run the sensor continuously for 24 hours to allow it to stabilize, since the errors might resolve as the sensor conditions itself - but it didn't.

**Some outputs from the MCU-81 testing**
DHT22 Temperature: 26.8°C
DHT22 Humidity: 61.7%
Updated ENV_DATA with Temp: 26.8°C, Humidity: 61.7%
Raw I2C data: b'\x03\xfd\xfd\xfd'
MCU-81 eCO2: 1021 ppm
MCU-81 eTVOC: 65021 ppb
MCU-81 Temperature: 26.8°C
MCU-81 Humidity: 61.7%
STATUS: 0b10001
ERROR_ID: 0x3
Conditioning period complete, checking for stable readings.
:::info
MCU-81 data pin non functioning. More testing needed.
:::
## Visualizing the data through Adafruit  
```mermaid
graph LR
Pico_hardware --> WiFi_Connection --> Adafruit_Cloud --> Low-code_Adafruit_Visualization
```
Adafruit is a **cloud-based online platform** that allows me to collect, store, and visualize data from my Internet of Things (IoT) project. As a **low-code solution**, it’s designed to be easy to use by hobbyists who want to monitor electrical and connected hardware over the internet. It is possible to access it from anywhere through a web browser or mobile app.
I'm only planning to use the **free-tier** account of Adafruit, since it provides enough **features** for my small project:
- Data Collection: Gather data from sensors and devices.
- Data Storage: Securely store data in the cloud.
- Data Visualization: Create dashboards with graphs and widgets.
- Triggers and Alerts: Automate actions based on specific conditions.
- APIs: Programmatically access and integrate the data.
Some **limitations** (typical of free-tier services):
- Limited Data Points: Up to 30 data points per minute.
- Limited Feeds: Creation of up to 10 feeds.
- Basic Dashboards: With some limitations of widgets, color schemes, etc.
**First steps**
* Create a [Adafruit account](https://www.adafruit.com/), preferably with a "Two-factor Authentication" under Account settings / Security and Privacy and verify the e-mail registered for the account.
* Get the "ADAFRUIT_AIO_USERNAME" and the "ADAFRUIT_AIO_KEY" from the black key icon on the yellow background in the upper right corner of the Adafruit webpage.

* If you wish to group certain data together (in my case "dht22"), please name the feeds like this in your Python code:
```python=1
AIO_FEED_TEMP = keys.AIO_USER + "/feeds/dht22.temperature"
AIO_FEED_HUM = keys.AIO_USER + "/feeds/dht22.humidity"
```
**Reference to files and file structure:**

- [main.py](https://github.com/sarasjodin/pico-wh/blob/master/002_wifi/dht22_umqtt-adafruit/main.py) from my GitHub repository
- [keys.py](https://github.com/sarasjodin/pico-wh/blob/master/002_wifi/dht22_umqtt-adafruit/lib/keys.py) from my GitHub repository **NB! Add your specific keys.**
- [robost.py](https://github.com/micropython/micropython-lib/blob/master/micropython/umqtt.robust/umqtt/robust.py) from micropython's GitHub repository
- [simple.py](https://github.com/micropython/micropython-lib/tree/master/micropython/umqtt.simple/umqtt/simple.py) from micropython's GitHub repository
- use the same boot file as before for Wi-Fi connection.

:::success
MQTT communication with Adafruit IO using umqtt has been successfully verified.
:::
To be able to choose a new group feed's value for a new dashboards, you'll have to look for a collapsed group. See below photo.

This is a photo of my finilized Adafruit DHT22 data visualization:

:::success
The functionality of the Adafruit data visualization dashboard has been verified.
:::
The orange squared markers are periods where my data registration was turned off for programming:

1. I exhaled near the PICO board to observe any changes in temperature and humidity. Shortly afterwards, I opened the front door to let in some of the warm summer air from Milan.
2. However, I quickly closed the door to prevent the indoor temperature from rising to the outside 37°C.


## Integrating Adafruit with Discord: Setting Up Webhooks for Real-Time Data Updates 
```mermaid
graph LR
Pico_hardware --> WiFi_Connection --> Adafruit_Cloud --> See_next_row...
```
```mermaid
graph LR
...Adafruit_Feed --> Triggers_Adafruit_Action --> Discord_Webhook --> Discord_Channel
```


I wasn’t sure how much I would be able to accomplish during this summer course, due to given the unfamiliar sensors, the missing MCU-81 datasheet, and other commitments I had made. However, my eagerness to take a step-by-step approach in my IoT learning journey motivated me to prepare for the next steps. Having an action plan makes it much easier than to start from scratch.
To better visualize my upcoming ideas and ensure I understand the strengths of each tool, I prepared a series of steps. These visualizations will help me explore different tools and their unique offerings as I move forward.
## Alternative low-code solution  
```mermaid
graph LR
Pico_hardware --> WiFi_Connection --> Datacake_Cloud --> Low-code_Datacake_Visualization
```
## LoRa node with TTN  
**For long-range LoRa communication**
```mermaid
graph LR
Pico_hardware --> LoRa_Node --> LoRaWAN_Gateway --> TTN_Network --> Adafruit_Webhook --> Low_Code_Adafruit_Visualization
TTN_Network --> Adafruit_MQTT --> Low_Code_Adafruit_Visualization
TTN_Network --> Datacake_Webhook --> Low_Code_Datacake_Visualization
TTN_Network --> Datacake_MQTT --> Low_Code_Datacake_Visualization
```
We have several options when it comes to integrating TTN with other services. Webhooks and MQTT are the most commonly used, but depending on our project requirements, we might explore other alternatives like direct cloud integrations (Azure, AWS, Google), HTTP integrations, or even using platforms like IFTTT for automation.
## LoRa node with Helium  
**For long-range LoRa communication**
```mermaid
graph LR
Pico_hardware --> LoRa_Node --> Helium_Gateway --> Helium_Network --> Adafruit_Webhook --> Low-Code_Adafruit_Visualization
Helium_Network --> Adafruit_MQTT --> Low-Code_Adafruit_Visualization
Helium_Network --> Datacake_Webhook --> Low-Code_Datacake_Visualization
Helium_Network --> Datacake_MQTT --> Low-Code_Datacake_Visualization
```
When it comes to integrating Helium with other services, you have several straightforward options. Webhooks and MQTT are the most commonly used methods for sending data from the Helium Network to various platforms. Depending on your project requirements, these integrations can effectively connect your IoT data to visualization platforms like Adafruit and Datacake.
## LoRa node with a self-hosted IoT solution 
**For long-range LoRa communication**
```mermaid
graph LR
Pico_hardware --> LoRa_Node --> LoRaWAN_Gateway --> TTN_Network --> Self-hosted_Solution --> TIG_stack
Self-hosted_Solution -->ELK_stack
Self-hosted_Solution -->Mosquitto/NodeRed
```
## Transmitting the data / connectivity
**Sensor limitations:**
The DHT22 sensor should be **sampled no more than once every 2 seconds**. Sampling more frequently may cause inaccurate readings and reduce sensor lifespan.
**Platform limits:**
Adafruit Free Account has limits and **allows up to 30 data points per minute**. This equates to one data point every 2 seconds, which aligns well with the DHT22’s capabilities.
**Application requirements:**
I believe that for general environmental monitoring, **updating the data every 15 seconds should be sufficient**.
## Finalizing the design
| Whole board | DHT22 sensor |
| -------- | -------- |
|  | 
|
I had initially hoped to build something more complex and spend more time experimenting with additional components. However, I'm thrilled with the comprehensive instructions I've been able to create. Contributing to others' future success is something I deeply enjoy, and I’m excited to continue being an active member of the Linnaeus University Discord community. Once you're hooked on I♥T projects, there's no turning back!