# Tutorial on how to Build a Temperature and Humidity Sensor
### Author:
Hao Chen, hc222ig
## Overview
This project involves building an IoT device using a Raspberry Pi Pico to measure and report temperature and humidity data. The data is collected using a DHT11 sensor and sent to the Datacake platform for visualization. The device is programmed in MicroPython and connected to the internet via Wi-Fi.
Time to complete: Approximately 5-6 hours
## Objective
I chose this project to gain hands-on experience with IoT development, specifically focusing on environmental monitoring. The project provides practical insights into sensor integration, data transmission, and cloud-based data visualization.
The device serves as a simple environmental monitoring system that can be used in various applications, such as home automation, greenhouse monitoring, or office environment tracking.
This project will provide insights into real-time data collection and analysis, the process of connecting devices to the cloud, and how to visualize data for better understanding and decision-making.
## Material
The following list of used material was purchased within the Start Kit - Applied IoT at Linnaeus University (2024) from electro:kit for 399kr.
| Item | Image |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Raspberry Pi Pico WH | <img src="https://www.electrokit.com/cache/ba/999x999-product_41019_41019114_PICO-WH-HERO.jpg" width="100"> |
| DHT11 Temperature and Humidity sensor | <img src="https://www.electrokit.com/upload/product/41015/41015728/41015728.jpg" width="100"> |
| Breadboard with 840 connections | <img src="https://www.electrokit.com/upload/product/10160/10160840/10160840.jpg" width="100"> |
| USB cable A male - micro B 5p male 1.8m | <img src="https://www.electrokit.com/upload/quick/36/bf/5f05_41022181.jpg" width="100"> |
| Jumper wires (male/male and female/male) | <img src="https://www.electrokit.com/cache/24/700x700-product_41012_41012684_41012684.jpg" width="100"> |
## Computer Setup/Chosen IDE
Visual Studio Code with the Pymakr plugin.
Steps for Setup:
1. **Install VS Code:** Download and install from the [VS Code website](https://code.visualstudio.com/).
2. **Install Pymakr Plugin:** Go to Extensions in VS Code, search for Pymakr, and install it.
3. **Install Additional Software:** Install Node.js from [Node.js website](https://nodejs.org/en).
4. **Update the RPi Pico Firmware:** Download the MicroPython firmware from [here](https://micropython.org/download/RPI_PICO_W/). Download the latest **.uf2** file from the Releases category.
5. **Connect the RPi Pico:**
* Connect the micro-USB end of your cable into the Raspberry Pi Pico.
* Hold the BOOTSEL button down on the board.
* Connect the USB type A end of your cable into your computer's USB port.
* Release the BOOTSEL button after connecting it to your computer.
6. **Copy Firmware:**
* A new drive named RPI-RP2 will appear in your file system.
* Copy the downloaded .uf2 file to this drive.
* Wait until the board automatically disconnects from your computer.
7. **Reconnect the Board:** Unplug and plug back the USB cable to confirm the board is ready.
## Putting Everything Together
**Electrical Connections**
Follow the wiring diagram below to connect the DHT11 sensor to the Raspberry Pi Pico:

**DHT11 Sensor**
* VCC to Pico 3.3V (red wire)
* GND to Pico GND (black wire)
* Data to Pico GPIO27 (yellow/blue wire, with a pull-up resistor if necessary)
Ensure all connections are secure and double-check the pin mappings to avoid any damage to the components.
**Electrical Calculations**
Ensure that the power supply (5V via USB) is sufficient for all connected components. Calculate the total current draw to avoid overloading the Pico's power supply.
## Platform
**Chosen Platform**
Datacake: A cloud-based platform for IoT data visualization.
**Functionality:** Datacake offers easy setup for IoT devices, real-time data visualization, and configurable dashboards.
**Why Chosen:** It provides a free tier for the first five created devices suitable for small projects, easy integration, and robust features for data analysis.
## The Code
**Project Structure**
The project is organized with the following files and folders:

Root:
* boot.py
* main.py
* pymakr.conf
* .gitignore
lib/ folder
* datacake_keys.py
* dht.py
* keys.py
* wifiConnection.py
**lib/datacake_keys.py**
This file contains the Datacake API URL and token:
```
# datacake_keys.py
API_URL = 'https://api.datacake.co/v1/devices/YOUR_DEVICE_ID/data'
API_KEY = 'YOUR_API_KEY'
```
**lib/dht.py**
This file contains the DHT11/DHT22 driver code:
```
# DHT11/DHT22 driver for MicroPython on ESP8266
# MIT license; Copyright (c) 2016 Damien P. George
import sys
import machine
if hasattr(machine, "dht_readinto"):
from machine import dht_readinto
elif sys.platform.startswith("esp"):
from esp import dht_readinto
elif sys.platform == "pyboard":
from pyb import dht_readinto
else:
dht_readinto = __import__(sys.platform).dht_readinto
del machine
class DHTBase:
def __init__(self, pin):
self.pin = pin
self.buf = bytearray(5)
def measure(self):
buf = self.buf
dht_readinto(self.pin, buf)
if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xFF != buf[4]:
raise Exception("checksum error")
class DHT11(DHTBase):
def humidity(self):
return self.buf[0]
def temperature(self):
return self.buf[2]
class DHT22(DHTBase):
def humidity(self):
return (self.buf[0] << 8 | self.buf[1]) * 0.1
def temperature(self):
t = ((self.buf[2] & 0x7F) << 8 | self.buf[3]) * 0.1
if self.buf[2] & 0x80:
t = -t
return t
```
**lib/keys.py**
This file contains the Wi-Fi credentials:
```
# keys.py
WIFI_SSID = 'your_wifi_ssid'
WIFI_PASS = 'your_wifi_password'
```
**lib/wifiConnection.py**
This file contains the Wi-Fi connection code:
```
# wifiConnection.py
import keys
import network
from time import sleep
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(keys.WIFI_SSID, keys.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
def disconnect():
wlan = network.WLAN(network.STA_IF) # Put modem on Station mode
wlan.disconnect()
wlan = None
```
**boot.py**
This file initializes the Wi-Fi connection and performs an HTTP GET request to test the connection:
```
# boot.py
import lib.wifiConnection as wifiConnection
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) # Receive response
print(rec_bytes) # Print the response
s.close() # Close connection
# WiFi Connection
try:
ip = wifiConnection.connect()
except KeyboardInterrupt:
print("Keyboard interrupt")
# HTTP request
try:
http_get()
except (Exception, KeyboardInterrupt) as err:
print("No Internet", err)
# WiFi Disconnect
# wifiConnection.disconnect()
```
**main.py**
This is the main file that ties everything together:
```
import sys
sys.path.append('lib')
import lib.dht as dht
import machine
import time
import urequests
import lib.wifiConnection as wifiConnection
import lib.datacake_keys as datacake_keys
# DHT11 Sensor
tempSensor = dht.DHT11(machine.Pin(27)) # DHT11 Constructor
# WiFi Connection
ip = wifiConnection.connect()
print("Device IP:", ip)
# Check Internet Connection
try:
response = urequests.get("http://www.google.com")
print("Internet connection verified")
response.close()
except Exception as e:
print("No internet connection:", e)
while True:
try:
tempSensor.measure()
temperature = tempSensor.temperature()
humidity = tempSensor.humidity()
print("Temperature is {} degrees Celsius and Humidity is {}%".format(temperature, humidity))
# Send data to Datacake
headers = {
'Authorization': 'Token {}'.format(datacake_keys.DATACAKE_TOKEN),
'Content-Type': 'application/json'
}
payload = {
'device': '644972db-76c1-402d-a784-83a6c456cd84', # Device Serial Number
'temperature': temperature,
'humidity': humidity
}
try:
response = urequests.post(datacake_keys.DATACAKE_API_URL, headers=headers, json=payload)
response.close()
except Exception as e:
print("Error while sending data:", e)
except Exception as error:
print("Exception occurred:", error)
time.sleep(600) # Send updates every 10 minutes
```
**Explanation**
WiFi Connection: Connects the device to a Wi-Fi network using credentials stored in lib/wifiConnection.py.
**Data Reading:** Reads temperature and humidity from the DHT11 sensor every 10 minutes.
**Data Transmission:** Sends the data to Datacake using an HTTP POST request.
## Transmitting the Data:
Interval: Data is sent every 10 minutes.
Wireless Protocol: Wi-Fi is used to connect to the internet.
Transport Protocol: HTTP is used to send data to Datacake's API.
Design Choices:
Wi-Fi: Chosen for its simplicity and availability in most environments.
HTTP: Easy to implement and supported by Datacake.
## Presenting the Data
**Datacake Dashboard:** The dashboard is built to display real-time temperature and humidity data using configurable widgets such as charts and values. The data is displayed in an easy-to-understand format, allowing for quick insights into environmental conditions.
**Data Preservation:** The data is stored in Datacake's cloud database and is preserved for a minimum duration as per Datacake's free tier policy. This typically includes historical data retention for a certain period, enabling users to analyze trends over time.
**Visual Examples:**
Here are some examples of how the Datacake dashboard might look:


**Data Saving Frequency:** Data is sent to the Datacake database every 10 minutes, ensuring that the dashboard is updated with near real-time information.
**Database Choice**
Datacake's cloud storage was chosen for its ease of integration, real-time data visualization capabilities, and support for multiple IoT devices. The platform also offers a free tier, making it suitable for small-scale projects and prototypes.
**Automation and Triggers**
Datacake allows setting up alerts and triggers based on specific data conditions. For example, users can configure alerts to notify them when temperature or humidity exceeds a certain threshold. This is useful for applications such as monitoring server rooms, greenhouses, or residential environments.
**Triggers:** Custom triggers can be set to perform actions such as sending notifications, triggering other IoT devices, or logging events based on the data received.
## Finalizing the Design
**Final Results:**
The device successfully reads and transmits temperature and humidity data to Datacake. Visuals data is displayed on a desired custom dashboard, allowing for easy monitoring and analysis of the environmental conditions.
The final product was used indoors close to a window in a bedroom:

**Final Thoughts**
Improvements:
* Additional Sensors: Incorporating more sensors, for air quality detection, or motion sensors, could provide a more comprehensive environmental monitoring system.
* Power Management: Implementing power-saving features and exploring alternative power sources (e.g., battery) to make the device more versatile and portable.
Successes:
* Hardware Integration: The project achieved seamless integration of the DHT11 sensor with the Raspberry Pi Pico, ensuring accurate data collection.
* Cloud Platform: Utilizing Datacake for data visualization proved to be effective and user-friendly. The platform's real-time data updates and customizable dashboards enhanced the overall user experience.
* Learning Experience: The project provided valuable hands-on experience, for first time building in IoT development that included sensor integration, data transmission, and cloud-based data visualization.