Written by Joel Josefsson (jj224jr)
Table of Contents
The aim of this project is to expand the knowledge of IoT using the Firebase Realtime Database to access the data anywhere in the world.
This project features temperature and humidity measurements using a DHT11 module. The values are then transmitted to the database using WiFi. An android app then subscribes to the changes in the database and visualizes the data.
The estimated time the project took to complete is presented in the table below.
Circuit | Database | MicroPython | Android app | Total | |
---|---|---|---|---|---|
Hours | 3 | 6 | 10 | 10 | 29 |
This project was chosen based on the interest in building something functional to use in the home which can be used with a smartphone anywhere in the world.
When you want to know the outside temperature it is common to go on your smartphone and look at some weather application which shows the temperature over a whole city. However, is that the actual temperature on my balcony? Hence, the purpose of this project is to get an accurate temperature and humidity reading on my balcony during the summer heat which can be viewed on my phone.
The materials used in this project is presented in the table below:
Device | Quantity | Description | Price/Link |
---|---|---|---|
Raspberry Pi Pico W |
1 | Used to collect sensor data and transmit to the database. It features WiFi and the RP2040 chip. It has 26 GPIO pins and operates on 1.8-5.5V DC input power. | 98 SEK Electrokit |
USB-A male - Micro-USB |
1 | Used to connect the Raspberry Pi Pico W to the computer to upload code | 39 SEK Electrokit |
Push Button |
1 | Used as a way to reset the board without pulling the cable. | 9,22 SEK Elfa |
DHT11 Module |
1 | Used to measure the ambient temperature and humidity. It measures temperature using an NTC component and humidity using a resistive component. It operates at 3.3-5.5V DC with the accuracy of ±2°C for temperature and ±5%RH for the humidity. | 49 SEK Electrokit |
Breadboard |
1 | Used to put the components together | 69 SEK Electrokit |
Jumper Wires |
7 | Used to connect the components on the breadboard. | 49 SEK Electrokit |
Android Phone (Optional) | 1 | Used to visualize the data. (An emulator can be used instead) |
To program the Raspberry Pi Pico W we need an IDE. This project uses Thonny based on the simplicity of setting it up and saving the file to the microcontroller. The project is also utilizing Android Studio to make the android app.
Thonny is a very simple IDE for Python and is very easy to setup for Raspberry Pi Pico W. Micropython can be flashed on the microcontroller directly from Thonny.
In Thonny you can either save your python files on the computer or on the board. To save the file on the board simply select save and then a popup window lets you choose the Raspberry Pi Pico
Then choose a name for you file ending in .py and press ok to save on the board.
The file is now saved as hello_world.py on your Raspberry Pi Pico W and can be executed by pressing the play button at the top. The board is then reset and the words "Hello World" is printed in the REPL.
If you want the code to run when the microcontroller gets plugged in without pressing the play button name it main.py
. You can also have a boot.py
file which is the first file to run when plugged in. This is usually for connecting to the network and such.
Android Studio is used to make the app for the android phone.
To install Android Studio, they have very good instruction with a video on how to do the installation steps. It also have instructions for several different operating systems. Furthermore, to create a virtual device Android studio have great tutorial on how to create a android virtual device to debug your code on.
Firebase is googles own cloud database service. Hence, first you will need to have a google account and sign in to it. Next, to create a Realtime Database, Firebase have a good tutorial on how to set up the database. They also have a tutorial on how to set up Firebase for your app in Android Studio on Firebase.
The circuit of the components are illustrated below.
We make one 3.3V line from pin 36 on Raspberry Pi Pico W to the row closest to the blue line and one ground line from pin 38 to the row closest to the red line.
The DHT11 module have the pins signal, power and ground respectively from left to right. Hence, the signal pin is connected to the GPIO pin 16 on our microcontroller, ground is connected to the ground line and the power line is connected to the 3.3V power line which will be sufficient to power the DHT11. Since the module already features a pull up resistor there is no need to add an extra resistor between the signal and power line. The DHT11 also draws 2.5mA at the maximum which is significantly lower than the limit of our microcontroller, so no need for external power.
The button is connected with the left side to ground and right side to GPIO pin 17. The internal circuit of the Raspberry Pi Pico W already have a pull up resistor so no need for that. One not when connecting a button is on which pins to connect. A button is basically two circuits which connects when the button is pressed. One circuit on the two right pins and one circuit on the two left pins. Hence, when connecting the button make sure to connect the ground and signal to two different internal circuits, otherwise it will constantly be short circuited and read the same value regardless of the state of the button. When the button is not pressed no signal is carried to the GPIO pin and the pull up resistor will pull up the signal to 1. When the button is pressed the circuit is short circuited and the resulting signal to the pin is 0.
The platform used for this project is Firebase Realtime Database which is a NoSQL cloud database synced in realtime across all connected devices. The data is stored as JSON. The free account can have 100 connections, 1 GB storage and 360 MB Downloads per day which is more than enough for this project. You can either update a variable to have sort of MQTT functionality but you can also save lots of data in order to make a dataset or to have the data to present in a graph.
The main code for the microcontroller and for the android app is presented here.
The library to connect and push data to the Firebase database is ufirebase downloaded from Github and saved to the microcontroller under the lib folder.
The first step is to make a file where all the secrets are held such as the WiFi information as is structured as such:
and save it as secrets.py on the microcontroller
First off we need to connect to the WiFi in our boot.py file. We import the necessary libraries
The Pin class is used to blink the on board LED to have visual feedback when connecting. The sleep_ms is used when waiting on connecting. The network is used to connect to the WiFi and secrets are our secrets file made before.
Next we define a variable led to refer to the on board LED:
Then to connect to the network:
First off we make a WLAN client which is then checked if already connected. If it is not we make the network interface active and connect using the SSID and password of the router. Next while the board is connected the on board led is blinking every 0.2s to indicate that it is trying to connect.
The ufirebase is the library downloaded to access Firebase Realtime Database. It has the function to connect to the database, get data and put data from Firebase. We import it and give it the name firebase
To define the URL to the firebase to set it up we use firebase.setURL()
as such:
We also need to define the variables refering to the DHT11 and the button. It is done with the Pin class from the machine library. The DHT11 is defined using the DHT11 class from the dht library.
To have our microcontroller take maesurements every hour and post them to the database we use a timer defined in the machine library. The timer is set to periodic with a period of one hour meaning that the timer will restart after it runs out every hour. The callback function of the timer takes the measurements using the d variable and post them in the database under the respective key using firebase.put()
. They are saved as strings as it is easier to work with in android studio later.
Finally we use an IRQ on the button to instantly reset the board when pressed. The variable button
is set to trigger on a falling edge with the function to reset the board as handler. The button is triggered on the falling edge since the pull up resistor in the board always makes the button read as 1
and when we press the button it reads 0
.
The layout of the app is made using jetpack composables. The function Card(){}
is used to present each of the measurements. Inside the function Text()
is used to present the data.
To have the data in our cards update with the database Livedata<T>
is used which is observed in the composable as a state.
In the class MainActivity
three constructors are defined, two for the data from the database using MutableLiveData<T>
and one refering to the database.
In the class, a function readData()
takes the database constructor and defines two references, one for the path to the temperature data and one for the path to the humidity data.
Then two eventlisteners are made, one for temperature and one for humidity. They are exactly the same except they post to the data to tempData
for temperature and humData
for humidity. When new data is posted to the database the eventlistener will be triggered and get the key and the value of the changed data which will be posted to the respective MutableLiveData<T>
variable.
The data from the DHT11 is transmitted to Firebase Realtime Database using WiFi once every hour in order to minimize the power consumption but also since the temperature outside does not often change instantly. The transport protocol used to send data to the database is TCP protocol using sockets.
The data is saved to the database once every hour and stays there until it is removed.
The database looks like this when done:
There are only two keys, Humidity
and Temperature
which is all we need for this project. However, it can be further expanded in the future to include past data which can serve as a database for an machine learning model or to have displayed in the app.