I have a RPi4B, MH-Z19C CO2 sensor and a UART to USB adapter.

When I connect to the sensor using USB I get stable readings:

{'co2': 1001, 'temp': 19, 'S': 0, 'U': 0}
{'co2': 1006, 'temp': 19, 'S': 0, 'U': 0}
{'co2': 1012, 'temp': 19, 'S': 0, 'U': 0}
{'co2': 1014, 'temp': 19, 'S': 0, 'U': 0}
{'co2': 1014, 'temp': 19, 'S': 0, 'U': 0}
{'co2': 1014, 'temp': 19, 'S': 0, 'U': 0}
{'co2': 1014, 'temp': 19, 'S': 0, 'U': 0}
{'co2': 1016, 'temp': 19, 'S': 0, 'U': 0}

But when I use the GPIO, the CO2 value looks as follows:

{'co2': 855, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 906, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 924, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 927, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 911, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 854, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 788, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 760, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 761, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 767, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 799, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 855, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 900, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 897, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 885, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 841, 'temp': 18, 'S': 0, 'U': 0}
{'co2': 767, 'temp': 18, 'S': 0, 'U': 0}

I use following python script to communicate with the sensor:

import serial
from time import sleep
import argparse
import sys

parser = argparse.ArgumentParser()
args = parser.parse_args()

device = '/dev/ttyS0'

if args.device:
        device = args.device

ser = serial.Serial(device, 9600, timeout=1)

while True:
        raw = ser.read(9)
        if len(raw) < 9:
                print("Read timeout")
        res = {'co2': raw[2] * 256 + raw[3], 'temp': raw[4] - 40, 'S': raw[5],
'U': raw[6] * 256 + raw[7]}

and this cabling when using the GPIO:


I checked with different cables and different 5V/ground pins.

How can I get stable results through the GPIO?

Edit: If I use 5V/ground from the USB adapter and serial from GPIO I get results that are much better, but still not as stable.

If I use 5V/ground from GPIO and serial from the USB adapter the results are as bad as connecting everything to GPIO.

  • I'm sorry for my useless answer - I confused the Pi's 3.3V and 5V pins and didn't recognize that you're actually powering the sensor like I suggested. I deleted my answer... My other guess is also that there's a problem with power delivery. Are you using ordinary jumper cables to power the sensor? If that's the case you could try different (thicker) cables. 125mA is not that much current, though...
    – Sim Son
    Sep 21 at 17:13
  • Yeah, the sensor data is verified with a checksum and also the temperature values look correct, so I aggree that the communication almost certainly is not the problem.
    – Sim Son
    Sep 21 at 17:17
  • Have you disabled the serial console in raspi-config? Otherwise, using the primary serial port will interfere with that.
    – PMF
    Sep 21 at 18:24
  • @PMF I have disabled serial console in raspi-config. @SimSon I doubt the cables are the issue as I tried using cables from the adapter with GPIO with same results. I'll try to get thicker cables just to make sure. I'm wondering if it could be an issue with the Pi itself, I received it today so I can still return it.
    – Phastasm
    Sep 21 at 18:32
  • 1
    Many sensors are voltage sensitive, maybe yours is as well. I believe the voltage feeding the sensor and or the A/D is difference between setups. I am not very good with word problems and pictures, a schematic does a lot including showing all power and ground connections in the power supply(s) and the system hardware.
    – Gil
    Sep 22 at 1:32

The issue was obviously power delivery. I fixed it by using an another power supply.


Just wanted to add that it's not normal for a sensor with specified 4.5 - 5.5V voltage range to be this sensitive to supply voltage. In fact, now that you "fixed" this by using a different power supply there is no guarantee that the new (more stable) value you're reading is any closer to actual CO2 level.

Good gas sensors are expensive, and cheap stuff from "Zhengzhou Winsen Electronics Technology Co" are essentially toys which are often unable to tell between an increase in CO2 and an increase in humidity. The readings go up when you breathe on them in both cases.

You may want to invest in something like a T6613.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.