Spurious zero (or way too low) readings from CO2 sensor

So I have a recently-built sensor, where the CO2 module sometimes reports 0, or strangely-low values (like 520ppm when the surrounding ones are >800ppm). Here’s a graph:

Is this just normal sensor noise? Or is there something wrong with the connection between the sensor and the PCB? I could resolder those.

I can of course paper over these values by doing quantiles/median when graphing, or ignoring all zero values, but a) that is just papering over it and b) would not solve the too-low-but-not-0 values.

This should not happen with the CO2 sensor.

I think there might be two issues:

a) You have some weak soldering on the board. Maybe just resolder the points and make sure they flow nicely around the holes.

b) Your power supply is not providing stable power. Please try with a high-quality power supply.

Let me know if that helps.

a) You have some weak soldering on the board. Maybe just resolder the points and make sure they flow nicely around the holes.

They look good enough: not too much solder (nicely curved almost-cones), and are shiny. They cover both the pins and the pads.

b) Your power supply is not providing stable power. Please try with a high-quality power supply.

This might be it. I’ve now switched to powering it with a an 8x (sic) USB2 hub, which should have plenty of power. I will also try different cables.

Please let us know if that fixes it.

Measurements from today (you can even see when I came home).

The deeper dip is to -1, which I guess is an error message of some sort. The other dip is to 515ppm.

In the last 24h, there are another two dips, again to 515ppm, so it’s probably something systematic. The frequency may be lower than it was with the other power supply and cable, but it’s too early to be sure.

@klausman I am not sure what you use on your backend but could it be that the low (but non zero/-1) values are already averaged. So what I mean is that you get -1 data points and correct values but these are sometimes averaged and lead to low numbers?
Maybe you can log the incoming stream of CO2 values with a timestamp and see if that could be the case.
Also, in your code, you could add an if statement to only send the payload to the server if CO2 > 400. Do you use our library or ESP home etc?

I’m using the library code from Airgradient (slightly edited to not send quite as many datapoints). I don’t do averaging there (and not in Grafana/Prometheus, either). I’ll change the receiving code to log every datapoint received to disk as well, to see if the 515 is an artifact of the -1 as you described. If that’s the case, I can just drop -1 (or <400) values on the ESP directly.

I’ve now run this again, with the more-stable power supply and changing the ESP-side code to drop all measurements <=0, which naturally got rid of the -1 readings.

But I still get spurious measurements, and they’re always exactly 514ppm:

I’ve also looked at the data arriving at my gateway-to-prometheus, and the readings are there (so they’re not interpolation artifacts of Prometheus or Grafana).

As I was going over the code to not report readings of 0 or -1, I very closely checked if there could have been any way the variables could have become aliases, un-initialized or assorted other things, but I have not found any evidence of that.

My next step will be to remove the OLED display (and all its code) to see if that may have any influence. It’s unlikely, but it’s an easy first step to simplify the code. After that, I will pare down further, removing the other sensors and simplifying the code to the bare necessities.

@klausman
Thank you for the update. This is quite interesting.

In the Arduino library under examples is simple code just for CO2.
image

You can use that as a base.

What is also interesting is that the error seems to always occur at the same CO2 level of around 675ppm:

Interesting find. Note the bit patterns:

515
1000000011
675
1010100011

If it were just one, I’d figure it’s an occasional bit-flip. But maybe two? Unfortunately, I don’t know what the wire format is for the communication between the ESP and the sensor. A friend will lend me a solder-joint inspection kit soon, and I’ll have a close look at my soldering.

So I inspected the soldering and it seemed like there might have been some issue with solder going through the PCB instead of connecting pin to pad. The 675->515 error has gone away, but I already have new suspects :slight_smile: I’ll keep it running as is to get more data.

One thing that I noticed is that the CO2 sensor is extremely sensitive about the input voltage that you feed into it. With my unit I get readings in very different value ranges depending on what I use to power the board. This is a bit of a PITA for me because until I permanently mount it somewhere I’ll have to power it from different sources (e.g. laptop USB, power brick, power bank, USB hub) which typically output slightly different voltage ranges. Until I commit to a single power source this will definitely mess with the automatic baseline correction algorithm.

One other thing that I noticed with my unit is that it seems to work as long as the input voltage sits between 4.64v (min that I measured) and 4.73v (max that I measured using one of my power sources while still OK). If I power it from my laptop’s USB ports, the input voltage is somewhere around 4.82v - 4.86v and this will ALWAYS make reads return 0ppm and set bit 1 (Fatal error) and bit 3 (Algorithm Error) of the MeterStatus input register.

I don’t know if this helps but maybe it’ll give you some ideas to explore.