Tracker Dog

The CO2 content of indoor air gives you a clue as to its quality. Setting up a simple sensor will tell you when it’s time to let in some fresh air.

The earth’s atmosphere is made up of 78 percent nitrogen, 21 percent oxygen, and 1 percent argon. Depending on the environment, up to 4 percent water vapor can also be present. Carbon dioxide (CO2) only accounts for a share of 0.04 percent.

But this share, along with the sun’s rays and some trace elements from the soil, enables plants to grow. Humans and animals, on the other hand, generate energy using oxygen to convert food. In the process, they emit CO2, which typically accounts for 4 percent of the air humans breathe out.

In addition, humans excrete aerosols that can transmit respiratory diseases such as influenza or COVID-19. For this reason, CO2 content is a useful indicator of indoor air quality. If the CO2 level exceeds a value of 1000 ppm, also known as the Pettenkofer number, it’s time to ventilate (ppm, or parts per million, is a common, but not officially established, unit of measure). The legal limit for the workplace is 5000 ppm.

Before the industrial revolution, the CO2 content in the atmosphere was 0.02 percent, or 200 ppm. Since then, it has been increasing in an almost linear way, modulated by annual fluctuations. In 2020, the average was 413.6 ppm.

Carbon dioxide has an effect on the climate. It blocks infrared radiation windows at wavelengths of 4.3 and 15 µm. The higher the CO2 concentration, the more infrared radiation is emitted back to earth and the higher the equilibrium temperature between solar and infrared radiation is. Unlike other greenhouse gases (such as methane), carbon dioxide is stable and remains in the atmosphere for thousands of years.

MOX Sensors

Metal oxide (MOX) semiconductor gas sensors mainly adsorb organic or reactive gases. Figure 1 shows two modules designated MQ2 and MQ3. They use gas adsorption to measure the change in resistance on a thin metal oxide (MOX) layer, typically tin oxide. To avoid saturation, the system is heated during use. To protect against explosion, the sensors are enclosed with metal gauze.

b01_mq23.tif
Figure 1: MQ2 and MQ3 gas sensors measure the CO2 concentration as the change in the resistance on a metal oxide layer.

Before initial start-up, MOX sensors need to be degassed. In Figure 2, you can see how the resistance at the sensor that I just switched on increases and the voltage drop at the load resistor decreases. The half-life in the time window for the measurement is 600 seconds. The data sheet recommends preheating for many hours. Adsorption sensors are inexpensive, but are nonspecific in terms of their reaction to many gases and difficult to calibrate. Carbon dioxide is almost not detected at all.

b02_ausgasen_ENG.tif
Figure 2: The degassing curve of an MQ3 sensor shows how the resistance is changed by heat.

NDIR Detectors

Nondispersive infrared (NDIR) detectors measure the absorption of infrared radiation at a fixed wavelength (nondispersive). For CO2, this is typically 4.3 µm. A photodetector measures the absorption of a short light pulse. The less light that reaches it, the higher the CO2 content is. All of the components for a NDIR detector are installed in the housing, which is only a few centimeters in size (Figure 3).

Ambient gases diffuse into the interior through the white covered apertures in the front and on the left side of the housing. An incandescent lamp as an infrared source is hidden under the bump on the front. The interior uses mirrors to lose as little light as possible through diffusion. If the covers on the apertures are damaged, dirt can penetrate into the measuring chamber, which impacts the detector’s sensitivity.

The MH-Z19 sensor can communicate with the outside world via several interfaces. In our lab, we focused on the serial interface. In principle, it could talk to a Raspberry Pi via the UART ports, pin 8 and pin 10. Instead, we performed the tests with a serial-to-USB converter (located on the right in Figure 3).

b03_mhzsusb.tif
Figure 3: The MH-Z19 CO2 sensor with a serial USB interface measures the incidence of infrared light on a detector.

Communications

The serial-to-USB converter’s data lines are designed for 3.3 volts, while the sensor requires 5 volts. Figure 4 shows how to connect the module: On the right, you can see the lines for the 5V voltage supply and on the left the two communication lines.

b04_mnzbz.tif
Figure 4: The communication connections on the MH-Z19 sensors are designed for 3.3 volts.

Connect the transmit line on the sensor to the receive line on the serial-to-USB converter and vice versa (i.e., Tx to Rx and Rx to Tx). To avoid destroying the device, the communication line must not exceed a voltage of 3.3 volts.

There are some libraries that help the MH-Z19 communicate on the Rasp Pi’s UART interface, but the serial-to-USB converter makes this even easier. Plug in the USB connector, configure the serial port, send commands to the detector, and read the responses.

First, you need to determine the name that the system uses to address the new USB device. Calling dmesg | grep tty returned ttyUSB0 in our lab. If you want to use a Python program to read the data later on, it makes sense to start the interpreter in interactive mode first (Listing 1). You can then configure the serial port setting to use a baud rate of 9600 and a timeout of one second (line 3).

Listing 1: Testing the MH-Z19

01 $ python3
02 >>> import serial
03 >>> port = serial.Serial('/dev/ttyUSB0', baudrate=9600, timeout=1)
04 >>> rco2= b'\xff\x01\x86\x00\x00\x00\x00\x00\x79'
05 >>> port.write(rco2); port.readline()
06 9
07 b'\xff\x86\x03\xbf9\x00\x00\x00\x7f'
08
09 >>> port.write(rco2); s=port.read(9)
10 >>> print('co2: ', s[2]*256 + s[3])

The port.write(rco2) command tells the detector to send data. The output first returns the number of bytes read, 9 in our example, and then the data payload. The following lines of code process the numbers. If everything worked out, and if you just connected the sensor for the first time, the output will be 5000 (ppm). While the MH-Z19 determines relative values very accurately, it doesn’t have a reference point. That’s why the manufacturer assigns a default of 5000 ppm when shipping out the sensor, as a safety measure.

Strictly speaking, calibration would require standardized conditions, but I will be making do with a simplified procedure here. Set up the sensor in a well-ventilated place. Then tell the sensor to use the value it detects as the atmospheric minimum. Based on its default setting, this is 400 ppm.

Communication is routed via the
HD line, which you need to short to ground for some time for this purpose. Based on comments on the web about calibration, it appears that the communication period should be at least 20 minutes. Other users also advise against triggering calibration via the software.

Get Ready to Measure

The MH-Z19 has two measuring ranges, and newer modules have three: up to 2000 ppm, up to 5000 ppm, and up to 10000 ppm. The variables from Listing 2 set the upper limit when you use a write command to send them to the detector.

Listing 2: Reading the Data

$ python3
### read data
>>> rco2= b'\xff\x01\x86\x00\x00\x00\x00\x00\x79'
### ranges: 2000, 5000, 10000 ppm
>>> r2000 = b"\xff\x01\x99\x00\x00\x00\x07\xd0\x8F"
>>> r5000 = b"\xff\x01\x99\x00\x00\x00\x13\x88\xcb"
>>> r10000 = b"\xff\x01\x99\x00\x00\x00\x27\x10\x2F"
### get data
>>> port.write(rco2); s=port.read(9)
>>> print('CO2: ', s[2]*256 + s[3], 'ppm; T: ', s[4] - 40, 'C)

The sensor corrects its analyses as a function of the ambient temperature, which it also outputs. The last line in Listing 2 outputs the concentration in parts per million and the temperature in Celsius. If the output appears to be incorrect within a loop, a pause of 100 milliseconds between two queries can help.

Measurements

In the age of COVID, you might not have access to a conference room with bad indoor air. As an alternative, simply breathe into a bag and hold the sensor inside it. Figure 5 shows another testing option: Cover the bottom of a tall glass with baking soda (sodium bicarbonate) and add water or a weak acid.

19330.png
Figure 5: With a glass and some baking soda you can create a test setup for measuring CO2; adding water stimulates the baking soda causing a reaction.

The baking soda will decompose and give off carbon dioxide. The gas collects at the bottom of the glass
and slowly rises, where the detector registers it.

If you do this right, you will see the measurement curve shown in Figure 6, but too much baking soda will cause the concentration to quickly exceed the limit of 10000 ppm.

b06_test_ENG.tif
Figure 6: An MH-Z19 measurement of a CO2 concentration in the air at 4000 ppm.

To be able to collect measurements, the ambient gas needs to diffuse into or out of the housing when the sensor is returned to a normal atmosphere after CO2 exposure. Since the measurement bandwidth is small, the half-life is less than 30 seconds. The time is determined by the exponential fit from Figure 7.

b07_abklingen_ENG.tif
Figure 7: Time resolution and decay behavior of an MH-Z19 sensor.

Measurements were taken every second. However, the integration time of the detector in the sensor is five seconds. This is why the measuring points look like a staircase instead of creating a continuous curve.

Conclusions

Inexpensive MOX sensors are simple to use and easy to read, assuming you have an analog-to-digital converter (ADC). Carbon dioxide is an inert gas, which makes detection difficult. The MH-Z19 sensor consists of a miniature measurement chamber that allows CO2 concentrations of a few 100 ppm to be determined via light absorption in the infrared range.

To assess the quality of the indoor air, all you need to do is to distinguish between two states with less than or more than 1000 ppm CO2 content in the air. Absolute measurements to measure a steady increase of the greenhouse gas in the atmosphere will not work due to a missing reference and the long-term stability of the sensor.

The MH-Z19 sensor gives you digital data output. When paired with a serial-to-USB converter and a few lines of Python code, you can turn a Rasp Pi into a practical air quality monitoring device.