S8 CO2 reading of -2

Does anyone know what the -2 error means? When I get -2 error it does not send data. I can recover by power cycling the unit and breathing on the sensor. After a couple try’s it’s back. It has only happened twice when I was first setting it up and moving it to different locations. Also, I can’t seem to find the recommended power supply current rating, if someone knows that would be helpful.



It is a return code of the function AirGradient::getCO2_Raw() in the library airgradient.cpp

As you can see in the code snippet below in the third line from the bottom it says return -2; and means that no value could be read because the software deemed the CO2 sensor not available. Why this is/was the case is not clear for me etiher but I guess a flaw of the softserial library which is having some timing difficulties.

First thing I would do, is check for any electrical issues (check for bad solderings at the sensor and D1).

int AirGradient::getCO2_Raw(){
  // CO2_READ_RESULT result;
  const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
  byte CO2Response[] = {0,0,0,0,0,0,0};
  _SoftSerial_CO2->write(CO2Command, 7);
  if (_SoftSerial_CO2->available()){
	for (int i=0; i < 7; i++) {
      int byte = _SoftSerial_CO2->read();
      CO2Response[i] = byte;
	  Serial.print (CO2Response[i],HEX);
	  Serial.print (":");
	  if (CO2Response[0] != 254) {
		  Serial.println("Invalid serial read");

		  return -1;
		  // Serial.print (CO2Response[i],HEX);
	      // Serial.print (":"); 	  
    unsigned long val = CO2Response[3]*256 + CO2Response[4];  
    return val;	
    return -2;

I also get a -2 on the CO2 sensor. However, when I have the USB cable attached to my computer and the Arduino IDE serial monitor active, it works just fine. Close the serial monitor and the CO2 sensor stops working.

In case it helps anyone, I too was seeing the -2 value from the S8. I went back and rechecked all of my solder joints and noticed one that needed a bit of touchup. That fixed the problem and it has been working fine since.

The S8 needs a very stable power supply. So make sure you have a high quality power adapter. This often helps with these issues as well.

Even with my bench top power supply, it’s a bit flaky… I’ll have my improved circuit boards in the next week. I’ll let you know how that works out once I get everything connected.

So… I have my updated board running an SGP30 with an S8 CO2 and SHT31, all sensors are working as expected on my updated board.

Readings are a bit wonky right now as I’ve only had it up for a few minutes… Seems none of these sensors play nicely for the first couple of days.

I’m still missing the PM sensor on this board, but it’s somewhere in transit between China and me.

# HELP particle_count Count of Particulate Matter in µg/m3
# TYPE particle_count gauge
# HELP particle_count Count of Particulate Matter in µg/m3
# TYPE particle_count gauge
# HELP particle_count Count of Particulate Matter in µg/m3
# TYPE particle_count gauge
# HELP rco2 CO2 value, in ppm
# TYPE rco2 gauge
# HELP atmp Temperature, in degrees Fahrenheit
# TYPE atmp gauge
# HELP rhum Relative humidity, in percent
# TYPE rhum gauge
# HELP sensors_boot_time AirGradient_Internal boot time, in unixtime.
# TYPE sensors_boot_time gauge
# HELP total_volatile_organic_compounds total of armful gaz detected.
# TYPE total_volatile_organic_compounds gauge
# HELP ethanol ethanol level.
# TYPE ethanol gauge
# HELP hydrogen hydrogen level.
# TYPE hydrogen gauge


This board revision is a definite win. With no mods, everything is working just fine including the CO sensor and SGP30.

Just got a PM sensor and it’s working as well. I will attach the gerbers later after I do a couple small edits.

Modified Board Gerber Files

Tested to 3.73 volts on the 5v rail. Still runs just fine.

I have 3 of these setup now and have not been able to read anything but -2 from the s8 as of yet.

I am using CO2_Simple sample code

Here are some of my tries:

  1. Ensure good stable 5V supply - I do see a small led flash in the sensor roughly every 3-5 seconds
  2. Tried changing code delays/timeouts
  3. Checked soldering
  4. Breadboarded circuit so same as AirGradient pcb
  5. Tried using different D1 mini’s
  6. Tried several different SoftwareSerial libraries.
  1. Tried building/testing with Arduino IDE.

I do use PlatformIO to build using VSCode.

Blink app works fine

Only thing that I cant seem to verify is that SoftwareSerial is working correctly, and I have a feeling that is the problem. PlatformIO seems to default to EspSoftwareSerial @ 6.12.7 is this the best one?

Here is a log:

Processing d1 (platform: espressif8266; board: d1; framework: arduino)
--------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/d1.html
PLATFORM: Espressif 8266 (4.0.1) > WEMOS D1 R1        
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
 - framework-arduinoespressif8266 @ 3.30002.0 (3.0.2) 
 - tool-esptool @ 1.413.0 (4.13)
 - tool-esptoolpy @ 1.30000.201119 (3.0.0)
 - tool-mklittlefs @ 1.203.210628 (2.3)
 - tool-mkspiffs @ 1.200.0 (2.0)
 - toolchain-xtensa @ 2.100300.210717 (10.3.0)        
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 36 compatible libraries
Scanning dependencies...
Dependency Graph
|-- AirGradient Air Quality Sensor @ 1.5.0
|   |-- EspSoftwareSerial @ 6.12.7        
|   |-- Wire @ 1.0
Building in release mode
Retrieving maximum program size .pio\build\d1\firmware.elf
Checking size .pio\build\d1\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [====      ]  35.6% (used 29156 bytes from 81920 bytes)
Flash: [===       ]  26.2% (used 273741 bytes from 1044464 bytes)
Configuring upload protocol...
AVAILABLE: espota, esptool
CURRENT: upload_protocol = esptool
Looking for upload port...
Auto-detected: COM3
Uploading .pio\build\d1\firmware.bin
esptool.py v3.0
Serial port COM3
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 40:91:51:53:16:7a
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Compressed 277888 bytes to 203583...
Writing at 0x00000000... (7 %)
Writing at 0x00004000... (15 %)
Writing at 0x00008000... (23 %)
Writing at 0x0000c000... (30 %)
Writing at 0x00010000... (38 %)
Writing at 0x00014000... (46 %)
Writing at 0x00018000... (53 %)
Writing at 0x0001c000... (61 %)
Writing at 0x00020000... (69 %)
Writing at 0x00024000... (76 %)
Writing at 0x00028000... (84 %)
Writing at 0x0002c000... (92 %)
Writing at 0x00030000... (100 %)
Wrote 277888 bytes (203583 compressed) at 0x00000000 in 18.0 seconds (effective 123.8 kbit/s)...
Hash of data verified.

Hard resetting via RTS pin...
=============================== [SUCCESS] Took 22.01 seconds ===============================

19:27:19.980 > ₆₅₅₃₃ ₆₅₅₃₃ ₆₅₅₃₃ CO2 Successfully Initialized. Heating up for 10s

19:27:30.291 > C02: -2
19:27:35.506 > C02: -2
19:27:40.721 > C02: -2
19:27:45.936 > C02: -2
19:27:51.150 > C02: -2
19:27:56.366 > C02: -2
19:28:01.581 > C02: -2
19:28:06.795 > C02: -2


platform = espressif8266
board = d1
framework = arduino
board_build.mcu = esp8266

Does anyone else see garbage character through the serial monitor at every startup, or just me…

Any ideas, suggestions appreciated…

Garbage on the serial monitor is an indication of a serial speed mismatch.

Thanks for the response. I had considered that, tried multiple speeds and none of the time it disappeared or was anything sensible.

It is also on the monitor line and I doubt it interferes with the GPIO (??)

It is only on reset/app startup which makes me think it is a poor initialization.
More curious is if it does not happen to others and it does to me on all my d1 mini’s.

Added tries:
8) Building/running from different computer
9) running through a powered USB Hub
10) Tried different USB cables

Yeah, I get junk on restart on some of my devices… I believe that to be normal.

1 Like

Jumping in to the chat as my problem might be related as I’m having issues with 2 kits I have installed in 2 different rooms. Both are frequently reporting CO2 values of -1 on the attached OLED but on app.airgradient.com/dashboard there is no error and it reads the CO2 values I would expect for the room at that time. So, is something off with how it’s communicating with screen then? Both S8 setups have the same script running and were built a few months apart.

I’ve never used the dashboard, does it time stamp those readings? Because I would expect that if you are getting a -1 or -2 (error reading) it would likely update the display but maybe not pass that over to the dashboard and the dashboard will only show the last valid reading…

I could be completely wrong about that though.

Yes. We are doing error handling on the dashboard and ignore invalid values.

I suppose why that’s interesting then is that the display will read “CO2 -1” only for hours at a time, but the AirGradient dashboard will be updating without any data gaps larger > 5minutes (smallest bin size).

EDIT: And the values change in the Dashboard so it isn’t just reporting the same value over and over (i.e., last valid value) or doing some weird averaging of the same value/time_bin. It will go up when it should (office door closed) and down when it should (office door open/window open).

Also, I switched USB cable from a cheaper one that came with some random Amazon device to one that came with my PS4 controller and after 12 hours it was still reading the correct CO2 values. Will report back and switch out the second device with higher quality USB cable as well. The USB charging block I was using for the one where I switched cables was from an iPhone charger so I assume it is of a high quality build as well.

Did you check the solderpoints if there are some weak ones? Sometimes these can cause some weird issues as well.

I thought it was unlikely they’d both have the same reaction to a solder any specific solder joint(s) given they were assembled months apart and have the exact same problem.

I swapped the USB cables for both units out with higher quality cables. I’m at 2.5 days with unit 1 with no problems and 18 hours with unit 2 with no problems. So, as far as I can tell the problem was the USB cable not being able to supply the super stable signal the unit requires. Honestly had no idea that was a thing (hobbiest here). Only other time I’ve had issues like that was with cables being data and/or power when working with microcontrollers like Adafruit boards.

So, unless something comes up I’d say my problem is tentatively closed.

Problem: S8 sensor was giving CO2 = -1 and sometimes >60,000 on the OLED. Still recorded realistic values to the dashboard with occasional 1 hour gaps (about once every few days). The -1/>60,000 value was present for >80% of the time on the OLED. I would also get emails daily letting me know there were power failures.

Solution: Swapped out cheap, low quality USB cables with those from known manufacturers (e.g., PlayStation 4 controllers by Sony ). Haven’t gotten any power failures and the display and dashboard are reporting realistic values. 2.5 days in test for unit 1 and nearing 24 days for unit 2. Will update if things change.

Update: Both sensors are still running well, but the sensor in my office went down for ~15 minutes. It coincides with the exact moment I started charging a Makita 18V battery on a rapid charger on a shared extension cord. So, from what I’m seeing that caused a little current wobble, which upset the sensor. The sensor went back online once the circuit current stabilized.

Does this sound reasonable to anyone with actual EE knowledge? That the S8 is just very sensitive to current fluctuations? If it’s relevant, this is on a circuit that is not truly grounded (farm house from the 1920s).

No, the current isn’t the issue… See my test above… It’s noise that it’s sensitive to. The stock boards with these kits have some issues with noise. They need a very clean noise free environment to run properly. Your charger probably puts out a fair amount of EMI.