Monitoring air quality with IAC-core c and ESP8266

I wanted to get some insight into the internal air quality. Already for a while I was tinkering around with it, even build my own dashboard, but now that I discovered HASS, I’m switching more and more of my home automation into it, and this was one of the projects on my todo list.

I’m using a IAQ-core c sensor, wich communicates using i2c to a ESP8266. The ESP8266 in turn is connected to my wifi and sends the CO2 and VOC values over MQTT to hass.

I used my home brew pcb to connect everything together, is’s still a bit in prototype state, so it now looks like this:

The idea is to later get the sensor inside the box, combined with some other sensors (like temperature, humidity, light) ad then close it up.

The results are good, I can see the CO2 and TVOC values in HASS:


and when I close all doors and windows while in the room, I can clearly see it rising:


I’ve shared the code here:

The only downside is that this sensor is a bit expensive, especially if you want to do this in every room, so I also ordered one of these to do some testing with: CJMCU-811


This is great. I use a netatmo sensor that includes CO2 in its measurements, and I, too, notice a dramatic difference between the windows being open and closed.

Another interesting thing to note is that the CO2 level gives a hint as to whether or not someone is in the room. The problem is that it is only a hint because it is slow to fall when someone leaves, and as you noted, there are a few other factors that play into it (e.g. windows being open, someone is cooking, etc.).

For this reason, though, I’ve always thought of including this information in a Bayesian binary sensor as a lightly weighted observation for room presence monitoring. It is a weak indicator, sure. But the more observations included, the more accurate it gets.

1 Like

cool, didn’t even think about that, could be useful if you combine it with other sensors. For now I just wanted to know how “good” the air quality in my work room was.
I’m not yet sure if my measurements are ver precise though. I found this table online:

250-350ppm Normal background concentration in outdoor ambient air
350-1,000ppm Concentrations typical of occupied indoor spaces with good air exchange
1,000-2,000ppm Complaints of drowsiness and poor air.
2,000-5,000 ppm Headaches, sleepiness and stagnant, stale, stuffy air. Poor concentration, loss of attention, increased heart rate and slight nausea may also be present.
5,000 Workplace exposure limit (as 8-hour TWA) in most jurisdictions.
40,000 ppm Exposure may lead to serious oxygen deprivation resulting in permanent brain damage, coma, even death.

According to this table, I should very quickly get “Complaints of drowsiness and poor air.” :face_with_raised_eyebrow:
Makes me wonder what it will be in the bedroom or at my work…

What kind of readings do you get from the Netatmo?

That is very cool. I really want to implement a air quality sensor, but that IAQ core c is very expensive to ship one to my country (total cost is $67 USD).

Can you let us know how you get on with the CJMCU-811 and how it compares to the IAQ.

Well, with the windows closed, no forced air circulation (as in the central AC/heat not running), and my wife and I both downstairs, the downstairs sensor reads in the range of about 1200 ppm to 1500 ppm. I’m not so sure about any complaints of poor air, though. :grinning: And it never rises above 2000 ppm unless someone’s cooking something in the oven.

Yes, will post once I got one of them

Where did you order the IAC-core c? Is the CJMCU-811 better or the same compared to the IAC-core c?

have you tried the bme680?

It’s been a while since my last post. I by now received 2 CJMCU-811 sensors out of china, but was unable to get either of them to do anything. Even when I hook them up to a Arduino nano and run a simple I2C scanner, I do not get any response, so I’m not yet sure where to go from there.

The BME680 might be a option, it’s still cheaper than the IAQ sensor

I got the IAC-core c from mouser by the way

ErikNL: I have been doing a similar experiment. I am now measuring air quality on both CJMCU-811 (CCS-811) and CJMCU-932 (iAQ-core) in my home office, but on two different Arduinos.

I did not succeed in interfacing CJMCU-811 with a cheap Arduino Uno clone. With original Arduino Uno it seems to work. One reason may be that according Adafruit page, the chip uses i2c clock stretching, which is not working on all platforms.

CJMCU-932 however works with a cheap Arduino Uno clone.

I am using two Arduinos because they did not work on the same i2c bus. I suspect that the reason is that on both boards (not the sensor itself) have a built-in pull-up resistor. The bus does not work if there are two pull-up resistors. I am suspecting this is so, because both of them work individually without pull-up resistors.

I am not sure if iAQ-core has done enough burn-in yet, but here are the values I am getting now:

‘hdc1080’: {‘Temp’: ‘29.10’, ‘Humidity’: ‘27.13’},
‘iaqcore’: {‘tVOC’: ‘1463’, ‘Resistance’: ‘122153’, ‘ECO2’: ‘5308’},
‘ccs811’: {‘CO2’: ‘434’, ‘tVOC’: ‘5’}

So the values are very different.

Ver interesting, I did not know the CJMCU-932 did use clock stretching, that might indeed be the reason that I didn’t get it to work on a ESP8266. Maybe it will work when I would use the BRZO library for it, but that would require some more “bit banging” on my side.

Strange that your sensors give such different results, I did notice that the IAQ core is quite sensitive for temperature changes. Since my room temperature wend up quite a bit (because I was running a mining PC), it gave me much higher values than before.

I am by the way also experimenting with a MH-Z14A NDIR co2 sensor, but did not yet get it working on a ESP8266, wich I would like, because then I can send the values over MQTT to home assistant

I’ve also been trying a few things. So far I’ve tried the CCS811 + BME280 (Sparkfun), BME680 and the HDC 1080 (temp+humidity). The Bosch temperature is always higher than any other sensor.

I’m considering the Senseair S8, it’s not cheap but there is code available for both RPi and Arduino.

Would you recommend a ccs811 over the bme680?

Yes I would. However they give you different information. The BME680 gives you a air quality %, based on some calculations. The CCS811 returns eCO2 and TVOC.
If you are planing to use on the RPi you will need to reduce the baudrate on i2c.

1 Like

I did not yet have any luck with the ccs811. Normaly I first start with the i2c scanner ( when I get a new i2c sensor, but the ccs811 did not show up with that, not on a arduino or ESP8266.

I now did some testing with the BRZO library (, that I used for the IAQ core sensor too. I made a very simple sketch that should return at least some data:

#include "brzo_i2c.h"

uint8_t SDA_PIN = 4;
uint8_t SCL_PIN = 5;
uint8_t iaq_adr = 0x5A;

uint8_t buffer[14];

uint8_t error = 0;

uint16_t co2;
uint16_t tvoc;

void setup() {
  brzo_i2c_setup(SDA_PIN, SCL_PIN, 3000);

void loop() {
   brzo_i2c_start_transaction(iaq_adr, 100);
   brzo_i2c_read(buffer, 14, true);


   error = brzo_i2c_end_transaction();

   if (error != 0) {
    Serial.print("Brzo error : ");


But all I got was error nr4, which means: no communication. I even tried pulling the addr pin to high, so the address would change into 0x5B, but to no avail. I’m guessing that these cheap ccs811 sensors from aliexpress are just bogus (wouldn’t be the first time I get fake ic’s from aliexpress).

My testing setup got pretty messy by the way :smile:

My next project will be testing this sensor:

It’s a NDIR (nondispersive infrared sensor) co2 sensor, which should give more reliable CO2 readings.

Erik I was only able to get the CCS811 on my RPi. I have the Sparkfun BME280+CCS811 combo. I couldn’t get to work with their own ESP32. Didn’t try on 8266 NodeMCU.

I should correct my thoughts to badstraw. The BME680 has a great advantage that is compatibility around all platforms.

1 Like

Hmm, interesting, but there shouldn’t actually be any reason for it now to work on a esp8266 or arduino. Just to be sure, I now ordered one from adafruit, together with a bme680 and a SGP30 sensor (

I hope to get them all running together so that I can compare then and see wich one gives me the best results.

I did some work on the MH-Z14a, got it working on a arduino, now I want to get it working on a ESP8266 so that I can send the values via MQTT to home assistant

I now have the MH-Z14a working on a ESP8266 and am able to send over the values via MQTT to home assistant. Code sample here:

It was a bit tricky to get it running because the MH-Z14a required 5v, while the ESP8266 needs 3.3v.

I will soon report on the values I get out of it, they seem to be a bit lower than what the IAQ core-c is reporting.

I also got the CCS811 in from adafruit, so I hope I can soon compare the three.

I got some results, I nog had the IAQ-core-C, CCS811 and MH-Z14a running alongside for one day. If I put all of then together in one graph, it looks like this:


It’s interesting to see that the IAQ-core-C and CSS811 follow the same path, but the CCS811 is reporting a much higher value. The co2 values the CSS811 are reporting are way above what is considered to be healthy.
In this graph it looks like the MH-Z14a is not doing much, but when I only put that sensor in a graph, it looks like this:

if you look at it closely, you can see that it is the same pattern as the IAQ-core-C and CCS811, but with much lower values. This sensor also works in a very different way and can report lower values than the other 2 sensors.

Not sure what conclusion I can draw from these values, I think I just let them run for a few more days, while I wait for the bme680 and SGP30 sensors.

I did publish my code for the CCS811 here:

I will try your CCS811 code later the week. My CCS811 has a tendency to “crash”.
I was able to get the BME680 ruining with the BSEC (official bosh) code.
It is way more sophisticated than the other BME680 codes. Including the one for the home assistant.

On the Pi the C code runs flawlessly just need to figure it out how to mqtt the data from C.

For the Arduinos (ESP32 and ESP8266)

The setup is way easier on platformio. Just place the libalgobsec.a and add build_flags = -L/Users/username/Documents/PlatformIO/Projects/BSEC_BME680/lib/ -lalgobsec

I now got the BME680 and SGP30 sensors in too. I now have all 5 sensors running next to each other.
I made 2 sketches to run them on a ESP822 once more:

The BME680 is a interesting sensor, because it can also report temperature, humidity and pressure. It however doesn’t give a CO2 or eCO2 value, it just gives a resistance value, that you should somehow convert into a values that makes sense.

I will leave all 5 sensors running for a while now, see if I can make sense out of their output values and see which one is the most reliable.