# 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_bb](https://hackmd.io/_uploads/SJcmuqMPR.jpg) **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: ![Skärmavbild 2024-07-01 kl. 14.19.04](https://hackmd.io/_uploads/HJgD_cGDC.jpg) 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: ![Skärmavbild 2024-06-19 kl. 15.55.56](https://hackmd.io/_uploads/HyDPOe5LC.png) ![Skärmavbild 2024-06-26 kl. 22.20.34](https://hackmd.io/_uploads/rJzudgqLA.png) **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: ![IMG_3235](https://hackmd.io/_uploads/Bkrfqlq8A.jpg) **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.