# The Indoor temperature & humidity monitor This project is about building a temperature and humidity device using a microcontroller to measure indoor temperature and humidity. Name: Rami Fareed Omar Student number: rf222km The entire project is pretty straight forward and it might take around 6 hours to complete from A to Z. ## Objective I chose to build a mini indoor weather station because I was planning to buy one to monitor indoor temp & humidity, so I thought this is a great opportunity to create my own mini weather station. The mini weather station will give me insights about how the temperature and humidity indoor are over time, to see how I can optimize using the heater/aircon to get best indoor air. ## Material I have purchased the following items from amazon to make building my mini weather station possible | Item | Description | Purchased from | Price |picture| | ----------- | ----------- | ------------ | ---------- |------- |Micro controller | Freenove ESP32 WROVER| Amazon | 150 kr |![ESP32](https://i.imgur.com/SKBPOM5.png "title" =200x250) | |Extension board | Freenove ESP32 GPIO| Amazon | 100 kr |![Extension board](https://i.imgur.com/SfRyNC6.png =200x250)| |DHT11 | Elegoo dht11 sensor | Amazon | 70 kr |![DHT11](https://i.imgur.com/zChhpY3.jpg =150x150)| |Wires |3x socket to socket jumper wire |Amazon | 20 kr |![Jumper](https://i.imgur.com/krGiTNA.png =150x150)| |Power Cable | 9v battery power cable| Amazon | 10 kr |![power cable](https://i.imgur.com/2hQBr50.png =150x150)| |USB Cable | Type A Male to Type B Micro| Amazon | 30 kr |![usb](https://i.imgur.com/tYYJ0VB.png =150x150)| |9V Battery |Varta 9V2 580mAh | Amazon | 20 kr |![9v battery](https://i.imgur.com/3oGduxL.png =150x150)| I chose the ESP32 from freenove since it's a neat device that offers WIFI and Bluetooth connectivity, which covers my need and is programmed by Micropython. ## Computer Setup I use **Thonny** as an IDE due to it being a more simple and orginazed IDE than others like *Atom* which I started with but realized that I can do more using **Thonny**. I upload my initial `main.py` and `boot.py` using the upload function in **Thonny** and after that I only did modify the files on my Micro controller directly without the need to unload and upload the files ever again and that's one of the great features **Thonny** offers. I did install Node.js on my machine and also the driver that was supplied by the manufacturer of my esp32 in order to get it connected to my IDE. For flashing my device and uploading the newest [Firmware](https://micropython.org/download/esp32/), I used [ESP Web Flascher](https://nabucasa.github.io/esp-web-flasher). So in order to start coding on your ESP32 device, follow the steps below: 1. Install the driver that is provided with the ESP32 kit, to get your device read by your computer. 2. Install your IDE, as mentioned above I used **Thonny**, use this [link](https://https://thonny.org/) to download the IDE 3. Now you need to flash your ESP32 device and install the latest software. for that use the links below: * Go to the micropython website and download the latest firmware (file type .bin) using this [link](https://micropython.org/download/esp32/) * Now open the [Webflasher](https://nabucasa.github.io/esp-web-flasher) which allows you to flash your device and install the newest firmware.(Make sure to use Chrome webbrowser to avoid running into connectivity issues) 4. Download and install `node.js` from this [link](https://nodejs.org/en/download/), Make sure to always use the current version not LTS. 5. Now connect your ESP32 device to your computer and go into Thonny do the following: * Click on Run in the menu bar at the top of the screen * Select "select interpreter" * Select the device that Thonny shoud use to run your code, that would be "Micropython (ESP32)" * At the bottom of the window, you will see Port or WebREPL, select the port your device is showing in Now you are good to go! ## Putting everything together Below you can see that circuit board with all the connections necessary to get the sensors working. I connected the DHT11 to pin number 21. ![Circuit Diagram](https://i.imgur.com/MxvlW3P.png) Power consumption of the devices is around 4.4 mAh in active mode and 0.21 mAh in deep sleep mode. So after calculating to run the device for around 10 seconds every hour to get the readings sent to my platform that will consume around 5.33 mAh a day and with a battery capacity of 580 mAh from the battery I purchased I will the device running for 3.6 months on the same battery. To account for error margin, I would say that the device can comfortably run for 3 months on this battery. In the [**link**](https://docs.google.com/spreadsheets/d/1drsw-cGTUWbKN4zhJAiCEoVDgoio4MHSU_G_Wzz49uQ/edit#gid=0) you will find some calculations and how I got this result. ## Platform I have chosen to work with **Adafruit** since its fairly easy to implement and also push the data to. It offers great visuals and easy start. On top on that it's free of charge for my project and I love it. There are more complicated solutions out there that like _**Amazon Iot**_ but i felt it's enough and functional to go with adafruit. ## The Code The code below is structured in steps to make it possible to follow and understand easily: * Before we begin with the code, since we are using `MQTT` protocol to send the data to the platform, we need the following [MQTT](https://github.com/iot-lnu/applied-iot/blob/master/network-examples/mqtt_ubidots/mqtt.py) liberary to be added as shown in the file structure below: ![file tree](https://i.imgur.com/hkOpove.png) * We start with `boot.py` file in order to connect the device to the internet whenever the device boots: ``` # Import Lib import uos as os import uerrno as errno import network iter = os.ilistdir() IS_DIR = 0x4000 IS_REGULAR = 0x8000 # -- Wifi code starts -- def do_connect(): import network sta_if = network.WLAN(network.STA_IF) # Put modem on Station mode if not sta_if.isconnected(): # Check if already connected print('connecting to network...') sta_if.active(True) # Activate network interface sta_if.connect('WIFI Name', 'Wifi Password') # Your WiFi Credential # Check if it is connected otherwise wait while not sta_if.isconnected(): pass # Print the IP assigned by router print('network config:', sta_if.ifconfig()) 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) # Receve response print(rec_bytes) # Print the response s.close() # Close connection # WiFi Connection do_connect() # HTTP request http_get() # -- Wifi code ends -- ``` * Then there's the `main.py` file that contains all the code needed in order to get the readings of temp and humidity and send them then to the platform "Adafruit": ``` # Importing needed liberaries to get all needed functionalities import machine from machine import Pin import network from mqtt import MQTTClient import ubinascii import time from time import sleep import dht import micropython # BEGIN SETTINGS # Adafruit IO (AIO) configuration AIO_SERVER = "io.adafruit.com" AIO_PORT = 1883 AIO_USER = "rami_omar" AIO_KEY = "aio_lLwh01MRONVe1ZKQTNsaGfAt5unO" AIO_CLIENT_ID = ubinascii.hexlify(machine.unique_id()) # Can be anything AIO_TEMPERATURE_FEED = "rami_omar/feeds/temperature" AIO_HUMIDITY_FEED = "rami_omar/feeds/humidity" AIO_TEMPERATURE_FAHRENHEIT_FEED = "rami_omar/feeds/temperature-fahrenheit" # END SETTINGS # FUNCTIONS # Defining function to read sensor data def read_temp(): sensor.measure() temp = sensor.temperature() hum = sensor.humidity() temp_f = temp * (9/5) + 32.0 print("Temperature: %3.1f C" %temp) print("Temperature: %3.1f F" %temp_f) print("Humidity: %3.1f %%" %hum) return temp, hum, temp_f # Defining function to send data to Adafruit def send_data(client,value,topic): print("Publishing: {0} to {1} ... ".format(value, topic), end='') try: client.publish(topic=topic, msg=str(value)) print("DONE") except Exception as e: print("failed") # Defining client and sensor sensor = dht.DHT11(Pin(21)) client = MQTTClient(AIO_CLIENT_ID, AIO_SERVER, AIO_PORT, AIO_USER, AIO_KEY) try: client.connect() except Exception as e: print("Connection failed") # Calling functions temp, hum, temp_f = read_temp() send_data(client, temp, AIO_TEMPERATURE_FEED) send_data(client, temp_f, AIO_TEMPERATURE_FAHRENHEIT_FEED) send_data(client, hum, AIO_HUMIDITY_FEED) time.sleep(3) # Delay sleep by 3 seconds in order to send the data to platform, note that this is in seconds machine.deepsleep(60*60000) # Sleeps for 60 minutes and sends data again when it wakes up, note that this is in Milliseconds ``` After recreating the code and also follow the guide on how to connect to adafruit you will be able to recreate this project. ## Transmitting the data The data is transmitted using WIFI and mqtt protocols to get it sent to adafruit.The data is transmitted every hour to make sure to save energy consumption and have a better understanding of the temprature readings over the day. I chose to use wifi since it's indoors temperature & humidity monitoring and the power consumption will as mentioned [Putting everything together](#Putting-everything-together) not be great and the device will work for a long while uninterruped. ## Presenting the data I used Adafruit to store and present my data and the platform offers 5 feeds with 30 entries per minute limitation for the free account, so in my case the data that i'm sending every hour (meaning one entry every hour) will not create any issues with saving the data on there hence the data storage have no time limitation so I will use this to my advantage and will keep the data in there without storage time limitation. As it supports 5 feeds for free that's enough for my usecase since I will be only having 3 feeds for: * Temperature Celsius * Temperature Fahrenheit * Humidity The reasons above made me go with Adafruit as a platform. The trigger to send data is every hour. To make that possible, I have added `machine.deepsleep()` in my code. So my micro controller wakes up from deep sleep will send the data to Adafruit and will return to sleep. I have also used webhooks to get notified on my Discord when temperature reachs 25 and more degrees Celsius. Below is a snippet of my Dashboard: ![Adafruit dashboard](https://i.imgur.com/M0Yi86I.png) ## Finalizing the design I'm amazed that I was able to learn how to code and use a micro controller in such this short amount of time and I'm proud of the end results. If I have had little more time I would have gone with more advanced level of project, but I feel this course gave me the basics on how to program micro controllers and demonstrated the use cases of the IoT devices and I will definitely in the future build more devices and use different network connection methods like LoRawan. Here's are some pictures of my final device: ![ESP32](https://i.imgur.com/Oj9gRvA.jpg) ![Sensor](https://i.imgur.com/s2smvuc.jpg) As you can see in the pictures above, I have created air circulation vents (the little holes) to make sure that the device doesn't overheat when in operation.