Breath of Fresh Air

Arduino-based Air Quality Monitor & Datalogger

Erich Heinzle and Steph Kriewaldt

Issue 56, March 2022

This article includes additional downloadable resources.
Please log in to access.

Log in

An open-source low-cost air quality monitor using the Arduino ecosystem.

In Issue 53, we caught up with Erich from the Lobethal Lutheran School with their school’s Arduino-based Christmas lights controller for their community event.

Recently, Erich got in touch to discuss another of their school’s Arduino-based projects; an air monitoring project to assess air changes and air quality in the classrooms.

With students returning to schools around Australia in late January, it was important for schools to take steps to better ventilate classrooms to help avoid Covid spread. Thousands of classrooms across the country have also been fitted with air purifiers, however, in some states, this is not the case. Air purifier or not, it is still expected that traditional ventilation measures be taken, such as opening windows to let fresh air in and stale air out.

In order to measure air quality in their classrooms, and also provide their students with a learning opportunity, the Lobethal Lutheran School has designed an Arduino Nano-based data logger.

The custom designed shield is open hardware, and the code is open source. It uses an Arduino Uno board, Adafruit logger and sensors, 7-segment display and cabling/USB power supply, which all comes in at under $100. Using an Arduino Nano Every and a generic sd/rtc daughter board, gets the cost down to around $60-$70 per unit.

In Lobethal Lutheran’s case, they have one board permanently fixed in each classroom, and a portable unit that can do logging wherever it’s needed.

The circuit used a DFRobot CCS811 CO2 sensor to measure CO2 levels. CO2 is a reasonable proxy for air changes and ventilation, and by extension, air quality with respect to airborne pathogens such as Covid.

Principal, Steph Kriewaldt has been getting the students to look at the collected data and getting them to see how ventilation can be improved, which naturally, makes for a good, practical STEM exercise.

According to Steph, some of their classrooms were safe at around 400-500ppm (parts per million), however, some of them were quite concerningly at around 1500.

By monitoring the classroom’s CO2 in realtime, the students can study the data and see the difference in CO2 levels when ventilation is improved by opening windows and turning on fans.

Steph has kindly sent us an example of the plots of collected data.

The Broad Overview

This low cost data logging air quality monitor can be of use in educational and community settings to provide a qualitative indication of air quality over time.

In particular, CO2 levels can be a useful proxy for air turnover in built environments, and by extension, inform measures that seek to reduce the risk of persisting airborne pathogens. The utility of CO2 as a proxy for airborne pathogen loads will be affected by sources of combustion or fermentation (i.e. processes producing CO2 in addition to people) in the indoor space, and by the use of air purifying devices, such as those circulating air through suitable filters.

During operation, updated readings are displayed sequentially on the 4 digit LED display.

  • Temperature readings in Centigrade are preceded by "t" on the LED display
  • Humidity readings in percent are preceded by "h" on the LED display
  • Carbon dioxide readings in ppm (parts per million) are preceded by "CO2" on the LED display
  • Total volatile organic compound readings in ppb (parts per billion) are preceded by "tvoc" on the LED display

The code also streams results over USB as a serial device, allowing readings to be viewed as they are collected in a serial monitor in real time.

How it works

The shield and accompanying software allow the CCS811 sensor to be used to monitor CO2 and total volatile organic compounds (VOC), and the AM2320 sensor allows humidity and temperature to be recorded as well.

The shield also has provision for a TM1367 based four digit LED display to allow the display of readings in realtime.

In addition to taking and displaying readings every 10 seconds, the accompanying code will write time stamped readings to an SD card every three minutes, thanks to an Adafruit datalogging shield with a PCF8523 real time clock.

The hardware has been tested on the Adafruit "R3 compatible" version of their datalogging shield, and a genuine Arduino Uno R3.

The datalogging shield requires a CR1220 battery for the real time clock, and will require a FAT16 or FAT32 formatted SD card of between 32MB and 32GB in size.

Board Assembly

The Adafruit Datalogging Shield is sandwiched between the Arduino Uno and the Lobethal Lutheran School sensor/display shield PCB.

For data transfers to and from the SD card, the Adafruit Datalogging Shield uses SPI on the following Arduino Uno pins:

  • SCK
  • MISO
  • MOSI
  • D10 as CS (chip select)

For real time clock operations, the datalogging shield also shares the I2C bus with the CCS811 and AM2320 sensors, using the following pins:

  • SDA(A4)
  • SCL(A5)

This leaves multiple pins free on the Arduino if code customisation is needed, such as for on/off signals for fans or building ventilation systems. There is ample prototyping space available on the datalogging shield for wiring of this nature, to allow pins D4 to D9, for example, to be broken out for various control signals.

Data logs are written in CSV format, with sequential naming starting with LLSAQM00.CSV

About the PCB

The PCB was designed in pcb-rnd and simplifies the connections for the TM1367 display, CCS811 sensor and AM2320 sensor to an underlying Arduino Uno R3.

The PCB layout can be opened in pcb-rnd, and Gerbers for the shield have been provided in a zip file to allow ordering from the usual online PCB suppliers.

The PCB also allows for the use of a 16 pin, 0.39" (4YSD-439AB4B-35 or similar) four digit, seven segment LED display with current limiting resistors, instead of the four pin four digit TM1637 module. A sketch supporting these displays will be uploaded to Erich’s GitHub in due course

The Build:

Parts Required:JaycarAltronicsPakronics
1 x Arduino Uno R3 or compatible board (with USB cable)XC4410Z6280ARD-A000066
1 x Adafruit R3 compatible data logging shieldXC4536 ^Z6380 ^ADA1141
1 x CR1220 battery for datalogging shieldIncludedS4996B-
1 x SD card, formatted as FAT16 or FAT32, between 32MB & 32GBXC4989D0328ADA2692
1 x 5V supply/USB chargerMP3144M8903A-
1 x AM2320 sensor--ADA3721
1 x DFRobot CCS811 air quality sensor-Core Electronics: SEN0339-
1 x TM1637 based four digit, seven segment LED display-Phipps: PHI1071888-
1 x 40-pin Header StripHM3212P5430DF-FIT0084
1 x 40-pin Header SocketHM3230P5390-
1 x 2x3 Header Socket*HM3208P5383 ^-
1 x LobethalLutheranAirQualityShieldV1 PCB-See text.-

Parts Required:

* Quantity required, may only be sold in packs.
^ Similar product to one used, however, this is untested with this build. Modifications may be required.

Step 1:

Prepare the Arduino Uno, Datalogging Shield and headers.

Step 2:

Break apart the 40-pin header to create 1 x 6 pin, 2 x 8pin and 1 x 10-pin headers.

Step 3:

Insert the four inline headers and 6-pin socket into the Uno with the shorter pins sticking up.

Step 4:

Place the Datalogging shield on top of the Uno so that the pins stick through the PCB holes.

Step 5:

Solder all of the pins onto the Datalogging shield.
Double-check for any poor or dry solder joints.

Step 6:

Cut the 40-pin header socket into a 20-pin socket.

Step 7:

Using some cutters or pliers, remove the 7th pin so you have 6 pins on one side and 13 on the other.

Step 8:

Cut the socket into two, to make one 6-pin and one 13-pin

Step 9:

Prepare the Air Quality sensor and 7-pin header.

Step 10:

Solder the header to the sensor as shown here.

Step 11:

Solder a 7-pin header into the shield and insert the sensor as shown here. Note that the 7th pin (RST) remains exposed and is not required to be connected.

Step 12:

Prepare the AM2320 sensor.

Step 13:

Insert the AM2320 sensor into the shield and solder on the top side of the board, as shown here.

Step 14:

Prepare the 13-pin header with its missing 7th pin.

Step 15:

Prepare headers and sockets as you see here.
Note: The 7th pin needs to be removed from the header.

Step 16:

Mount the header sockets and insert the pins as shown here.

Step 17:

Place the Shield on top so that the pins protrude through as you see here.

Step 18:

Solder all of the pins, making sure the solder joints are shiny and don’t short to any other tracks.

Step 19:

Place the datalogging shield on top with the pins protruding through, as shown.

Step 20:

Solder the pins.

Step 21:

Prepare the 7-segment display. As you can see here, the 4 pins on the display are at a right angle.

Step 22:

Using a pair of long-nose pliers, gently bend the pins so that they are straight.

Step 23:

Using a soldering iron and pliers, carefully melt the solder joint for each pin and push the pin through, as shown here.

Step 24:

Do this for all four pins.

Step 25:

Solder the four pins to the shield.


After assembling the datalogging shield's headers and inserting the battery, the shield should be mounted on the Arduino Uno R3 and the clock example code available within the Arduino library manager used to set the current time (see Adafruit instructions on setting up the datalogging shield).

Note: The unit should be powered down before inserting or removing the SD card.

Once the air quality PCB has been assembled, it can be mounted on the datalogging shield, and the air quality monitoring sketch uploaded.

After reset, if all goes well, an initial flash screen "LLS" should appear, after which readings will be displayed sequentially, with new readings being taken every 10 seconds. Every three minutes, cached readings are written to the SD card.

It is recommended that the CCS811 be given a 48 hour initial burn-in period and be allowed 20 minutes for the sensor to warm up to provide reliable readings thereafter.

The Code

The code, pcb layout and Gerbers can be found on the school’s GitHub page:


Reading & Resources:

Erich Heinzle

Volunteer Educator

Steph Kriewaldt

School Principal - Lobethal Lutheran School, Adelaide