How to build an air quality monitor using Raspberry Pi Zero W
Tags: raspberrypi, diy, iot
Published: 2021-05-13 02:32:15

![](https://storage.googleapis.com/zenn-user-upload/1vldwz10efzfph122q6ziy3vuf22)

Hi, it's [Takuya](https://twitter.com/inkdrop_app).

Knowing the air quality is useful to keep yourself productive because the bad air quality would affect your brain performance more than you'd think.
So, I built a room air quality monitor that displays the temperature, humidity, CO2 density, and barometric pressure of my home office.
It notifies with sound when the CO2 level gets more than 1,000 ppm - So, I can know when to refresh the air.
I'm gonna show you a walkthrough of how to build it.

Let's get started.

{% youtube 0gNnUWtbmeI %}

### Architecture

![](https://storage.googleapis.com/zenn-user-upload/mmsu7g5gkyqemoz0s4ydvt8uf63e)

This is the architecture overview.
It is made with a Raspberry Pi Zero W, which runs Nginx and has an ANAVI Infrared pHAT with some sensors attached.
And you can view it from a browser on any device.

### Unbox a Raspberry Pi Zero W

![](https://storage.googleapis.com/zenn-user-upload/o9d6elj2n3z0qibkmf0ccti3pol3)

* https://amzn.to/3eyF0xJ

### SanDisk 32GB MicroSD Card

![](https://storage.googleapis.com/zenn-user-upload/82y3l7b2eszw3qlm8vblfk0k3s0p)

* https://amzn.to/3hlJfi3

### Anker 2-in-1 USB C Memory Card Reader

![](https://storage.googleapis.com/zenn-user-upload/cse1crawk1g1h8mx0993grgxm76e)

* https://amzn.to/33vdf31

### Download Raspberry Pi Imager

![](https://storage.googleapis.com/zenn-user-upload/k57nvajbis11ejokmxa0p3k3tjng)

* https://www.raspberrypi.org/software/

### Write a Raspberry Pi OS to the SD Card

![](https://storage.googleapis.com/zenn-user-upload/kzolwnggylkz0kr9l3tjbfb27l3t)

### Configure your Wi-Fi network

![](https://storage.googleapis.com/zenn-user-upload/pkmogohtphggcfcwhp759lkw4u51)

To get your Rasberry Pi to connect your Wi-Fi network, create `wpa_supplicant.conf` file in the root directory of the SD card memory.

```sh
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=<Insert 2 letter ISO 3166-1 country code here>

network={
 ssid="<Name of your wireless LAN>"
 psk="<Password for your wireless LAN>"
}
```

* https://www.raspberrypi.org/documentation/configuration/wireless/headless.md

### Enable SSH server

![](https://storage.googleapis.com/zenn-user-upload/fhbdbbfatgyqquyswrydwc137bxz)

You have to enable SSH server to connect through the network.
Create an empty file named "ssh" in the root directory by `touch` command.

### Boot the Raspberry Pi

![](https://storage.googleapis.com/zenn-user-upload/klcv93uo6xu5i43gltmgeb92ydun)

### Check if connected to the Wi-Fi network

![](https://storage.googleapis.com/zenn-user-upload/jozfjfgkilzxdkomqosx6le4ej2p)

```sh
ping raspberrypi.local
```

### Log in to the Raspberry Pi via SSH

![](https://storage.googleapis.com/zenn-user-upload/9q2ndhic6u6luyamxol8u1ixj9bm)

```sh
ssh pi@raspberrypi.local
```

* user: `pi`
* pass: `raspberry`

### Unbox an ANAVI Infrared pHAT

![](https://storage.googleapis.com/zenn-user-upload/l33og8431a8fedltoxwxwft4b8hg)

* https://www.crowdsupply.com/anavi-technology/infrared-phat

ANAVI Infrared pHAT is an add-on for the Raspberry Pi family, which adds an ability to control your old consumer electronic devices like air conditioning with infrared signals.
On top of that, it supports sensor modules.
With the advanced kit, you can get these sensor modules for the air quality:

* HTU21D - temperature & humidity
* BMP180 - temperature & barometric
* BH1750 - light

### Install the ANAVI Infrared pHAT to the Raspberry Pi Zero

![](https://storage.googleapis.com/zenn-user-upload/5zff7y4v6rgysv9dyrb2w8ayvsg7)

### Connect the sensors to the I2C slots

![](https://storage.googleapis.com/zenn-user-upload/ri5phyxwlyvavfmrqevpmqjd51r6)

### MH-Z19 - CO2 density sensor

![](https://storage.googleapis.com/zenn-user-upload/oodqhamjtxttawwt1f0jxzr8t0cb)

* https://amzn.to/3uCcIbo

MH-Z19 is a low-cost CO2 density sensor.

### Connect MH-Z19 to the UART slot

![](https://storage.googleapis.com/zenn-user-upload/pp3qkqlqyc6ucgbozfr8bqos6ecg)

### Check if MH-Z19 is working

![](https://storage.googleapis.com/zenn-user-upload/pyk39a83qerhud22t1al7d5rsknh)

### Update Raspberry Pi packages

![](https://storage.googleapis.com/zenn-user-upload/nn4c6xtcsrkdfa66vd7l915olqve)

```sh
sudo apt update
sudo apt upgrade -y
```

### Install git & build tools

```sh
sudo apt install git build-essential
```

### Install python-smbus and i2c-tools

```sh
sudo apt install python-smbus i2c-tools
```

### Enable I2C interface

![](https://storage.googleapis.com/zenn-user-upload/o2torgjyxba5ms458mpnssfvo7xy)

```sh
sudo raspi-config
```

Choose 'Interface Options' -> 'I2C' -> 'Yes'.
Then, reboot.

### Check the I2C interface working

![](https://storage.googleapis.com/zenn-user-upload/5btjfbuoypb64lygevj9f71vo0z8)

```sh
sudo i2cdetect -y 1
```

### Get the example code for testing the sensors

![](https://storage.googleapis.com/zenn-user-upload/joajwanq9nfzsjcj4br12dyhjhk2)

* https://github.com/AnaviTechnology/anavi-examples

```sh
git clone https://github.com/AnaviTechnology/anavi-examples.git
cd anavi-examples
```

### Install wiringpi

```sh
sudo apt install wiringpi
```

### Build the example code

![](https://storage.googleapis.com/zenn-user-upload/gsn3dh16v1yqamp9iinfh5bqbvue)

```sh
cd ./sensors/HTU21D/c
make
./HTU21D
```

### Enable Serial interface

![](https://storage.googleapis.com/zenn-user-upload/owoktt24g76q9ckr5ymlrrn04uto)

```sh
sudo raspi-config
```

Choose 'Interface Options' -> 'Serial Port' -> 'No' -> 'Yes'.

### Install python-pip

```sh
sudo apt install python-pip
```

### Install a Python module for mh-z19

```sh
sudo pip install mh-z19
```

Test it:

```sh
sudo python -m mh_z19
# -> {"co2": 5000}
```

### Put MH-Z19 outside for a while for calibration

![](https://storage.googleapis.com/zenn-user-upload/m75lbw64142cz3zrbvcsgxikppzu)

### Run ZERO point calibration

![](https://storage.googleapis.com/zenn-user-upload/jvaug4tjftovuuqk0hqpnnkip0d2)

While the device is put outside, run ZERO point calibration to calibrate the CO2 sensor:

```sh
sudo python -m mh_z19 --zero_point_calibration
```

After a while:

```sh
sudo python -m mh_z19
# -> {"co2": 400}
```

### Install nginx web server

![](https://storage.googleapis.com/zenn-user-upload/c94cmjfl0cwqt8vifswhcqm2vf0g)

```sh
sudo apt install nginx
```

### Clone a web UI

I published my web UI for displaying the sensor data on GitHub here:

* https://github.com/craftzdog/anavi-phat-sensors-ui

You can reuse it by cloning the repository.

```sh
cd ~
git clone https://github.com/craftzdog/anavi-phat-sensors-ui
cd anavi-phat-sensors-ui
```

### Build C programs for the sensors

![](https://storage.googleapis.com/zenn-user-upload/5vj4af7qmvaf70hgorq518cnijai)

```sh
cd sensors/BH1750
make
cd ../HTU21D
make
cd ../BMP180
make
```

### Prepare test data

```sh
cd ~/anavi-phat-sensors-ui
mkdir data
./sensors/HTU21D/HTU21D > ./data/HTU21D.json
./sensors/BMP180/BMP180 > ./data/BMP180.json
./sensors/BH1750/BH1750 > ./data/BH1750.json
sudo python -m mh_z19 > ./data/MH_Z19.json
```

### Configure nginx

![](https://storage.googleapis.com/zenn-user-upload/tn1ird21grmhut0t9qc4c186ojbq)

```sh
sudo vi /etc/nginx/sites-available/default
```

Replace the line:

```nginx
root /var/www/html;
```

with:

```nginx
root /home/pi/anavi-phat-sensors-ui;
```

Then, restart nginx.

```sh
sudo /etc/init.d/nginx restart
```

### Open the web interface from browser

![](https://storage.googleapis.com/zenn-user-upload/shjqj8hra87mwjgkorotu01ug2ep)

![](https://storage.googleapis.com/zenn-user-upload/z8sztlmjoo62yuz0si1uiqel8t31)

Boom!

### Configure root's crontab to update data every 5 minutes

```sh
sudo crontab -e
```

Edit it like so:

```cron
*/5 * * * * /usr/bin/python -m mh_z19                > /home/pi/anavi-phat-sensors-ui/data/MH_Z19.json
*/5 * * * * /home/pi/anavi-phat-sensors-ui/sensors/HTU21D/HTU21D > /home/pi/anavi-phat-sensors-ui/data/HTU21D.json
*/5 * * * * /home/pi/anavi-phat-sensors-ui/sensors/BMP180/BMP180 > /home/pi/anavi-phat-sensors-ui/data/BMP180.json
*/5 * * * * /home/pi/anavi-phat-sensors-ui/sensors/BH1750/BH1750 > /home/pi/anavi-phat-sensors-ui/data/BH1750.json
```

### Put the Raspberry Pi in a cable box

![](https://storage.googleapis.com/zenn-user-upload/8dpzrvjliug4maw4fx8idnnlc7q3)

![](https://storage.googleapis.com/zenn-user-upload/mpdydsbpzzvuah3zmj6p2j7vv6st)

![](https://storage.googleapis.com/zenn-user-upload/fdoc38l8qkii3kcp5qviz9fnpqc1)


* * *

That's it.
I hope you found it helpful.
Enjoy hacking.

#### Follow me online

* Check out my app called [Inkdrop - A Markdown note-taking app](https://www.inkdrop.app/)
* Subscribe Newsletter http://eepurl.com/dNgJo6
* Twitter https://twitter.com/inkdrop_app
* Blog https://blog.inkdrop.info/
* Discord community https://discord.gg/QfsG5Kj
* Instagram https://instagram.com/craftzdog