# ComfortZone ⛅ The straightforward indoors climate check
Ana Gabriela Carlos Andrade Uzeda Accioly, ac223qm - June 2024
## Tutorial Overview
This project is a tutorial that aims to guide a total beginner through building an IoT "ComfortZone" system using a Raspberry Pi Pico, a DHT11 sensor, a MCP9700 sensor, and a Mac. This system monitors its immediate surrounding environment's temperature and humidity, helping to assess whether they remain within ideal conditions.
This project takes about 7 hours to complete and takes you through every step of its completion so it is as easy as possible to follow. If you notice anything that could be clearer, please highlight and comment on it. I will be glad to further facilitate the journey!
### Objective
Ever crank up the air conditioner or humidifier, only to find yourself still feeling uncomfortably warm or cool? You know your system is running, but why isn't it achieving the desired comfort level? This project tackles that exact frustration. By building a ComfortZone, you'll be able to gain insights to help you better manage your climate control gears to create a consistently comfortable space by pinpointing issues to optimize your system for peak comfort. Or maybe you will learn that it's your body that needs more water for thermoregulation!
### Materials
|component |description |qtty | store and price |
|-------------------------|-------------------|:---------------------------:|---------------------------|
| Raspberry Pi Pico <figure> <img src="https://www.electrokit.com/cache/ba/317x230-product_41019_41019114_PICO-WH-HERO.jpg" alt="Raspberry Pi Pico" height="220"/> <figcaption>Fig. 1</figcaption> </figure>| this microcomputer is the brain of the operation, collecting and processing sensor data|1| Electrokit (part of "Start Kit - Applied IoT at Linnaeus University; 2024" - 399 SEK)|
| MCP9700 Sensor <figure> <img src="https://www.electrokit.com/upload/product/41011/41011628/41010569.jpg" alt="MCP9700 Sensor" /> <figcaption>Fig. 2</figcaption> </figure>|this sensor adds a layer of accuracy by triangulating the temperature data given by the digital sensor below|1|Electrokit (part of "Start Kit - Applied IoT at Linnaeus University; 2024" - 399 SEK)|
| DHT11 Sensor <figure> <img src="https://www.electrokit.com/upload/product/41015/41015728/41015728.jpg" alt="DHT11 Sensor" /><figcaption>Fig. 3</figcaption> </figure>| this sensor directly measures temperature and humidity for initial readings| 1 |Electrokit (part of "Start Kit - Applied IoT at Linnaeus University; 2024" - 399 SEK)|
|Jumper Wires, 15cm Male/Male <figure> <img src="https://www.electrokit.com/cache/24/700x700-product_41012_41012684_41012684.jpg" alt="Labbsladd 40-pin 30cm hane/hane"/><figcaption>Fig. 4</figcaption> </figure>| jumper wires commonly used for breadboards, with male connectors on both ends for easy connection between components on the breadboard|10|Electrokit (part of "Start Kit - Applied IoT at Linnaeus University; 2024" - 399 SEK)|
|USB A-Male to Micro B-Male Cable, 1.8 m <figure> <div style="text-align: center;"> <img src="https://www.electrokit.com/cache/ad/700x700-quick_54_1f_9382_41003290.png" alt="41003290 USB-kabel A-hane - micro B 5p hane 1.8m" height="180" /> </div> <figcaption>Fig. 5</figcaption> </figure>|standard USB cable with a Type-A connector on one end (flat, rectangular) that plugs into a computer and a Micro B connector on the other end (smaller, asymmetrical) that connects to Raspberry Pi Pico to provide power and program it|1|Electrokit (part of "Start Kit - Applied IoT at Linnaeus University; 2024" - 399 SEK)|
| Breadboard with 840 Tie Points <figure> <img src="https://www.electrokit.com/upload/product/10160/10160840/10160840.jpg" alt="Kopplingsdäck 840 anslutningar"/> <figcaption>Fig. 6</figcaption> </figure>| a solderless prototyping platform that allows you to connect components using jumper wires without soldering|1|Electrokit (part of "Start Kit - Applied IoT at Linnaeus University; 2024" - 399 SEK)|
|Jumper Wires, 30cm Female/Male <figure> <img src="https://www.electrokit.com/cache/24/700x700-product_41012_41012684_41012684.jpg" alt="Labbsladd 40-pin 30cm hane/hane"/><figcaption>Fig. 6.b</figcaption> </figure>| jumper wires commonly used for breadboards, used for extension of DHT11 in printed box shown at part B of project|3|Electrokit (part of "Start Kit - Applied IoT at Linnaeus University; 2024" - 399 SEK)|
|PrimaCreator EasyPrint PLA 1.75mm 1 kg Brons <figure> <img src="https://i.postimg.cc/0Nkt3DMS/Screen-Shot-2024-08-18-at-21-40-11.png" alt="bronze_PLA"/><figcaption>Fig. 6.b1</figcaption> </figure>| Flexible, strong PLA filament for a variety of prints. Low warping, great for large and small parts. For 3D printing the project extension|1|InkClub- 349,90 SEK)|
In this project, Raspberry Pi Pico (Fig. 1) is used. This is a compact and powerful microcontroller programmed using MicroPython, a user-friendly language ideal for beginners and experienced makers alike. The Pico has a variety of built-in features, including digital and analog input/output pins, making it perfectly suited for building an Internet of Things (IoT) project like ComfortZone.
### Computer Setup
This is a quick process, just follow the steps one-by-one.
**1. Install Node.js:** This is a program that runs behind the scenes and helps working with MicroPython. Download and install it from:
https://nodejs.org/en/download/prebuilt-installer
Once installed, open Terminal (Command + Spacebar to open Spotlight Search.
Type “Terminal” and press Enter or Return) and type:
<code class="bash hljs">
<span class="hljs-built_in">which</span>
node
</code>
If installed correctly, Terminal will show something like this (where usr is your Mac's username):
<code class="bash hljs">
<span class="hljs-built_in">/usr/local/bin/node
</code>
**2. Install Visual Studio Code (VS Code):** This is the coding editor used, a program where to write the code for ComfortZone, a step that comes later. This program is popular because it's powerful and has lots of features built-in and is great for this project because it can work with MicroPython, the programming language used for ComfortZone. You can download it from:
https://code.visualstudio.com/Download (if the Mac already had VSCode installed and running during the nodejs installtion, restart your Mac).
**3. Install Pymakr:** This is an extension for VS Code that helps working with Pico. Open VS Code and on the left bar, click on extension:
<figure style="text-align: center;">
<div>
<img src="https://i0.wp.com/www.phdata.io/wp-content/uploads/2021/06/VSCode-Extension-Icon-.png" alt="VS Code extension icon" height="100" />
</div>
<figcaption>Fig. 9</figcaption>
</figure>
On the search bar (top of middle-left column), type Pymakr and install it. It should have the following icon and say "official Pymakr plugin":
<figure style="text-align: center;">
<div>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAIVBMVEX///8eHjxWVmyOjp3x8fMrK0fHx86AgJFkZHjj4+eqqraERLDQAAAC8klEQVR4nO3R607jQBBEYZNluez7P/AC4eIktgd3l3UKVP17NKWjb5pyuVwul8vlcrlcLpfL5XK5XC6Xy+Vyudzh93jq37/5h4L/niohp7v+/Zl/qP7vB4f8vf8lISUQw5AaiGFIDcQvpAjiF1IEsQupgtiFVEHcQsogbiFlELOQOohZSB3EK6QB4hXSALEK6YBYhXRAnEJaIE4hLRCjkB6IUUgPxCekCeIT0gSxCemC2IR0QVxC2iAuIW0Qk5A+iElIH8QjRADiESIAsQhRgFiEKEAcQiQgDiESEIMQDYhBiAaEDxGB8CEiEDxEBYKHqEDoEBkIHSIDgUN0IHCIDoQNEYKwIUIQNEQJgoYoQcgQKQgZIgUBQ7QgYIgWhAsRg3AhYhAsRA2ChahBqBA5CBUiB4FC9CBQiB6ECTkAhAk5AAQJOQIECTkChAg5BIQIOQTkGyGPD6N73hVyDMg4ZO8uBDIO2bsLgQxDdu9CIMOQ3bsQyChk/y4EMgrZvwuBDEIKuxDIIKSwC4Fsh1R2IZDtkMouBLIZUtqFQDZDSrsQyFZIbRcC2Qqp7UIgGyHFXQhkI6S4C4Gsh1R3IZD1kOouBLIaUt6FQFZDyrsQyFpIfRcCWQup70IgKyGNXQhkJaSxC4Esh3R2IZDlkM4uBLIY0tqFQBZDWrsQyFJIbxcCWQrp7UIgCyHNXQhkIaS5C4HchnR3IZDbkO4uBHIT0t6FQG5C2rsQyHVIfxcCuQ7p70IgVyGCXQjkKkSwC4Fchih2IZDLEMUuBHIRItmFQC5CJLsQyDxEswuBzEM0uxDILES0C4HMQkS7EMhXiGoXAvkKUe1CIJ8hsl0I5DNEtguBfITodiGQjxDdLgTyHiLchUDeQ4S7EMg5RLkLgZxDlLsQyFuIdBcCeQuR7kIgryHaXQjkNUS7C4G8hIh3IZCXEPEuBDKd1LsQyHRS70Ig05N6FwKZnsdP9h0EksvlcrlcLpfL5XK5XC6Xy+VyuR95/wF4ey/wjL8aCAAAAABJRU5ErkJggg==" alt="Pymakr plugin icon" height="100" />
</div>
<figcaption>Fig. 10</figcaption>
</figure>
Now the Pymakr icon should show up somewhere below the extension icon on the left bar. Click on it. On the column where you had found the search bar, it should now show "projects" on top and on the lower area, "Devices". This confirms the previous steps were taken correctly.
**4. Preparing the Pico:** Gather the Pico (remove sponge), the Breadboard, and the USB cable.
>**4.1.** Press Pico (Fig.1) firmly into Breadboard (Fig. 6; occupying positions 1C to 1H - the side of Pico with the USB connector on the edge - all the way to 20C to 20H), so there is no left space in between Pico's sides and the board.
<figure style="text-align: center;">
<div>
<img src="https://projects-static.raspberrypi.org/projects/getting-started-with-the-pico/5ebf38b3cdb484ab2185f695b89dd81d190516d1/en/images/Pico-Top-Breadboard.png
" alt="Pico with Breadboard" height="300" />
</div>
<figcaption>Fig. 11</figcaption>
</figure>
>**4.2.** Connect USB's Micro B side to Pico (notice that this image is not showing the Breadboard, but they are connected at this point)
<figure style="text-align: center;">
<div>
<img src="https://projects-static.raspberrypi.org/projects/getting-started-with-the-pico/5ebf38b3cdb484ab2185f695b89dd81d190516d1/en/images/Pico-Top-Plug-v2.png
" alt="Pico with USB" height="260" />
</div>
<figcaption>Fig. 12</figcaption>
</figure>
>**4.3.** Download Micropython into your Mac from:
>https://micropython.org/download/RPI_PICO_W/ (under Firmware, the latest release). A file named uf2 will be downloaded, save it somewhere where you can easily access.
>**4.4.** While firmly pressing the Bootsel button on Pico, connect the USB A to you Mac. When the drive RPI-RP2 shows up in your desktop or on the left side of a Finder window, you may stop pressing Bootsel.
<figure style="text-align: center;">
<div>
<img src="https://kalumajs.org/images/pico-bootsel.png" alt="Pico Bootsel" height="140" />
</div>
<figcaption>Fig. 13 (note that the image here is flipped when compared to the previous ones) </figcaption>
</figure>
>**4.5.** Click and drag the uf2 file (from step 4.3) into the RPI-RP2 drive (from step 4.4).The drive will automatically disconnect. A message might pop up of it being disconnected, you may ignore that.
>**4.6.** (from the Mac only) disconnect and reconnect the USB cable. Remove any other USB connected devices from your Mac. Open VS Code app, click on Pymakr plugin (Fig. 10) and check under Devices (bottom area of left-middle column). You should find an item that has "usb" in its name.
>
>**4.7.** Test by opening a terminal in this device (Fig. 14)
>
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/Y2DsnPnp/Create-Terminal-VSCode.png" alt="Terminal Pymakr" height="360" />
</div>
<figcaption>Fig. 14</figcaption>
</figure>
>> **4.7.** copy and paste the followin text, then press enter/return:
```python
print("Good luck with your studies, from LNU!")
```
>> **4.8.** Check that the text showed up as in Fig. 14.
Great! You just finished another step!
### Putting everything together
At this point you will set up the hardware 💪 You will need the Pico-Breadboard-USB assemble from step 12 disconnected from your Mac. At the next steps, look closely to make sure you are plugging the pins into their assigned columns and rows.
**5.** **Establishing a power supply for your circuit** (notice that the numbers in the images in this section 5 are flipped; follow the numbers in the instructions it will result with distances like the pictures below that have been planned considering the issue with the numbers).
>**5.1** Connect a red wire from column I row 5 (Raspberry Pi Pico's 3V3 OUT) into the second row of the positive column. With this, you're providing power to the positive rail of the breadboard. This 3.3V rail will then supply power to the various components you connect to it.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/2yTL6xWx/1.png" alt="cable1" />
</div>
<figcaption>Fig. 15</figcaption>
</figure>
>**5.2.** Connect a black jumper wire from column I row 3 (Raspberry Pi Pico's GND) into the first row of the negative column. Press the pin right into the whole, it may feel a little wobbly in there, unlike the sensors you will be connecting later. With this you're creating a common ground reference point for all the components in your circuit. This ground acts as the return path for electricity, similar to the negative terminal of a battery.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/Z5Wvbp5r/2.png" alt="cable2" />
</div>
<figcaption>Fig. 16</figcaption>
</figure>
>**5.3.** Creating common positive and negative rails. This ensures that all the positive connection points on the breadboard are electrically connected to each other, and all the negative connection points are similarly connected. This allows you to power components from any point along the positive rail and connect them to ground (negative) from any point on the negative rail (note that the specific row numbers here are not important, but follow it so the finished product remains as clean as possible).
>>**5.3.1.** Connect a red wire from row 44 positive top, to row 44 positive bottom.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/ZnY01yQv/3.png" alt="cable3" />
</div>
<figcaption>Fig. 17</figcaption>
</figure>
>>**5.3.2.** Connect a black wire from row 43 negative top, to row 43 negative bottom.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/VL6dgnM3/4.png" alt="cable4" />
</div>
<figcaption>Fig. 18</figcaption>
</figure>
**6.** **Connecting the MCP9700 Sensor.** This is the analog temperature sensor. With the round side of it turning away from the center of the Breadboard, (turning outwards and the flat side to wards the center) position it so each of its pins can be inserted into column J, rows 30, 31 and 32. Firmly press it in so it is no more than 2 mm away from the breadboard (it's ok if it bends slightly).
>**6.1.** Connect a black wire at column F number 32 going up to the negative column (blue) around row 33. This is grounding the sensor (its right pin is ground when looking at its flat side). This is crucial for proper operation, especially when dealing with analog signals like the voltage output from the MCP9700.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/jjQxtSPH/1-ST-BLACK-MCP.png" alt="1st_black_mcp" />
</div>
<figcaption>Fig. 19</figcaption>
</figure>
>**6.2.** Connect a yellow wire at column I number 31 going up towards Raspberry Pi Pico at column I number 9 (by Pico's GP27). Here you're configuring the Raspberry Pi Pico to read an analog voltage signal from the MCP9700, by connecting the sensor's analog voltage out into an Analog-to-Digital Converter (ADC) pin in Raspberry Pi Pico.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/VvT1DrP8/FIRST-YELLOW.png" alt="1st_yellow_mcp" />
</div>
<figcaption>Fig. 20</figcaption>
</figure>
>**6.3.** Connect an orange wire at column F number 30 going up to the positive column (red) around row 27. This is connecting the Vin (voltage in) pin of the sensor to the power supply, powering the sensor.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/J4fMXkQ3/FIRST-ORANGE-MCP.png" alt="1st_orange_mcp" />
</div>
<figcaption>Fig. 21</figcaption>
</figure>
**7.** **Connecting the DTH11 Sensor.** This is the digital temperature and humidity sensor. With the blue side of it turned towards the center of the Breadboard, position it so each of its pins can be inserted into column H, rows 62, 63, 64. Firmly press it in so it is no more than 2 mm away from the breadboard.
>**7.1.** Connect a black wire at column F number 64 going up to the negative column (blue) around row 62. This is grounding the sensor (its right pin is ground when looking at its blue side).
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/k5cmLhPw/LAST-BLACK.png" alt="last_black_DHT" />
</div>
<figcaption>Fig. 22</figcaption>
</figure>
>**7.2.** Connect a long green wire at column F number 62 going up towards Raspberry Pi Pico at column B number 1 (by Pico's GP0). You're establishing a data connection between the DHT11 sensor and the Raspberry Pi Pico (note that any GP pin from Raspberry Pi Pico would work for this purpose, but keep it like that for a cleaner finish).
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/9F7jcfjD/GREEN.png" alt="green_DHT" />
</div>
<figcaption>Fig. 23</figcaption>
</figure>
>**7.3.** Connect an orange wire at column F number 63 going up to the positive column (red) around row 60. This is connecting the Vin pin os the sensor to the power supply, powering the sensor. This is connecting the Vin (voltage in) pin of the sensor to the power supply, powering the sensor.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/3xj5DbN7/2-ND-ORANGE.png" alt="orange_DHT" />
</div>
<figcaption>Fig. 24</figcaption>
</figure>
The electrical consumption of this hardware is:
|component |standby| peak|
|---|---|---|
|MCP9700|6 µA| 8-10 µA*|
|DTH11| 300 µA| 60 µA*|
* sources: https://ww1.microchip.com/downloads/en/devicedoc/20001942g.pdf
https://www.cytron.io/p-dht11-sensor-module-breakout#:~:text=Specifications%3A,Output%3A%20Serial%20data
That's it for setting up the hardware, congrats! ⭐ 👏 ⭐
### Platform
This project, as described above, was designed for a total beginner with no prior experience with electronics or hardware, and no experience with programming. For that, a meticulous **explanation and elaboration** of steps is laid out.
Because of this goal, **Adafruit** platform is an excellent choice. Here's why:
• Adafruit is great for those new to electronics. Their website offers a wealth of tutorials, guides, and projects designed to be easy to follow. They take complex concepts and break them down into clear, understandable steps that often include visuals and troubleshooting tips.
• It offers a cloud-based platform that simplifies managing data and interactions with one's project. This eliminates the need for complex server setup or additional hardware, making it ideal for smaller projects.
• The free tier of Adafruit's platform provides everything one needs to get started, including the ability to send data (feeds) and receive notifications (messages) within specific limits. This is perfect for experimenting and building small projects like this one. Upgradable plans are available allowing for scalability.
• It has reduced coding requirements. Adafruit's platform can help minimize the amount of code needed to write for basic functionality. This is especially helpful for those who are still learning the ropes of programming.
• Webhook Integration for Notifications. Adafruit's platform leverages webhooks to send notifications (messages), in this case to Discord when certain temperature or humidity thresholds are reached.
Adafruit's platform acts as a communication conduit between this project and Discord. It seamlessly transfers sensor data to the cloud, enabling Discord to generate real-time notifications based on temperature and humidity readings.
**Follow the steps below to begin with Adafruit:**
**8.** Let's start by visiting https://accounts.adafruit.com/, setting up a username and saving the username in a folder on your desktop so you can access very easily later.
**9.** Sign in to the control panel at https://accounts.adafruit.com/users/sign_in
**10.** Click on IO on the top (leftish) of the page.
**11.** Create a **Feed** group by going to Feeds (black bar on topish of the page) > + New Group.
>**11.1.** Name it ComfortZone
>**11.2.** Click on + New Feed and name it Humidity ComfortZone
>**11.3.** Click on + New Feed and name it Temperature ComfortZone
**12.** Create a **Dashboard** to visualize the data. Click on Dashboard (black bar on topish of the page)> + New Dashboard.
>**12.1.** Name it ComfortZone
>**12.2.** Click on ComfortZone
>**12.3.** Click on:
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/0yfRJsw0/Screen-Shot-2024-06-28-at-18-50-48.png" alt="settings" height="60" />
</div>
<figcaption>Fig. 25</figcaption>
</figure>
>>**12.3.1.** + Create New Block
>>>**12.3.1.1.** Select line chart
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/Tw54QMpS/Screen-Shot-2024-06-28-at-18-55-08.png" alt="Line_Chart" height="90" />
</div>
<figcaption>Fig. 26</figcaption>
</figure>
>>>>**12.3.1.2.** Click on ComfortZone
>>>>**12.3.1.3.** Click on Humidity ComfortZone
>>>>>**12.3.1.3.1.** Name Block to Title Humidity ComfortZone
>>>>>**12.3.1.3.2.** Remove Decimal Places
>>>>>**12.3.1.3.3.** Click on Create Block.
>**12.4.** Click again on:
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/0yfRJsw0/Screen-Shot-2024-06-28-at-18-50-48.png" alt="settings" height="60" />
</div>
<figcaption>Fig. 25</figcaption>
</figure>
>>**12.4.1.** + Create New Block
>>>**12.4.1.1.** Select line chart again (Fig.16)
>>>>**12.4.1.2.** Click on ComfortZone
>>>>**12.4.1.3.** Click on Temperature ComfortZone
>>>>>**12.4.1.3.1.** Name Block with Title Temperature ComfortZone
>>>>>**12.4.1.3.2.** Remove Decimal Places
>>>>>**12.4.1.3.3.** Click on Create Block.
>**12.5.** Click on
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/0yfRJsw0/Screen-Shot-2024-06-28-at-18-50-48.png" alt="settings" height="60" />
</div>
<figcaption>Fig. 25</figcaption>
</figure>
>>**12.5.1.** Click on Edit Layout
>>>**12.5.1.1.** Move the two charts to the top of the screen and enlarge them.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/mgcCPbq0/Screen-Shot-2024-06-28-at-19-10-09.png" alt="settings" height="200" />
</div>
<figcaption>Fig. 27</figcaption>
</figure>
### The Code
Now let's start working with the codes. You got this!
**13.** Open Vs Code
**14.** Create a file called keys.py and paste the following code in it substituting with the appropriate keys where it says "substitute":
(Find SSID and Wi-Fi passord on your router; Adafruit's key icon is the one below and is found on the top right corner)
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/2Sp8xr3p/Screen-Shot-2024-06-28-at-19-23-18.png" alt="key" height="60" />
</div>
<figcaption>Fig. 28</figcaption>
</figure>
```python
>import ubinascii # Conversions between binary data and various encodings
import machine # To Generate a unique id from processor
# Wireless network
WIFI_SSID = "substitute_with_your_SSID" # Name of you WI-Fi
WIFI_PASS = "substitute_with_your_Wi-Fi_password" # No this is not our regular password, usually on your router.
# Adafruit IO (AIO) configuration
AIO_SERVER = "io.adafruit.com"
AIO_PORT = 1883
AIO_USER = "substitute_with_username_found_in_key_icon_in_Adafruit"
AIO_KEY = "substitute_with_Active_Key_found_in_key_icon_in_Adafruit"
AIO_CLIENT_ID = ubinascii.hexlify(machine.unique_id()) # Can be anything
AIO_TEMPERATURE_FEED = "substitute_with_MQTT_found_in_Adafruit>Feeds>Temperature_ComfortZone>Feed_Info"
AIO_HUMIDITY_FEED = "substitute_with_MQTT_found_in_Adafruit>Feeds>Temperature_ComfortZone>Feed_Info"
# Discord webhook URL (replace with your Discord webhook URL)
DISCORD_WEBHOOK_URL = "substitute_with_key_found_in_your_Discord>General>settings_icon>Integrations>Webhooks>ComfortZone_Webhook>Copy_Webhook_Url"
```
**15.** Create a new file and name it main.py. Paste the following code in it:
```python
# main.py -- put your code here!
import keys # Contain all keys used here
import wifiConnection # Contains functions to connect/disconnect from WiFi
import time # Allows use of time.sleep() for delays
from mqtt import MQTTClient # For use of MQTT protocol to talk to Adafruit IO
import machine # Interfaces with hardware components
import micropython # Needed to run any MicroPython code
import random # Random number generator
from machine import Pin # Define pin
import dht
# DHT11 sensor pin
tempSensor = dht.DHT11(machine.Pin(0)) # DHT11 Constructor
# MCP9700 analog temperature sensor pin
adc = machine.ADC(27)
# Temperature and humidity thresholds
high_temp_threshold = 24
low_temp_threshold = 19
high_humidity_threshold = 55
low_humidity_threshold = 3
# Function to get temperature and humidity readings from DHT11 sensor
def get_dht11_data():
tempSensor.measure()
return tempSensor.temperature(), tempSensor.humidity()
# Function to get temperature reading from MCP9700 sensor
def get_mcp9700_temperature():
mv = adc.read_u16()
adc_12b = mv * (4095 / 65535)
volt = adc_12b * (3.3 / 4095)
temp_shift = volt - 0.5
temp_slope = 50 - 0
temp = temp_shift / (abs(0.5 - 0) / abs(50 - 0))
return temp
# BEGIN SETTINGS
# These need to be changed to suit your environment
RANDOMS_INTERVAL = 20000 # milliseconds
last_random_sent_ticks = 0 # milliseconds
led = Pin("LED", Pin.OUT) # led pin initialization for Raspberry Pi Pico W
# Callback Function to respond to messages from Adafruit IO
def sub_cb(topic, msg): # sub_cb means "callback subroutine"
print((topic, msg)) # Outputs the message that was received. Debugging use.
if msg == b"ON": # If message says "ON" ...
led.on() # ... then LED on
elif msg == b"OFF": # If message says "OFF" ...
led.off() # ... then LED off
else: # If any other message is received ...
print("Unknown message") # ... do nothing but output that it happened.
# Function to publish average temperature and humidity to Adafruit IO MQTT server at fixed interval
def send_avg_temp():
try:
dht_temp, dht_humidity = get_dht11_data()
mcp_temp = get_mcp9700_temperature()
# Calculate average temperature
avg_temp = (dht_temp + mcp_temp) / 2
print("temperature")
print(avg_temp)
print("humidity")
print(dht_humidity)
except Exception as e:
print("FAILED")
try:
client.publish(topic=keys.AIO_TEMPERATURE_FEED, msg=str(avg_temp))
print("DONE")
except Exception as e:
print("FAILED")
try:
client.publish(topic=keys.AIO_HUMIDITY_FEED, msg=str(dht_humidity))
print("DONE")
except Exception as e:
print("FAILED")
# Try WiFi Connection
try:
ip = wifiConnection.connect()
except KeyboardInterrupt:
print("Keyboard interrupt")
# Use the MQTT protocol to connect to Adafruit IO
client = MQTTClient(keys.AIO_CLIENT_ID, keys.AIO_SERVER, keys.AIO_PORT, keys.AIO_USER, keys.AIO_KEY)
# Subscribed messages will be delivered to this callback
client.set_callback(sub_cb)
client.connect()
client.subscribe(keys.AIO_TEMPERATURE_FEED)
print("Connected to %s, subscribed to %s topic" % (keys.AIO_SERVER, keys.AIO_TEMPERATURE_FEED))
try: # Code between try: and finally: may cause an error
# so ensure the client disconnects the server if
# that happens.
while True: # Repeat this loop forever
client.check_msg()# Action a message if one is received. Non-blocking.
send_avg_temp() # Sends the average temperature (and humidity defined at send-avg-temp) to Adafruit IO if it's time.
time.sleep(60)
finally: # If an exception is thrown ...
client.disconnect() # ... disconnect the client and clean up.
client = None
wifiConnection.disconnect()
print("Disconnected from Adafruit IO.")
```
That was quite alright, wasn't it?! 🙌
### Transmitting the data / connectivity
In this project, the raw sensor readings from the DHT11 and MCP9700 sensors aren't directly transmitted to the cloud. Instead, they're packaged into a payload, which is a structured format that makes the data easier for the receiving platform (Adafruit in this case) to understand and process.
**Wi-Fi** was opted to transmit this packaged data to the cloud. Wi-Fi offers a reliable and relatively high-bandwidth connection, making it suitable for transmitting the temperature and humidity readings.
#### Breakdown of the data transmission process
**16.** The Raspberry Pi Pico collects temperature and humidity readings from both the DHT11 and MCP9700 sensors **every minute**.
**17.** The code processes the sensor readings and creates a payload for transmission. This payload is formatted as a JSON object.
**18.** The temperature value included in the payload is the average of the readings from both sensors. This is achieved by calculating (DHT11_temp + MCP9700_temp) / 2 and storing the result in a variable included in the payload. The rest of the payload structure contains the averaged temperature, humidity reading from the DHT11 sensor, and a timestamp.
**19.** The code utilizes **MQTT** (Message Queuing Telemetry Transport) to publish the data payload to a specific topic (feed) on the Adafruit cloud server. MQTT is a good choice for its lightweight nature.
**20.** The Adafruit cloud platform receives the published data and stores it securely, including the averaged temperature and humidity readings. This allows for **data visualization**, **historical analysis** (these viewed in Adafruit's **Dashboard**), or triggering actions based on the combined temperature data and the humidity readings (through Adafruit's Actions).
**21.** When the averaged temperature or humidity readings reach predefined thresholds within the Adafruit platform, webhooks are used to send notification messages to the **Discord server** (through Adafruit's Actions). Discord acts as the "end-point" where one receives **real-time alerts** based on the processed sensor data. For this to happen, <span style="color:orange;">follow the next steps:</span>
>**21.1.** Sign in/Sign up on Discord
>https://hammerandchisel.zendesk.com/auth/v2/login/signin?return_to=https%3A%2F%2Fsupport.discord.com%2Fhc%2Fen-us&theme=hc&locale=en-us&brand_id=96508&auth_origin=96508%2Ctrue%2Ctrue
>
>**21.2.** Go to https://discord.com/channels/@me
>**21.3.** On the left bar, click on +
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/gjskDBSC/Screen-Shot-2024-06-28-at-20-02-25.png" alt="discord_plus" height="60" />
</div>
<figcaption>Fig. 29</figcaption>
</figure>
>>**21.3.1.** Click on Create My Own > For me and my friends > Name it "ComfortZone" > Click Create
>>
>**21.4.** Click on the gear icon by general (left-to-middle bar)
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/HnVPZrBT/Screen-Shot-2024-06-28-at-20-13-16.png" alt="discord_general_settings" height="60" />
</div>
<figcaption>Fig. 30</figcaption>
</figure>
>>**21.4.1.** Click Integrations (left bar) > Create Webhook (purple) > New Webhook
>>>**21.4.1.1.** Name it ComfortZone alerts > Click Save Changes
>>>
>>**21.5** Click on Copy Webhook URL
>>**21.6.** Go back into Adafruit (if you had signed out, sign back in to the control panel at https://accounts.adafruit.com/users/sign_in
and click on IO on the top (leftish) of the page)
>>**21.7.** Click on Actions (black bar on topish of the page)> + New Action
>>>**21.7.1.** On the popup window, select "No, use the form"
>>>**21.7.2.** Choose action type - **Reactive**
>>>**21.7.3.** Input:
>>>>>If: Humidity ComfortZone
>>>>>Is: greater than | Comparison Value or Feed : 55
>>>>>Then: send a webhook message to:
>>>>>To URL: paste here <span style="color:blue;">Discord Webhook URL</span> (from step 6.5)
>>>>>With Template: Discord Template
>>>>>**21.7.3.1.** Paste the following code in the box:
```
{
"username": "{{feed_name}}",
"content": "It's too humid! {{value}}%"
}
```
>>>>>**21.7.3.1.** Click on Submit
>>**21.8.** Create 3 new actions follwing steps 21.7. to 21.7.3.1. using the details below in Figs. 31, 32, and 33:
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/2jGcpRtP/humidity-dry.png" alt="humidity_dry_adafruit" height="350" />
</div>
<figcaption>Fig. 31</figcaption>
</figure>
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/xC0vgq9q/temp-hot.png" alt="temp_hot_adafruit" height="350" />
</div>
<figcaption>Fig. 32</figcaption>
</figure>
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/hjrrqT29/temp-cold.png" alt="temp_cold_adafruit" height="350" />
</div>
<figcaption>Fig. 33</figcaption>
</figure>
Remember to submit after each new action. You have completed the connection to send alerts to Discord, congratulations! ⭐ 👏 ⭐
#### Design Choices and Considerations:
While Wi-Fi provides good range within a Wi-Fi network, it can impact battery life compared to low-power protocols like LoRa. However, since this project operates within a local Wi-Fi environment and power consumption is less critical, Wi-Fi offers sufficient range and bandwidth for its needs.
MQTT is an excellent choice for this project due to its lightweight nature and efficient data transmission. It minimizes the impact on battery life compared to constantly sending data over a direct connection. It was however where an issue occurred. There was a repeating error in VS Code related to it. This was due to an incompatibility with the Wi-Fi - if the Wi-Fi frequency is set to 5 GHz when ones hardware or driver can only handle 2.4 GHZ, it will not work. If this occurrs, to fix it, one has to find one's router number (System Preferences > Network > TCP/IP > Router:) and type it into the address bar of the browser (if it says the page is unsafe, dismiss it and continue until reaching the page of the internet provider > login). To login, one will probably use username "admin"; for password use the same as the Wi-Fi password (otherwise try a mixture of adding nothing to these fields or info from Wi-Fi's SSID and password). Then check if the Settings > Wi-Fi 2.4 GHz > Main Access Point SSID is the one used in keys.py (file in VS Code - in the section The Code: 2).
This approach balances reliable data transmission with efficient power consumption, making it suitable for a project like this. If long-range communication or extreme battery optimization were priorities, alternative protocols like LoRa could be explored.
### Presenting the data
The data collected - the averaged temperature and humidity readings - are visualized on a user-friendly dashboard within the Adafruit platform. This allows easy monitoring sensor trends.
#### Dashboard Design
In this project two line charts in Adafruit are used for visualizing both the averaged temperature and humidity data over time. These charts display the sensor readings on the Y-axis (vertical) and time on the X-axis (horizontal).
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/Tw4KmPwz/Dashboard-Comfort-Zone.png"/>
</div>
<figcaption>Fig. 34</figcaption>
</figure>
Adafruit allows the display of real-time data updates (in this project **every minute**) as new readings are received **as well as historical data for a specific timeframe.** The platform's free tier stores data for 30 days allowing an analysis of the climate variations within that timeframe.
Adafruit utilizes its own internal **database** infrastructure to store sensor data from connected devices, making it a smooth choice.
The Adafruit platform is configured to **trigger** automated notifications based on sensor readings. Alerts are sent to the Discord server if the averaged temperature and/or humidity exceeds a predefined threshold.
#### Benefits
Adafruit provides valuable insights with its line charts that give a clear view of temperature and humidity trends, allowing the monitoring of environmental changes and/or identification of potential issues. Automated notifications based on sensor thresholds further enhance the project's functionality by keeping users informed of critical events.
### Finalizing the design
This project aimed to create a remote temperature and humidity monitoring system using a Raspberry Pi Pico, two sensors (DHT11 and MCP9700), and the Adafruit platform. Here's a look at the final setup:
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/c1D5PGgr/final-hardware-Comfort-Zone.png"/>
</div>
<figcaption>Fig. 35</figcaption>
</figure>
**Elaboration on the design choices regarding data transmission and wireless protocols:** By leveraging Wi-Fi connectivity, the Raspberry Pi Pico transmits sensor data (averaged temperature and humidity) to Adafruit IO using MQTT. Adafruit's platform then stores the data securely and allows for visualization through user-friendly dashboards:
When predefined temperature or humidity thresholds are reached, Adafruit can trigger automated notifications sent to a Discord server:
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/T25V086V/Discord-alerts.png" />
</div>
<figcaption>Fig. 36</figcaption>
</figure>
**Project Extension**
After completing the above project, I explored connecting it to a self-hosted server to enhance its capabilities. This was considering that pursuing alternative methods to add complexity to the project would have necessitated additional financial resources, which were unavailable at the time. Three different approaches, outlined in the document linked here (https://lucid.app/lucidspark/e6a5a79a-c920-4fb6-a5e8-d0f14392324d/edit?invitationId=inv_f9c74ae3-a6cd-4de4-94dd-6fb02a0782d3&page=0_0#), were investigated. Unfortunately, each path encountered technical hurdles that couldn't be overcome with my existing knowledge, online resources, and the limitations of the Mac OS 10.15 environment. The decision was then taken to extend the project by learning Fusion, building a case for the apparatus and 3D printing it with materials that I already had available. (If you are interested in learning Fusion, like me, you may easily learn it by following this great tutorial: https://www.youtube.com/watch?v=d3qGQ2utl2A).
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/sXn1c9Y2/outside-case-iot.png/">
</div>
<figcaption>Fig. 37</figcaption>
</figure>
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/SRJRt2df/inside-case-iot.png/">
</div>
<figcaption>Fig. 38</figcaption>
</figure>
So that the apparatus would fit in a case, without closing the DHT11 sensor in allowing for a better read of the humidity, cables with male/female connectors were used as enxtensions. MCP9700 Sensor remained inside, as the temperature difference because of its placement is insignificant.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/d1QLrSTX/new-iot-longer-cable.jpg/">
</div>
<figcaption>Fig. 39</figcaption>
</figure>
**Finished Product**
The finished product was printed in bronze PLA giving it a sleek and modern look.
<figure style="text-align: center;">
<div>
<img src="https://i.postimg.cc/6qXwC8SQ/case-iot.jpg/">
</div>
<figcaption>Fig. 40</figcaption>
</figure>
**Overall Thoughts**
This project successfully demonstrates how to collect sensor data, transmit it wirelessly, and visualize it remotely using readily available tools and platforms.
Choosing Adafruit as the platform proved to be a great decision, especially for beginners, due to its user-friendly resources and beginner-oriented hardware options. Wi-Fi connectivity offered reliable data transmission within a local network, and MQTT facilitated efficient data communication.
Room for Improvement: While Wi-Fi worked well, exploring lower-power protocols like LoRa could be beneficial for battery-powered applications or longer-range communication. Additionally, incorporating data logging capabilities on the Raspberry Pi Pico itself could provide a backup in case of internet connectivity issues.
Looking Forward: This project serves as a solid foundation for further exploration. Integrating additional sensors or actuators could expand the monitoring and control capabilities. Experimenting with different data analysis techniques could provide deeper insights into the collected sensor data.
Working through this project in a hands-on fashion understanding each step is a great way to learn how to use the tools and what their functions can achieve. The aid of TAs during the workshops that gave birth to these instructions was priceless and hopefully this tutorial reflects their careful consideration and succeeds in passing forward knowledge to anyone willing to learn by doing 😇
Overall, this project highlights the potential of utilizing readily available tools and platforms to create a remote monitoring system, opening doors for future projects with even greater functionality.