Ever since I came across Raspberry Pi I wanted to try sensors. The easiest I could have think of was to attach a temperature sensor to it and take measurements frequently. I decided that it I want to see the temperature on my mobile or on my computer. I wasn’t quite sure about the architecture at this stage, but I knew that I might want to measure temperature in multiple places and the solution must be able to handle that without a significant change.
Hardware
I had a Raspberry Pi Zero WH (Pi Zero) and a Raspberry Pi 4 Model B (Pi), so I just needed to buy a sensor. I have started looking at sensors, but soon ended up comparing sensor kits. Then I discovered that there are multiple sensors to measure temperature, like DS18B20 (which has a waterproof version too), DHT11, BMP180, BME280, DHT22 and some others. I have found a great comparison and finally decided to buy a DollaTek DHT22 sensor for £5.99 because this one didn’t require an additional resistor. In addition to the temperature this sensor can also measure humidity without any extra effort.
All I had to do is to plug it into the Pi Zero using this schematic diagram.
In real life the cables had different colours simply because I used what I received (white, grey and purple cables). I used no resistor as I assume it is in-built into this version (I could be wrong though, but it works).
Cable | Schema | I used |
Positive (+) | Red | White |
Data | Blue | Grey |
Negative (-) | Black | Purple |
The first measurement
Once I plugged in everything I followed this article to start with downloading python 3 and pip.
sudo apt-get install python3-dev python3-pip
I also needed to get the latest and greatest of setuptools, wheel and pip python packages.
sudo python3 -m pip install --upgrade pip setuptools wheel
Then I was ready to install the Adafruit DHT library which I use to get the readings from the sensor.
sudo pip3 install Adafruit_DHT
Then with a bit of python code I was able to take a reading and print it on the console.
import Adafruit_DHT
DHT_SENSOR = Adafruit_DHT.DHT22
DHT_PIN = 2
while True:
humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
if humidity is not None and temperature is not None:
print("Temp={0:0.1f}*C Humidity={1:0.1f}%".format(temperature, humidity))
else:
print("Failed to retrieve data from humidity sensor")
To execute you just need to save it in a file, like tempandhum.py
and then execute it with the following:
python3 tempandhum.py
Architecture
Once I knew my sensor works I decided that I am going to build an API which can receive the measurements and save them into a MySQL database. This comes with a number of benefits
- I can add multiple Pi Zeros, so I can take measurements in more than one places without doing any changes to the code
- Once I add a bit of security I can host it publicly, so I can send measurements from to the same API from multiple physical sites
- I can scale the resources better if I need to
For now I will host it on the Pi, which means even if the Pi Zero is down I can access the measurements. To access the measurements I decided to build a web app. It will use the API to fetch the latest measurement to display.
An API to store and retreive measurements
To cover the basics I needed two endpoints to start with. One which can receive measurements from the Pi Zero and store them in the database, that is the POST. The Pi Zero will send its name, the date and time the measurment was taken and the actual measurements as numbers: temperature in Celsius and humidity as percentage.
The other endpoint I needed is a GET. This gets the device name as a parameter and will return the latest measurement sent by that device.
I added a third endpoint as well, so I can test easily the service while in development. This GET endpoint simply returns all measurements for all devices. Later on I am planning to use this endpoint (well a slightly modified version of it) to draw a chart of the measurements, but that is just a future development idea for now. I ended up keeping this endpoint, but not really using it for now.
A web app to display measurements
The last bit was the web application which simply uses the GET endpoint to display the latest temperature and humidity for just one device for now. Given I am using a template engine (Handlebars.js) it is very easy to add more if you have more devices. To do that today you need to modify the code, but I am planning to give that as an option to the user either via the UI or via some sort of configuration. For now I am happy that by simply browsing to http://raspberrypi:9000 on any of my devices while I am connected to my home network I can see the latest temperature and humidity.
Running them all in the background
I use pm2 to run all of them in as a background process. For node it is simple and this article details it well. I also found a good article describing in detail how to do it not only for the node apps, but for the python script too. The python one was also suprisingly easy by just running
pm2 start rpi-send-dht22.py --name rpi-send-dht22 --interpreter python3
I want to try this!
Great! You need to buy the hardware first, however you can just use one Raspberry Pi (any of them would do, even an older model) and connect the sensor to that plus install all components on it. I published all three components as a project on GitHub, so you don’t need to start from scratch. You can find the
- rpi-send-DHT22: python script which takes the reading
- rpi-measurements-api: the Node.js API which stores them and serves them to the web app
- rpi-measurements-web-dashboard: the Node.js web app which displays the latest measurement for a device
Happy measuring and I hope you’ll enjoy it as much as I did!