Coder Social home page Coder Social logo

Reliability of measurements about ccs811 HOT 103 CLOSED

bfaliszek avatar bfaliszek commented on August 25, 2024 2
Reliability of measurements

from ccs811.

Comments (103)

maarten-pennings avatar maarten-pennings commented on August 25, 2024 8

Hi, I'm not sure what I should answer, you have many hidden questions :-)

The CCS811 does not require calibration. But it does need to be "burned-in". This means that after around 1 week the sensor is more stable. However, the internal controller knows about this burn in period and compensates. Especially firmware version 2.0.0 is improved here. Which fw do you have? The example ccs811basic prints it.

The CCS811 is a so-called MOX sensor. This class of sensors has a chemical reaction with the gases (an oxidation/reduction). But not all gasses react with the sensors. Most "Volatile organic compounds" react. This is the TVOC reading. But the sensor is insensitive for CO2. The trick is that the CO2 reading assumes the sensor is inside a building (iAQ - indoor air quality), and that humans are the (only) producer of CO2. So the gas sensor measures VOCs, assumes they are from humans, maps that to the amount of humans, and then maps that to the CO2 they would produce. So yes, TVOC and CO2 correlate.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 4

Hi @bfaliszek, you have two issues.

First of all, you notice that the two sensors give different readings. What you should know is (quoting data sheet) "metal oxide sensors do not give absolute readings". Yes they pretend with their CO2 and TVOC registers, but they don't. They measure the resistance of their metal oxide layer, and then check how much that deviates from normal resistance, and that deviation maps to a CO2/TVOC readout. The problem is with this normal resistance, quoting the data sheet again " The resistance RS varies from sensor to sensor (manufacturing variation), from use-case to use-case, and over time." Bottom line, all sensors give a different CO2/TVOC reading, but when it goes up it at least we know air got worse.

Second issue you bring up is the drop in readings after power cycling. This has a similar background. Again quoting the datasheet on the aspect that clean (normal) air resistance varies: " To mitigate this problem, the output of the sensor is normalized: RS is divided by RA. The value of RA is known as the baseline. RA cannot be determined by a one-time calibration; it is maintained on-the-fly in software". By power cycling, you effectively remove the clean air knowledge built up by the sensor: if you power a sensor on in bad air, it only has that as a a reference and considers that as clean.

See the section "Manual Baseline Correction" in the datasheet.

I did not yet put in support for baseline backup and restore in the driver...

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024 3

@maarten-pennings I just got a Chinese sensor CCS811 HDC1080. Do you know if I can upload a new firmware for this sensor?
ccs811-hdc1080-co2-sensor-module-temperature-and

I just uploaded the firmware to 2.0. Everything went without problems. CCS811 and HDC1080 works OK. I plan to compare the data from two Chinese CCS811 boards(one with HDC1080 and second without HDC1080)

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 3

Successful CCS811 firmware updates:

# Person When Board Host IDE
1 @maarten-pennings 2018 Dec 5 ams eval kit ESP8266 (Robotdyn) Arduino
2 @maarten-pennings 2018 Dec 7 CJMCU-811 ESP8266 (Robotdyn) Arduino
3 @bfaliszek 2018 Dec 17 CJMCU-811 ESP8266 Arduino
4 @rovale 2018 Dec 28 CJMCU-811 ESP32 (LOLIN D32) Arduino
5 @bertrik 2019 Jan 03 CJMCU-811 ESP8266 (d1 mini) platformio
6 @bfaliszek 2019 Jan 04 CCS811/HDC1080 ESP8266 Arduino

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 3

I also think it is confusing.

I believe the new firmware uses special algorithm at the early life of the sensor. When early life is over, it uses the standard algorithm. The firmware knows when early life is over by persistently storing the run time on the sensor. The special algorithm at early life is needed, because the chemicals in the sensor are not yet "baked" to stability. Again, all this is what I mentally model from the documentation.

Since the old firmware did not have this algorithm, it also did not store the run time.

So, the 2.0.0 firmware is good for fresh "non-baked" sensors. But if you would use it on a baked sensor, the firmware would (incorrectly) apply the special algorithm the first couple of days, giving suboptimal readings. However, after the first couple of days, the persistent timer reaches the end-of-early-life value and switches to the standard algorithm, so your readings will be good from then onwards.

I believe the 2.0.1 firmware sets the internal timer to maximum, so that the standard algorithm kicks in immediately. This is good for "baked sensors". For fresh sensors, the first couple of days you would get suboptimal readings, but from then on it is fine.

Conclusion, after running a couple of days, it doesn't matter which firmware you have.

from ccs811.

ullix avatar ullix commented on August 25, 2024 3

Oh, good to know that I am not beginning to hallucinate ;-)
Your answer sounds as if you were somehow involved with the manufacture(r) of the chip. Are you?

In my years working as physicist I had to deal with data of even a lower quality than what one gets with a mox sensor. That in itself is not a problem. Neither is the non-calibrationability of the sensor. But I expect some reasonable reproducibility, and meaningful values, not muddled with some marketing language!

Here are data from last overnight run. The room window - ~1m apart - was open during the night, no people or other warm blooded animals (a fly bugged me) were around, so from midnight to 8am the room had time to equilibrate to the outside. So look what I got:

image

The eTVOC never went below 300 (ppb?). My experience does not allow me to judge TVOC, but eCO2 is estimated based on the same resistance data, and eCO2 at the end of the night was never lower than 1700ppm!

No way! CO2 should have been near the 400ppm value for outside air. And as I had logged data every second, the sensor sure should has had time to stabilize.

Given that CO2 is so far off, I can only conclude that TVOC is also way off any relevant value.

One thing I noticed: in one of the datasheets an example was given referring to a "resistance of 350kOhm". I never see anything higher than 150kOhm on my chip. Is that still within a normal manufacturing range for these CCS811 chips?

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024 2

Yes. It worked on my Chinese board without a problem.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 2

Thanks for the info - gives confidence!

from ccs811.

rovale avatar rovale commented on August 25, 2024 2

Hello! This repository looks amazing, well documented! I will try the firmware update. Did you find any release notes for the new firmware?

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 2

Indeed. It will not be absolue readings, but at least the reading before and after the power cycle will be the same if you get the baseline before power down, and restore it after power up.

(and that is not yet in the driver ... so you have to add that yourself and mail it to me :-) )

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 2

Hi @bfaliszek, there is a new release of the driver, it has baseline get and set. Not yet tested.
Test should be:

  • sensor on for more than 20 min (run-in) in clean air, get baseline
  • take empty bottle and put drop of alcohol in
  • switch sensor off, put in bottle, and switch back on.
    Internal baseline is reset but no wait for run-in needed because sensor was only of some seconds
  • read tvoc, will be reported as none/clean air (because the sensor woke up in dirty bottle)
  • Do set baseline and read again tvoc, should now be very high.

Good luck - and if you test, please let me know.

from ccs811.

ullix avatar ullix commented on August 25, 2024 2

I have just started to use the CCS811 chip, running it on an ESP32 together with a BME280 (temp, press, humid). While the Maarten lib for the CSS811 works well, I am not sure I can give the same compliment to the chip. Similar doubts were already raised in this thread.

The analysis was created with my program GeigerLog https://sourceforge.net/projects/geigerlog/, GeigerLog pulled the data from the ESP via WiFi, and logged them. In the next graph the right-hand-side graph shows the time course of only the tracks for eCO2 (black) and TVOC (orange). The two tracks are clearly correlated.

image

The left graph plots all the data shown on the right as eCO2 data on the Y-axis, and TVOC data on the X-axis. It shows a two-phase correlation, perfectly linear in each, with a break at 1500ppm eCO2 . As the sensor cannot measure CO2, this value is derived from the TVOC value. So much for the magic of calculating eCO2; just a single multiplication and an 'if'.

Next I wanted to challenge the chip a little bit, and uncorked an empty (sniff ;-)) bottle of fine Single Malt Scotch next to the chip. The little lad might have liked it, but really couldn't take it. Next graph same as the first: right side: both tracks eCO2 and TVOC run into their limit.
image

The left side graph shows again completely linear correlation, beginning at the 1500ppm point, continuing up to the limit. According to the data sheet, the eCO2 limit is 32768ppm, and the TVOC limit is 29206. Both limits are reached exactly.

But note that when TVOC ends at 29206, eCO2 is only at about 15000ppm! It can go up for an additional 15000+ ppm. I very much doubt that this makes sense.

Has anyone ever seen any data showing that this almost trivial derivation of eCO2 from TVOC makes sense? I have not.

And also, I'd like to see data demonstrating that TVOC as reported is anywhere near any real value. It looks suspicious.

from ccs811.

ullix avatar ullix commented on August 25, 2024 2

This CCS811 chip is giving nothing but troubles; I will give up on it. Is it a principle defect of the chip? Is my chip defect? Is the lib defect? (I don't think so. At least I did not find any issues).

I bought other MOX chips to compare it with: a SGP30 also produces eTVOC and eCO2, but no resistance, and a BME680, which only delivers resistance, but neither eTVOC nor eCO2. They offer a closed source blob to install, which is claimed to deliver some "Air Quality Index" (not tried yet).

With all 3 connected to my ESP32 at the same time, I got these results for overnight or daylong runs:
image

The BME680 resistance is around 400kOhm (divided by 5 for plotting), that of the CCS811 is only 55kOhm. This in itself is not a problem, but look at this garden fence of data. The inset shows an enlargement of one of the fence posts, which appear consistently every ~4.3minutes, and change the resistance by almost 20%!

Oh, maybe I should set the baseline, so here is the baseline overnight:
image
Which baseline should I pick? There are more than 64000 to choose from. Note the almost constant decrease from shortly before midnight for the next multiple hours, when everybody in the house was fast asleep, far away from the sensor.

I have really no sense of what the eTVOC should be. But I do have a sense for the CO2 level. Since all sensors CANNOT measure CO2, they estimate it from the eTVOC data, assuming some kind of a standard human. So, CO2 stands as a proxy for eTVOC. And in reverse conslusion: if CO2 is way off, then TVOC is also!

To get some better feeling at least for CO2 I purchased a little NDIR based CO2 monitor. A software for logging is on my Sourceforge site: https://sourceforge.net/projects/minimon/ . Its outside value of 430 ppm seems to be surprisingly good (expect anything greater than but near 416), and an inside value near my desk of 500 ... 700 ppm is at least consistent with expectations for a single person in a mid size room. What are the sensors showing:

image

The SGP30 gives eCO2 between 400 and 500 ppm. Seems like a bit on the low side, but at least the curve is smooth.

The CCS811 now gives the inverted garden fence. Now the fence poles dip down to 500...700ppm, which is exactly what I would expect, but the other end goes up to 1400 ppm, which is improbable.

Overall, this chip so far produces utter nonsense. If anyone finds a problem in the lib, I'll try again. But otherwise this is my end to the adventure with the CCS811.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 1

Thanks for the compliments.
No, I didn't find any release notes of the firmware... (pity).
Let me know which board you have and whether the update works.
I now have a 100% success rate but only for two boards :-)

from ccs811.

rovale avatar rovale commented on August 25, 2024 1

Hi Maarten, I flashed only one making your success rate is 3 out of 3, still 100%!

I was a bit puzzled by your ESP32 remark. Are you saying that Arduino with ESP32 and CCS811 version 1.0.0 does not work?

No, I wanted to tell you that your CSS811 library doesn't work with the 1.0.0 release of the ESP32 Arduino Core (https://github.com/espressif/arduino-esp32). It does work with the latest github master.

I want to start using the latest master anyway, because the 1.0.0 release has some trouble with WiFi disconnects which might have been solved in the upcoming 1.1.0 release. I see there are some commits related to that.

I really like TinyTronics. I had some mail conversations with Loek over the years, he is always so helpful.

from ccs811.

bertrik avatar bertrik commented on August 25, 2024 1

If you run the ccs811basic.ino example and open a serial console at 115200 bps, you should see it report the 'application version' after rebooting. If this is lower than 2.0 you can flash it with a newer firmware. If it's already updated to 2.0, the firmware update sketch does nothing (skips the update).

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024 1

I did the test. Saving the baseline works.
A few days ago I got MH-Z19, so I decided to compare CO2 measurements.
I assumed that the measurements from CCS811 will be slightly different (eCO2 vs. CO2), but the trends will be maintained and when the values from MH-Z19 will increase, the values from CCS811 will also grow. However, it did not happen. I put the CCS811 in clean air for 30 minutes to keep the right baseline. Then I changed the code so that ESP8266 would restart every 15 minutes (not to save the new baseline). Here are the results from the last 48 hours.

  • CCS811 (Chinese PCB, FW 2.0) – CJMCU-811 – Green
  • MH-Z19 - Yellow
    eco2vsco2

from ccs811.

bertrik avatar bertrik commented on August 25, 2024 1

Perhaps this is a person wearing perfume/aftershave walking past the sensor and then opening a door. The perfume would increase the TVOC reading, while opening the door would decrease the CO2. Just a guess...

BTW, I'm pretty sure that the MH-Z19 is in essence also a kind of relative sensor. It also uses an automatic baseline calibration algorithm to determine the lowest CO2 reading over 1 or 2 days and adjust that to 400 ppm (the assumed outdoor value). Here are some images of the insides of a MH-Z19: https://forum.mysensors.org/topic/7761/mh-z19-teardown and it looks like it basically just has a single infrared light path, with the light going from the light source, through the gas cell, then reflected against a curved mirror and finally through an infrared filter onto a photo detector.

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024 1

The bad air builds up from around 16:00 till 9:00, where it sharply drops to clean air. Is this sensor in an apartment, where people come home at 16:00, the sleeping room is connected to the living, and you ventilate at 9:00 when you go to work

That's exactly what it is. Readings are made in the bedroom. The decrease of readings in the case of MH-Z19 means ventilation of the room.

Did I understand that you restart the CCS811 without baseline save and restore? That does not sound wise.

I restart CCS811 and load the baseline (the last one was made is the one with clean air). That's why I thought that CCS811 will show similar trends as MH-Z19.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 1

I restart CCS811 and load the baseline

You say the baseline. So a baseline you once made, and then restored every time?
If that would work, than that would be called calibration, and it would be done once.
The whole problem is that the baseline changes (due to chemical reactions in the mox transducer).
That is why the chip keeps track of the baseline.

By the way, the CCS811 also has a "Conditioning Period (Run-In)" (see the section of that name in the datasheet), which essentially means that the sensor is only stable after 20min.

So, I would suggest: let it run, don't restart it.
If you want to restart, take longer on-periods (>> 20min); restore baseline after the run-in (so after 20 min), let it run for a while, and back-up baseline before power cycling.

from ccs811.

hmax42 avatar hmax42 commented on August 25, 2024 1

flashing worked for me.
i used arduino and an esp8266 with the purple cjmcu811 board.

from ccs811.

ardatekin avatar ardatekin commented on August 25, 2024 1

Finally I come to conclusion that the sensor and MCU should be wired to each other by soldering on a perfboard or pcb rather than on breadboard in order to read the most reliable results.
I have measured that there is a variable amount of resistance between the pins of sensor and MCU such as 15-24ohm.
And I also replaced esp32 with NodeMCU which looks more stable in my tests.
Resetting the i2c bus line with I2Cbus_clear when getting CCS811_ERRSTAT_I2CFAIL would also prevent getting more errors in operation time. (https://github.com/maarten-pennings/I2Cbus)

Sharing some screens from my environment. Thank you very much Maarten and bfaliszek

20190807_125607

20190821_175710

CO2_graphics_2

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024 1

I do not fully understand. When your system is in deep sleep mode, what is the mode of the CCS811? Is it (power) off, is it (power) on but idle, or is it (power) on and measuring in 10sec mode (mode 2)?

The bad news for you: MOX sensors do not mix well with low power. The reason is that a MOX sensor runs a (reversible) chemical process (oxidation), and in order to do so, it needs to heat the reaction chamber. Fortunately the chamber is small, but the temperature is high (think 300C). The cost of this is of course power for the heater.

There is more bad news. The chamber needs to be in balance (the chemical process needs to be at equilibrium). Getting in balance takes time; the datasheet calls this the "run-in period" and claims it takes 20 minutes (!) "After writing to MEAS_MODE to configure the sensor in mode 1-4, run CCS811 for 20 minutes, before accurate readings are generated."

So, what does this all mean: You have to switch on the sensor, you have to wait 20 min and only then you have accurate readings. And all that time the sensor eats power.

The good news is that this sensor has a special low-power mode: mode 3 (60 seconds). It pulses the heater thereby consuming less power (1.2mW vs 46mW), but still having an equilibrium. Maybe a different equilibrium then when the heater is always on, but the internal processing knows about the mode, and presumably adapts the numbers.

Switching to a different MOX chip will not help (significantly) - the heater is part of MOX technology.

Hope this helps you.

from ccs811.

nordicp avatar nordicp commented on August 25, 2024 1

I benchmarked various NDIR-CO2 sensors and all of them performed ok. The more expensive ones just had a smaller device to device variation and less noise which might not be of importance for the hobbyist. I ran the low-cost Winsen MH-Z19 at home and results were just fine. I also like the small size. The smallest CO2 sensor available on breakout is SCD40 (photo acoustic), it comes with an integrated rh/T sensor. I found this sensor to be influenced by air flow and cannot recommend it for installation into an air duct. This might be true for other "classical" CO2 sensors, too. NDIR-CO2 sensors should be protected from air stream by a housing or filter.
Please note that almost all available NDIR-CO2 sensors run an automatic baseline correction, setting the lowest signal value to the lowest value detected over a period of several days. This means they will adjust to a high CO2 level and get off calibration. This might be dangerous for certain applications e.g. fermentation cellars. Such applications require an absolute (calibrated) CO2 sensor (dual beam), which is more expensive but not needed for a standard indoor air quality application.

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024

Thank you for the comprehensive information. Especially about the correlation of TVOC and CO2.

I have a new CCS811 sensor. I just uploaded the firmware - https://github.com/maarten-pennings/CCS811/tree/master/examples/ccs811flash

In a few days I will send a new screenshot with measurements.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

So the "flashing of new firmware example" worked? I only had one Chinese board with old firmware, so I could not do much testing.

from ccs811.

rovale avatar rovale commented on August 25, 2024

Hi Maarten! Success! 👍 3 out of 3!

I also got a Chinese one, I guess. I bought it at a web shop close to you: https://www.tinytronics.nl/shop/en/sensors/temperature-air-humidity/ccs811-air-quality-sensor

I flashed it with an ESP32, a LOLIN D32. Your library does not work with the 1.0.0 release of https://github.com/espressif/arduino-esp32 but it does work with the latest master.

Again, thanks a lot! I will definitely use your library for my IoT project.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Thanks, so now a flash success rate of 5 out of 5! And you flashed with ESP32, also new!

I was a bit puzzled by your ESP32 remark. Are you saying that Arduino with ESP32 and CCS811 version 1.0.0 does not work?

When I had my Chinese CCS811 (1.0.0) board attached to an ESP8266 on Arduino it didn't work the first time. The 1.0.0 firmware had an incompatibility with my driver, so I added some driver code to support 1.0.0 sensors. I would expect my updated driver to work with 1.0.0 ccs811s irrespective of the host (ESP8266 or ESP32). Do you know why ESP32 doesn't work with 1.0.0?

And yes I know TinyTronics, I just got some stuff there, picking it up by bike :-)

from ccs811.

bertrik avatar bertrik commented on August 25, 2024

A bit off-topic, but I just like to mention that I also just successfully flashed a CJMCU-811 board from 1.1 to 2.0. I compiled it using platformio, I ran it on a wemos d1 mini (ESP8266).

Also I just noticed that the upper range in TVOC appears much larger now. With the sparkfun library I tried earlier, it saturated at a value of 1156. But now with this library and with the updated firmware, it appears it can go much higher. It appears that it's the firmware update that fixed the upper value issue.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Thanks @bertrik for logging the result (platformio is a new environment, so good to know).

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024

@maarten-pennings I just got a Chinese sensor CCS811 HDC1080. Do you know if I can upload a new firmware for this sensor?
ccs811-hdc1080-co2-sensor-module-temperature-and

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024

Measurements from the last 12 hours. Performed every minute. Sensors connected to two different ESP8266. Identical code. I do not understand these differences in measurements. Before 12:00 o'clock I turned off and turned on the ESP8266 again. The data after restart is much lower than before. Even after a few minutes of sensor work.

  • CCS811 (Chinese PCB, FW 2.0) – CJMCU-811 – Yellow
  • CCS811+ HDC1080 (Chinese PCB, FW 2.0) – CJMCU-8118 – Green

PS: WAK pin connected to GND.

zrzut ekranu 2019-01-7 o 12 29 08

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024

@maarten-pennings
Many thanks for the answer. I am getting ready to read the datasheet.

If I understand correctly, if I would like to get more "absolute readings", then I would have to restore the Baseline value from perfectly clean air, after each reboot of the sensor.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Thanks for checking the baseline save and restore.

The MH-Z19 is an absolute CO2 sensor, the CCS811 is a relative VOC sensor.
That is hard to compare. They really measure different things.
By the way, strange to see that several CCS811 spikes coincide with MH-Z19 valleys.

Your MH-Z19 readings are, for me, counter intuitive. The bad air builds up from around 16:00 till 9:00, where it sharply drops to clean air. Is this sensor in an apartment, where people come home at 16:00, the sleeping room is connected to the living, and you ventilate at 9:00 when you go to work... ?? Also, CO2 ppm levels above 1000 start to induce health problems (drowsiness, headaches).

Did I understand that you restart the CCS811 without baseline save and restore? That does not sound wise. Assuming your air indeed gets worse and worse (as the MH-Z19 indicates), the CCS811 would assume every 15 minutes - when it is re-powered - that the then measured air is clean air. So restarting a CCS811 is a good recipe for getting a flat line (with incidental spikes within the 15min periods).

from ccs811.

bertrik avatar bertrik commented on August 25, 2024

I've been logging both the reported TVOC en eCO2 level on a CCS811 with up-to-date firmware. My ESP8266 software uses a BME280 to correct for humidity and temperature. It saves the baseline value once every hour (and restores it on startup). I saw a sudden drop last night in both levels that I can't explain in terms of sudden changes air in quality.

I guess this is the automatic baseline algorithm adjusting itself. Are you also seeing this? The levels do seems pretty constant (not continually increasing or anything like that). Possibly this happened about 25 hours after re-powering it. The peak happened because I was teasing the sensor a bit, but it seemed to recover to its previous value.

https://imgur.com/trGEgB3

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Yeah, i also get that, typically in 24h intervals.

from ccs811.

pashar1 avatar pashar1 commented on August 25, 2024

Have anyone figured out how to make both HDC1080 and CCS810 to work together...

it looks like as soon as you initialize ccs811 HDC1080 no longer works...

i get correct readings from HDC1080 prior to ccs811.begin but after it's 125C and 100%

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Hi @pashar1, from code review, I see no reason why ccs811.begin would break hdc1080. I have no hdc1080.

What you could do to pinpoint the problem is to comment out more and more sections in ccs811.begin to see what breaks hdc1080.

from ccs811.

pashar1 avatar pashar1 commented on August 25, 2024

so far I was not able to pinpoint where...

here is sketch I have put... I have tried with ClosedCube_HDC1080 library and with example from TI just using i2c


#include <Wire.h>
#include <ccs811.h>


CCS811 ccs811(D4);

void setup() {
  uint16_t eco2, etvoc, errstat, raw;
  double temperature;
  double humidity;
   //Initialize I2C Communication
  Serial.begin(115200);
  Serial.println("");
  Serial.println("setup: Starting HDC1080 basic demo");
  
  Wire.begin();
  
  //Configure HDC1080
  Wire.beginTransmission(0x40);
  Wire.write(0x02);
  Wire.write(0x90);
  Wire.write(0x00);
  Wire.endTransmission();

  //Delay for Startup of HDC1080
  delay(20);



  humidity = readSensor(&temperature);

  //Print the current temperature to the right of the label

  Serial.print("T="); Serial.print(temperature);


  Serial.print(" RH="); Serial.println(humidity);

  Serial.println (" ccs811.begin " );
  ccs811.set_i2cdelay(50); // Needed for ESP8266 because it doesn't handle I2C clock stretch correctly
  bool ok = ccs811.begin();
  if ( !ok ) Serial.println("setup: CCS811 begin FAILED");

     
  delay(100);

  humidity = readSensor(&temperature);

  //Print the current temperature to the right of the label

  Serial.print("T="); Serial.print(temperature);


  Serial.print(" RH="); Serial.println(humidity);

  delay(100);
  
  ok = ccs811.start(CCS811_MODE_1SEC);
  if ( !ok ) Serial.println("init: CCS811 start FAILED");

  delay(10000);

  humidity = readSensor(&temperature);

  //Print the current temperature to the right of the label

  Serial.print("T="); Serial.print(temperature);


  Serial.print(" RH="); Serial.println(humidity);

  ccs811.read(&eco2, &etvoc, &errstat, &raw);

    Serial.print("\neCO2 concentration: ");
    Serial.print(eco2);
    Serial.print(" ppm");

    Serial.print("\nTVOC concentration: ");
    Serial.print(etvoc);
    Serial.println(" ppb");

    delay(100);
    
    humidity = readSensor(&temperature);

    Serial.print("T="); Serial.print(temperature);


    Serial.print(" RH="); Serial.println(humidity);


}

void loop() 
{
 
  
}

double readSensor(double* temperature)
{
  //holds 2 bytes of data from I2C Line
  uint8_t Byte[4];

  //holds the total contents of the temp register
  uint16_t temp;

  //holds the total contents of the humidity register
  uint16_t humidity;
  
  //Point to device 0x40 (Address for HDC1080)
  Wire.beginTransmission(0x40);
  //Point to register 0x00 (Temperature Register)
  Wire.write(0x00);
  //Relinquish master control of I2C line
  //pointing to the temp register triggers a conversion
  Wire.endTransmission();
  
  //delay to allow for sufficient conversion time
  delay(20);
  
  //Request four bytes from registers
  Wire.requestFrom(0x40, 4);

  delay(1);
  
  //If the 4 bytes were returned sucessfully
  if (4 <= Wire.available())
  {
    //take reading
    //Byte[0] holds upper byte of temp reading
    Byte[0] = Wire.read();
    //Byte[1] holds lower byte of temp reading
    Byte[1] = Wire.read();
    
    //Byte[3] holds upper byte of humidity reading
    Byte[3] = Wire.read();
    //Byte[4] holds lower byte of humidity reading
    Byte[4] = Wire.read();

    //Combine the two bytes to make one 16 bit int
    temp = (((unsigned int)Byte[0] <<8 | Byte[1]));

    //Temp(C) = reading/(2^16)*165(C) - 40(C)
    *temperature = (double)(temp)/(65536)*165-40;

   //Combine the two bytes to make one 16 bit int
    humidity = (((unsigned int)Byte[3] <<8 | Byte[4]));

    //Humidity(%) = reading/(2^16)*100%
    return (double)(humidity)/(65536)*100;
  }
}

here is output:

setup: Starting HDC1080 basic demo
T=24.35 RH=46.97
 ccs811.begin 
T=24.35 RH=0.00
T=24.35 RH=0.00

eCO2 concentration: 400 ppm
TVOC concentration: 0 ppb
T=24.35 RH=0.00

from ccs811.

regnerus avatar regnerus commented on August 25, 2024

Thanks for the awesome flashing sketch, just flashed two CCS811 / HDC1080 modules from Aliexpress (https://www.aliexpress.com/item/32871695408.html) using a WEMOS D1. 😄

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Hi @regnerus, thanks for letting me know. I have added your result to the table.

from ccs811.

ardatekin avatar ardatekin commented on August 25, 2024

Hi Maarten

I use CCS811-HDC1080 Module with DOIT ESP32 DEVKIT V1 developer board to measure the CO2 level with the library you shared with us.
Here is the module I bought,
https://www.banggood.com/CCS811-HDC1080-Carbon-Dioxide-CO2-Temperature-And-Humidity-Sensor-VOCs-Air-quality-Monitor-Sensor-Module-Winder-p-1428378.html

Modules wired on breadboard is below

20190716_143145

I have upgraded the firmware to 2.0 version as you have explained in CCS811 flash page.

I am not sure about the ppm values found by this electronic set. Please see the data I have shared in ccs811_hdc1080_eco2_etvoc_data.txt file.

ccs811_hdc1080_eco2_etvoc_data.txt

When I restart the ESP32, I receive around 400ppm in my office but after a while ppm values increases too much.
I had measured same office room with MH-Z19B sensor and had found about 400-600ppm range in my 2 weeks test.

Here is the code

air_quality_esp32.txt

My questions are,

  • Should I rely on this results or do I have a right implementation with the electronic set and written code? I need your comments about that.

  • When I enable printSerialNumber() function, the application crashes, abort() is called and ESP32 restarts and this loops forever. Here is what I see when I enable the printSerialNumber function

17:24:53.819 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
17:24:53.819 -> configsip: 0, SPIWP:0xee
17:24:53.819 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
17:24:53.819 -> mode:DIO, clock div:1
17:24:53.819 -> load:0x3fff0018,len:4
17:24:53.819 -> load:0x3fff001c,len:928
17:24:53.819 -> ho 0 tail 12 room 4
17:24:53.819 -> load:0x40078000,len:8424
17:24:53.819 -> ho 0 tail 12 room 4
17:24:53.819 -> load:0x40080400,len:5868
17:24:53.819 -> entry 0x4008069c
17:24:53.965 ->
17:24:53.965 -> setup: Starting CCS811 basic demo
17:24:53.965 -> setup: ccs811 lib version: 10
17:24:53.965 -> setup: hardware version: 12
17:24:53.965 -> setup: bootloader version: 1000
17:24:53.965 -> setup: application version: 2000
17:24:53.965 -> Device Serial Number=FFFF-FFFF-FFFF
17:24:54.019 ->
17:24:54.019 -> Stack smashing protect failure!
17:24:54.019 ->
17:24:54.019 -> abort() was called at PC 0x400d70b0 on core 1
17:24:54.019 ->
17:24:54.019 -> Backtrace: 0x40089a8c:0x3ffb1ee0 0x40089cb9:0x3ffb1f00 0x400d70b0:0x3ffb1f20 0x400d0d01:0x3ffb1f40 0x400d0dc1:0x3ffb1f80 0x400d2e2f:0x3ffb1fb0 0x40085aa1:0x3ffb1fd0
17:24:54.019 ->
17:24:54.019 -> Rebooting...
17:24:54.019 -> ets Jun 8 2016 00:22:57
17:24:54.019 ->
17:24:54.019 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
17:24:54.019 -> configsip: 0, SPIWP:0xee
17:24:54.019 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
17:24:54.066 -> mode:DIO, clock div:1
17:24:54.066 -> load:0x3fff0018,len:4
17:24:54.066 -> load:0x3fff001c,len:928
17:24:54.066 -> ho 0 tail 12 room 4
17:24:54.066 -> load:0x40078000,len:8424
17:24:54.066 -> ho 0 tail 12 room 4
17:24:54.066 -> load:0x40080400,len:5868
17:24:54.066 -> entry 0x4008069c
17:24:54.219 ->
17:24:54.219 -> setup: Starting CCS811 basic demo
17:24:54.219 -> setup: ccs811 lib version: 10
17:24:54.219 -> setup: hardware version: 12
17:24:54.219 -> setup: bootloader version: 1000
17:24:54.219 -> setup: application version: 2000
17:24:54.219 -> Device Serial Number=FFFF-FFFF-FFFF
17:24:54.219 ->
17:24:54.219 -> Stack smashing protect failure!
17:24:54.266 ->
17:24:54.266 -> abort() was called at PC 0x400d70b0 on core 1
17:24:54.266 ->
17:24:54.266 -> Backtrace: 0x40089a8c:0x3ffb1ee0 0x40089cb9:0x3ffb1f00 0x400d70b0:0x3ffb1f20 0x400d0d01:0x3ffb1f40 0x400d0dc1:0x3ffb1f80 0x400d2e2f:0x3ffb1fb0 0x40085aa1:0x3ffb1fd0
17:24:54.266 ->
17:24:54.266 -> Rebooting...
17:24:54.266 -> ets Jun 8 2016 00:22:57
17:24:54.266 ->
17:24:54.266 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
17:24:54.266 -> configsip: 0, SPIWP:0xee
17:24:54.266 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
17:24:54.266 -> mode:DIO, clock div:1
17:24:54.266 -> load:0x3fff0018,len:4
17:24:54.266 -> load:0x3fff001c,len:928
17:24:54.266 -> ho 0 tail 12 room 4
17:24:54.266 -> load:0x40078000,len:8424
17:24:54.320 -> ho 0 tail 12 room 4
17:24:54.320 -> load:0x40080400,len:5868
17:24:54.320 -> entry 0x4008069c
17:24:54.420 ->
17:24:54.420 -> setup: Starting CCS811 basic demo
17:24:54.420 -> setup: ccs811 lib version: 10
17:24:54.467 -> setup: hardware version: 12
17:24:54.467 -> setup: bootloader version: 1000
17:24:54.467 -> setup: application version: 2000
17:24:54.467 -> Device Serial Number=FFFF-FFFF-FFFF
17:24:54.467 ->
17:24:54.467 -> Stack smashing protect failure!
17:24:54.467 ->
17:24:54.467 -> abort() was called at PC 0x400d70b0 on core 1
17:24:54.467 ->
17:24:54.467 -> Backtrace: 0x40089a8c:0x3ffb1ee0 0x40089cb9:0x3ffb1f00 0x400d70b0:0x3ffb1f20 0x400d0d01:0x3ffb1f40 0x400d0dc1:0x3ffb1f80 0x400d2e2f:0x3ffb1fb0 0x40085aa1:0x3ffb1fd0
17:24:54.520 ->
17:24:54.520 -> Rebooting...
17:24:54.520 -> ets Jun 8 2016 00:22:57
.........
.........

  • When I enable the code for HDC1080 module I read similar values that pashar1 user shared in this thread

Temperature 125C and Humidity 100%

and sometimes correct temp and hum values are written on logs. This may not be the scope of this thread but I would like to know if you also have any comments about this case.

Kind Regards,
Arda

from ccs811.

bfaliszek avatar bfaliszek commented on August 25, 2024

@ardatekin to fixed HDC1080 125/100 problem, check this link https://github.com/closedcube/ClosedCube_HDC1080_Arduino/pull/8/commits/724a233c76da13d4e559262eb6eeaa5037d33f09 and add Wire.begin(HDC1080_SDA, HDC1080_SCL); and of course #define HDC1080_SDA 18 #define HDC1080_SCL 19
you can of course change the pins to other.

from ccs811.

theoroborus avatar theoroborus commented on August 25, 2024

Hello,

Using VSC and PIO, I was returned errors on the CCS811_SW000246_1-00.h file, but was possibly my fault as I'm quite new to that IDE. So I used the Arduino IDE and it worked like a charm. Thank you so much maarten-penning !

I also observed that the upper boundaries are higher now.

It was so interesting to read about other experiences. I wasn't aware about the baseline, will sure use the set_baseline.

By placing the sensor just above a drop of alcoolic gel, I sometimes obtain this :
http://image.noelshack.com/fichiers/2019/33/5/1565966769-values.png

I wonder why the sensor goes that crazy. The value is always the same when it happen :).

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

You mean the value 4294934528?
That is a funky value: it starts with 17 ones when you write it in binary,
I'm wondering whether that is an I2C line problem (SDA stuck hi) or an internal overflow.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

I'm glad you got it working.
Your project looks good!

from ccs811.

jarsiv avatar jarsiv commented on August 25, 2024

Thank you @maarten-pennings !

I got ESP32 Lolin and chinese CCS881 (CJMCU-811 ? ) on yeasterday. After couple hours it was running.
I also success to update firmware to V2.0 with Arduino.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Good work @jarsiv!

from ccs811.

ciphercore avatar ciphercore commented on August 25, 2024

Updated my CCS811 (CJMCU-811) from Aliexpress from App Version 1.1 -> 2.0 (Arduino Uno)

Thank you @maarten-pennings and everyone else in this thread

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Hi @ciphercore thanks for the feedback, I added your success to the table https://github.com/maarten-pennings/CCS811/blob/master/examples/ccs811flash/README.md

from ccs811.

astappiev avatar astappiev commented on August 25, 2024

Updated my CJMCU-811 from 0x1100 to version 0x2001 successfully (yes, there is a new file on AMS website). Thanks for the library @maarten-pennings.

They even added a changelog now

2-0-1      Firmware build including all 2-0-0 features accept management of the burn in period          

2-0-0      MOX sensor need a burn-in period of several days of operation from first power on before 
                 eCO2 and TVOC readings stabilize. The burn-in period is now managed so that stable 
                 readings are available after only 60 minutes of operation after first power on
           Extend eCO2 maximum output value to 64000 ppm
           Extend TVOC maximum output value to 64000 ppm
           Removed NTC functionality. Pin 8 not measured and left undriven
           Added "Internal_State" variable to the command register map
           Improved the algorithm which computes eTVOC and eCO2 

1-1-0      Initial Version

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

(yes, there is a new file on AMS website)

No, 2.0.0 and 2.0.1 are the same firmware.

See the readme:

The version of firmware to use depends on the usage status of the device.
New fresh sensors use firmware 2-0-0
Sensors run for a number of days use firmware 2-0-1

from ccs811.

astappiev avatar astappiev commented on August 25, 2024

from ccs811.

nicoolaro avatar nicoolaro commented on August 25, 2024

(yes, there is a new file on AMS website)

No, 2.0.0 and 2.0.1 are the same firmware.

See the readme:

The version of firmware to use depends on the usage status of the device.
New fresh sensors use firmware 2-0-0
Sensors run for a number of days use firmware 2-0-1

So i burned chip for 24hours with old 1.2 version, i just reflashed with your 2.0 version, should i waited for new 2.0.1 as stated in AMS website or should i keep using your version?
A bit confused now, thanks

from ccs811.

nicoolaro avatar nicoolaro commented on August 25, 2024

Gotcha, no concerns then.

from ccs811.

YL3CL avatar YL3CL commented on August 25, 2024

Hello! I want to consult. We use a sensor (version 2.0.0) in a system with a deep sleep mode. The sensor is not initialized. Once every 10 minutes we take measurements. We initialize the sensor to the measurement mode once every 10 seconds. We make several measurements, at least five (values ​​are less - we do not get the value IAQ_ECO2 at all). Then de initialization and sleep until the next cycle. General indications obtained during the measurement process are far from expected. If you start the sensor in mode 3, we do not fit into the energy budget, but the readings are satisfactory. Next option: 10 minutes in mode 0, then several measurements in mode 3, then mode 0 for 10 minutes. And this also does not help to get real measurements. Plus - in mode 0, there is also an unacceptable consumption. Question - how to use the sensor in deep sleep mode?

from ccs811.

YL3CL avatar YL3CL commented on August 25, 2024

Hello,
The sensor in standby (sleep) mode is not initialized. In this mode, the lowest consumption is observed. When the system wakes up, I put it into mode 2 (10 sec) and wait for 5..7 measurement cycles. Then I put the sensor into sleep mode (reset). And this happens every 10 minutes.
Based on your description of the sensor, you need to do a measurement cycle in mode 3 (60 seconds) for at least 20. Then do a longer sleep mode to satisfy the energy consumption budget.

from ccs811.

Roelski avatar Roelski commented on August 25, 2024

Succesfully upgraded sensor board with the HDC1080.

Now using esp32 with built in oled. Displays every 2 sec on display, and posts every minute to MQTT.
Still looking for a way to save and restore the mentioned baseline values in a controlled manner in case of power outage or reset of the board.

(Not sure why my code isnt interpreted as code?!? How to fix?! -> tripple quotes!)

For those interested:


// CJMCU-8128 CCS811 + HDC1080
// Wemos Lolin oled builtin.
// sda/scl pin 5,4
// Display address 0x3C
// pin 5 -> SDA
// pin 4 -> SCL
// VCC   -> VCC
// GND   -> GND
// Hint: show all mqtt topics:  mosquitto_sub -h 192.168.2.7 -v -t '#' 

#include <SparkFunCCS811.h>     //Click here to get the library: http://librarymanager/All#SparkFun_CCS811
#include <ClosedCube_HDC1080.h> //Click here to get the library: http://librarymanager/All#ClosedCube_HDC1080


// #include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <PubSubClient.h>
#include <WiFi.h> 

// esp32:
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(128, 32, &Wire, OLED_RESET);

//#define CCS811_ADDR 0x5B  //Default I2C Address
#define CCS811_ADDR 0x5A    //Alternate I2C Address

CCS811 myCCS811(CCS811_ADDR);
ClosedCube_HDC1080 myHDC1080;

uint16_t eco2,etvoc;
double temp,hum;

// Update these with WiFi network values
const char* ssid       ="yourSSIDhere"; 				//  your network SSID (name)
const char* password   ="yourwifipassword"; 			// your network password
const char* mqtt_server="192.168.2.7"; 			//your mqtt server ip
#define OUT_topic_eco2 "kamer/sensor1/eco2"  	// eco2 topic
#define OUT_topic_tvoc "kamer/sensor1/tvoc"  	// tvoc topic
#define OUT_topic_temp "kamer/sensor1/temp"  	// temp topic
#define OUT_topic_hum "kamer/sensor1/hum"  		//humidity topic
WiFiClient espClient;
PubSubClient client(espClient); 

long now=0;
long L5min=0;
long L5sec=0;

void setup() {  
  Serial.begin(115200);

 Serial.print("setup: I2C ");
  Wire.begin(5,4); // esp32 wemos  lolin

	// Default settings: 
	//  - Heater off
	//  - 14 bit Temperature and Humidity Measurement Resolutions
  myHDC1080.begin(0x40); 
  Serial.print("HDC1080 Manufacturer ID=0x");
  Serial.println(myHDC1080.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments
  Serial.print("Device ID=0x");
  Serial.println(myHDC1080.readDeviceId(), HEX); // 0x1050 ID of the device

  Serial.println("Start CCS811");

  if (myCCS811.begin() == false)
  {
    Serial.print("CCS811 error. Please check wiring. Freezing...");
    while (1)
      ;
  }
    Serial.println("Start SSD1306");

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  } 

  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  } 
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());  

// MQTT
  client.setServer(mqtt_server, 1883); 
         
 Serial.println("Show display");

  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(500);

  // Clear the buffer.
  display.clearDisplay();
  display.display();
  delay(100); 

  Serial.println("IO test");

  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);

  Serial.println("End setup.");    

}


void loop() {
      if (!client.connected()) {
        reconnect();
       }
      client.loop();

  now = millis();
  if (now - L5sec > 2000) // 2 sec (was 5sec. too lazy to rename variable)
    {
      L5sec = now;
          
      display.setCursor(0,0);
      display.clearDisplay();

      //Check if data is ready
      if (myCCS811.dataAvailable())
      {
        //If so, have the sensor read and calculate the results.
        //Get them later
        myCCS811.readAlgorithmResults();
  	    eco2=myCCS811.getCO2();
    	etvoc=myCCS811.getTVOC();
    	temp=myHDC1080.readTemperature();
      	hum=myHDC1080.readHumidity();

        Serial.print("eCO2: ");
        Serial.print(eco2);
        Serial.print(" ppm, TVOC: ");      
        Serial.print(etvoc);
        Serial.print(" ppb, Temp:");
        Serial.print(temp);
	    Serial.print(" C, Hum:");
        Serial.print(hum);
        Serial.println(" %rel");

        display.print("eCO2: ");
        display.print(eco2);
        display.println(" ppm");
  
        display.print("TVOC: ");
        display.print(etvoc);
        display.println(" ppb");
  
        display.print("Temp: ");
        display.print(temp);
        display.println(" C");
  
        display.print("Hum: ");
        display.print(hum);
        display.println(" %rel");
  	  
        display.display();
  
        //compensating the CCS811 with humidity and temperature readings from the HDC1080
        myCCS811.setEnvironmentalData(myHDC1080.readHumidity(), myHDC1080.readTemperature()); 
  
        if (now - L5min > 60000) // 1 min (was 5min. too lazy to rename variable)
         {
           L5min = now;
 //           char buffer [sizeof(unsigned int)*8+1];
 //           char * eco2_s = (char *) utoa(eco2,buffer,10);
 //           char * etvoc_s = (char *) utoa(etvoc,buffer,10);
 //           client.publish(OUT_topic_eco2, eco2_s, true); 
 //           client.publish(OUT_topic_tvoc, etvoc_s, true); 
  Serial.println("Start publish MQTT");    
            client.publish(OUT_topic_eco2, String(eco2).c_str(), true); 
            client.publish(OUT_topic_tvoc, String(etvoc).c_str(), true); 
            client.publish(OUT_topic_temp, String(temp).c_str(), true); 
            client.publish(OUT_topic_hum, String(hum).c_str(), true); 
  Serial.println("End publish MQTT");    
        }

    
       }
       else if (myCCS811.checkForStatusError())
       {
          printSensorError();
       }
      } // 5sec loop
}

//printSensorError gets, clears, then prints the errors
//saved within the error register.
void printSensorError()
{
  uint8_t error = myCCS811.getErrorRegister();

  if (error == 0xFF) //comm error
  {
    Serial.println("Failed to get ERROR_ID register.");
  }
  else
  {
    Serial.print("Error: ");
    if (error & 1 << 5)
      Serial.print("HeaterSupply");
    if (error & 1 << 4)
      Serial.print("HeaterFault");
    if (error & 1 << 3)
      Serial.print("MaxResistance");
    if (error & 1 << 2)
      Serial.print("MeasModeInvalid");
    if (error & 1 << 1)
      Serial.print("ReadRegInvalid");
    if (error & 1 << 0)
      Serial.print("MsgInvalid");
    Serial.println();
  }
}

// functions
// MQTT
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
/*    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) { */
    if (client.connect("ESP32Client")) {
      Serial.println("connected");
// subscribe to intopic
//      client.subscribe("inTopic");

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Thanks, I added to the success table.

(Not sure why my code isnt interpreted as code?!? How to fix?!)
Maybe use triple quotes, not a single.

Stay healthy - Maarten

from ccs811.

nordicp avatar nordicp commented on August 25, 2024

Humans emit combustible gases like hydrogen, methane and some VOCs while breathing, to which the sensor reacts. There is a nice correlation of the signal from the metal oxide sensor (which is completely insensitive to CO2) and CO2 as long as the gases are produced by humans, the correlation breaks down if VOCs are from other sources like cooking, cleaning agents or a bottle of Malt Scoth. Regarding very high concentrations of VOCs I wonder about the application. If the sensor should trigger a fan or air cleaner in an inddor environment the threashold level will be much smaller than the concentration measured close to a bottle of alcohole.
CCS811 is not a calibrated analytical instrument and performance will differ from high price lab equipment.

from ccs811.

ullix avatar ullix commented on August 25, 2024

@nordicp : if that is so clear, where are the data published? Please, provide a link.

from ccs811.

ullix avatar ullix commented on August 25, 2024

In continuation of my previous work ( link ), I used the same method, including the Scotch Sniff Test, and additionally recorded the resistance. I then plotted TVOC and eCO2 vs resistance, as shown in the graph:
image
The TVOC vs R curve can be fitted reasonably well with a 5th degree polynomial (equation in the graph). But only up to a certain point. The TVOC curve then shows saturation at the known limit of 29206 at a resistance of about 10kOhm.
Strangely, they let the eCO2 curve continue to its max of 32768 until a resistance of about 5kOhm. This explains the strange data when eCO2 was plotted against TVOC, see above. This implies that the eCO2 data are derived directly from resistance, and not from the TVOC. Somewhat strange, given that eCO2 should be an indirect derivation from TVOC.

Within the eCO2 curve one can see the breakpoint between the two phases at ~95kOhm.

Obviously the sensor is extremely non-linear vs resistance with barely a change in TVOC from 150kOhm down to 80kOhm, followed by major and increasing steps for every 10kOhm down.

So, while the chip can be used as a breathalyzer for serious alcoholics ;-) I am still not sure what its value is for monitoring my home, or any other place? Do others have more on the "Reliability of measurements"?

from ccs811.

nordicp avatar nordicp commented on August 25, 2024

The first iAQ sensors using the "equivalent CO2" output were introduced 2007. eCO2 should be interpreted as an air quality unit and can directly be used for driving a ventilation system which was set to CO2 threasholds, so there is no need to change the settings when changing to another sensor principle.
https://www.co2meter.com/blogs/news/5185132-co2-sensors-vs-voc-sensors-for-iaq-whats-the-difference
"All VOC air quality sensors are basically the same. Some manufacturers of air quality sensors are now providing an output in “CO2 equivalent units.” This measure is considered misleading and may confuse many new to the indoor air quality industry."
Logging of eCO2 and CO2 from an NDIR sensor will most likely show good correlation in offices, sleeping rooms but bad or no correlation in kitchens and bathrooms.
Your finding that eCO2 is derived from resistance is almost correct. Because this sensor is running a baseline correction algorithm it will update its baseline in certain intervals. Adding the rh/T compensation feature (which is included in Maarten's library) will also change the resistance to eTVOC (and eCO2) correlation.
Please keep in mind that this sensor was developed for indoor air quality applications and correct absolute readings are not priority as long as bad air is ventilated off. Because MOX sensors are not selective and systems cannot be recalibrated by the end user the readings of simple breathalizers (available in electronic stores) are pretty unreliable. Same is true for this little sensor module, it is not designed for such an application.
I am running some iAQ sensors at home and I can easily see if somebody is at home, if cooking is going on or if the windows are open.

from ccs811.

ullix avatar ullix commented on August 25, 2024

@nordicp : thanks for the link to this 8 year old article, confirming my newly found skepticism to "misleading measures".

"Correct absolute readings" aren't my problem, selectivity, as you call it, may be a better description. When you check your luggage weight at home with a cheap scale, you know it isn't very accurate. But at least you know it is measuring weight, and not volume, or temperature, or else.

But here that device would also be telling you the eDistance value as the miles you will be travelling. Admittedly, there might be a correlation between suitcase weight and distance, but there may be plenty of other reasons for high or low weight. It is some hyping up the ability of the sensor.

Still, no data in the article, nor linked to. If you could share some of your logs that, as you say, show distinguishable home-style activity, I would highly appreciate that.

I am sitting here at my desk, nobody else nearby, at a reasonably well ventilated place, the sensor nearby, and every now and then the sensor output jumps very high, comes down, and slowly creeps up higher and higher. Does not make sense.

from ccs811.

ullix avatar ullix commented on August 25, 2024

Something mysterious. Either this or a bug in the official CCS811 datasheet.

I keep experimenting, and this is another Scotch-Sniff-Test.
image

The sensor is overwhelmed and goes into its limits: orange is eTVOC and maxes out at 29206, and green is eCO2 and maxes out at 32769. This is exactly what I found previously.

And the very same numbers are mentioned in the data sheet - except they say it is the other way round. Here a quote from the ams Datasheet v1-06] 2019-Feb-07, Page 12:

eCO2:
The equivalent CO2 (eCO2) output range for CCS811 is from 400ppm up to 29206ppm.
eTVOC:
The equivalent Total Volatile Organic Compound (eTVOC) output range for CCS811 is from 0ppb up to 32768ppb.

On Feb 20, 2019 ams had issued a note saying that those values had been changed. So I looked up earlier datasheets and found in issue 2018-Mar-09:

eCO2
The equivalent CO2 (eCO2) output range for CCS811 is from 400ppm to 64000ppm.
TVOC
The Total Volatile Organic Compound (TVOC) output range for CCS811 is from 0ppb to 64000ppb.

And an even older one from 2016-Dec-23:

eCO2
The equivalent CO2 (eCO2) output range for CCS811 is from 400ppm to 8192ppm. Values outside this range are clipped.
TVOC
The Total Volatile Organic Compound (TVOC) output range for CCS811 is from 0ppb to 1187ppb. Values outside this range are clipped.
This is calibrated to a typical TVOC mixture in an indoor environment. If the ratio of compounds in the environment is significantly different the TVOC output will be affected as some VOC compounds will have greater or lesser effect on the sensor.

Very different! (As an aside, note that the caveat (bold by me) in the last sentence has been dropped completely in the later releases!)

Did the lib get it wrong? The *cpp has these lines:

      // Outputs
      if( eco2   ) *eco2   = buf[0]*256+buf[1];
      if( etvoc  ) *etvoc  = buf[2]*256+buf[3];
      if( errstat) *errstat= combined;
      if( raw    ) *raw    = buf[6]*256+buf[7];;

Nope, is at least in agreement with the datasheet, so it seems to me:
image

And my hard-, firm-, and software all seem to be the latest:

11:11:19.442 Found CCS811 lib version : 0x0A
11:11:19.555 Found hardware version: 0x12
11:11:19.663 Found bootloader version: 0x1000
11:11:19.770 Found application version: 0x2000
11:11:19.918 Found Sensor CCS811 w. ID: '0x81', ('129')

Can anybody confirm this screw-up?

from ccs811.

nordicp avatar nordicp commented on August 25, 2024

Confirmed. The PCN for the changes of max. readings is missing and your findings regarding the confusion of the numbers are correct. The note on calibration to a VOC mixture is dropped because such information is not leading anywhere and explained in the second sentence "If the ratio of compounds in the environment is significantly different the TVOC output will be affected as some VOC compounds will have greater or lesser effect on the sensor." Consequently the text got removed in later versions of the datasheet. In section "Automatic Baseline Correction" it is mentioned that "RA cannot be determined by a one-time calibration; it is maintained on-the-fly in software." Calibrated sensors will need recalibration after some time which is impossible in field installations and typically cannot be performed by the unexperienced end user. Calibration is also adding costs in productions. So all cheap gas sesor modules use some sort of auto calibration, same is true for single beam NDIR CO2 sensors.
I also do not recommend tests with very high concentrations of VOCs because the module is designed for the lower range 400 to 5000ppm eCO2 output.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

I recognize find of your issues, but i have never seen this garden fence. Do you run it in mode always on? Did you try a second one?

from ccs811.

mkgin avatar mkgin commented on August 25, 2024

I have seen similar "fences" with some example code for Arduino for the MH-Z14 NDIR sensors that various blogs copy-pasted from each other.

If I remember correctly, the fences were caused by a problem in the code. The data was received from the serial port as bytes, Temperature, CO2 ppm MSB, CO2 ppm LSB, checksum, etc. and put into a char array. When the "ppm" was calculated, the MSB and LSB where cast as "int" when calculating the ppm so the reported value would drop by 256 when the LSB went from 0x7F to 0x80.

Maybe adding some code to print out the raw bytes read from the sensor and calculated value could help find the cause of the fence.

from ccs811.

ullix avatar ullix commented on August 25, 2024

@maarten-pennings I use it with this setting ok = CCS811.start(CCS811_MODE_1SEC);. Are you asking for a second run? I bought this chip about 3 weeks ago, and I am running it basically continuously since then. Should have been well burned in, I think?

@mkgin I see, so a problem because int was used when uint should have been? I went through the lib but found no issue. But don't take my word, do it also. @maarten-pennings May be you can also have a look re this idea of mkgin. I'd be surprised, but one never knows.

EDIT:
this should be the relevant code from the CCS811::read function:

    uint8_t buf[8];
    ...
    // Outputs
    if( eco2   ) *eco2   = buf[0]*256+buf[1];
    if( etvoc  ) *etvoc  = buf[2]*256+buf[3];
    if( errstat) *errstat= combined;
    if( raw    ) *raw    = buf[6]*256+buf[7];;

I think this rules out at least this specific idea?

from ccs811.

nordicp avatar nordicp commented on August 25, 2024

CCS811 does a 24h baseline correction, the baseline should not jump up/down during the time. Is this the value from address 0x11 "Baseline"? In case yes, it is an encoded basline which includes information about baseline and current eCO2 output (see application note Baseline Save and Restore). This specific value is not constant.
Regaring the fence: I have seen quite a lot of data from CCS811 but never such a signal. If the setup is on breadboard I would check for voltage drops caused by the ESP32.

from ccs811.

ullix avatar ullix commented on August 25, 2024

The lib command to call the baseline is:

    #define CCS811_BASELINE         0x11 // 2 bytes
    ....
    // Reads (encoded) baseline from BASELINE (see datasheet). Returns false on I2C problems.
    bool CCS811::get_baseline(uint16_t *baseline) {
      uint8_t buf[2];
      wake_up();
      bool ok = i2cread(CCS811_BASELINE,2,buf);
      wake_down();
      *baseline= (buf[0]<<8) + buf[1];
      return ok;
    }

The wake_up/downs do nothing as my wake pin is permanently grounded. So, it is using 0x11 address, and it should give the correct reading. The application note on baseline is not helpful here, as the baseline is everywhere between zero and 64k, and does not seem to stabilize anywhere. Not even temporarily.

Blaming a voltage drop is a perhaps dangerous proposition, as the competing sensors SGP30 and BME680 are not as finicky about such a presumed voltage drop, and do perform smoothly!

I have no idea where the fence comes from, but it is reproducible.

from ccs811.

compie67 avatar compie67 commented on August 25, 2024

@maarten-pennings i am new to flashing. The .bin files where to put this for using your tutorial
https://github.com/maarten-pennings/CCS811/tree/master/examples/ccs811flash
And does this fixe the going to static value when unplugging usb?

Regard
Eric

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Hi Eric, it's all explained in the readme:

I have downloaded the 2.0.x firmware from the ams pages. I have written a Python script hex.py, Python 3.x - not Python 2.x. It is used to convert a binary firmware file to a C-array [...] Finally, I have written a sketch ccs811flash.ino that uses this array to flash the CSS811.

In other words, you don't need the bin, its converted version is included in the ino.

Your second question ... do not understand. The ccs811 doors not have USB.

from ccs811.

compie67 avatar compie67 commented on August 25, 2024

thank you, clear

i mean wheb powerup(i use the MicroBit coded with arduino software) the css811 runs and give proper value. When disconnect the usb(power) the value goes to some standard tvos 6501 and co2 4301

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

The CCS811 has a resistor Rs that varies with air quality. The tvoc value is roughly Rs/R0, where R0 is the resistance for cleanest air seen by the sensor. R0 is also known as "baseline" and is maintained by the sensor as long as it is powered. Once the sensor is switched off, R0 is lost. After a new power on, it takes some time before a good R0 is determined by the sensor.

So, what you can do is x=get_baseline () before you switch off, and set_baseline(x) after you switch on. But read the datasheet for details on when to do this exactly.

from ccs811.

BlackEdder0815 avatar BlackEdder0815 commented on August 25, 2024

I'm currently also playing around with a CCS811. Sensor seems to be accurate for some time. Then it jumps ahead - weird.
I try to read the "baseline" and monitored the values. Here is the log from while starting the module (already burned in module, but freshly fired up - after 2 hours of cool down)

Baseline: 65279
Heating up. Wait 1174 seconds till system is initialized
Humidity: 44.50%  Temperature: 21.20°C 
1111 1110 1111 1111

Baseline: 65471
Heating up. Wait 1024 seconds till system is initialized
Humidity: 44.10%  Temperature: 21.40°C
1111 1111 1011 1111

Baseline: 50879
Heating up. Wait 965 seconds till system is initialized
Humidity: 43.90%  Temperature: 21.50°C
1100 0110 1011 1111

Baseline: 40127
Heating up. Wait 907 seconds till system is initialized
Humidity: 43.70%  Temperature: 21.60°C 
1001 1100 1011 1111

Baseline: 33983
Heating up. Wait 848 seconds till system is initialized
Humidity: 43.50%  Temperature: 21.60°C 
1000 0100 1011 1111

Baseline: 29119
Heating up. Wait 790 seconds till system is initialized
Humidity: 43.40%  Temperature: 21.70°C 
0111 0001 1011 1111

Baseline: 24767
Heating up. Wait 730 seconds till system is initialized
Humidity: 43.20%  Temperature: 21.80°C 
0110 0000 1011 1111

Baseline: 19903
Heating up. Wait 671 seconds till system is initialized
Humidity: 43.10%  Temperature: 21.90°C 
0100 1101 1011 1111

Baseline: 17343
Heating up. Wait 615 seconds till system is initialized
Humidity: 42.90%  Temperature: 21.90°C 
0100 0011 1011 1111

Baseline: 14271
Heating up. Wait 549 seconds till system is initialized
Humidity: 42.80%  Temperature: 22.00°C 
0011 0111 1011 1111

Baseline: 11711
Heating up. Wait 493 seconds till system is initialized
Humidity: 42.60%  Temperature: 22.00°C 
0010 1101 1011 1111

Baseline: 9151
Heating up. Wait 436 seconds till system is initialized
Humidity: 42.70%  Temperature: 22.10°C 
0010 0011 1011 1111

Baseline: 7103
Heating up. Wait 380 seconds till system is initialized
Humidity: 42.70%  Temperature: 22.10°C 
0001 1011 1011 1111

Baseline: 2751
Heating up. Wait 323 seconds till system is initialized
Humidity: 42.60%  Temperature: 22.20°C 
0000 1010 1011 1111

Baseline: 1215
Heating up. Wait 204 seconds till system is initialized
Humidity: 42.40%  Temperature: 22.20°C 
0000 0100 1011 1111

Baseline: 447
Heating up. Wait 144 seconds till system is initialized
Humidity: 42.40%  Temperature: 22.20°C 
0000 0001 1011 1111

Baseline: 447
Humidity: 42.40%  Temperature: 22.20°C 
0000 0001 1011 1111

After that, it stayed constantly for a good hour at this baseline value.
Now, I opened the window and moved the sensor (within a case already) out the window (below 10°C out here):

Baseline: 26302
Humidity: 32.10%  Temperature: 22.80°C 
0110 0110 1011 1110

Baseline: 58045
Humidity: 32.40%  Temperature: 21.70°C 
1110 0010 1011 1101

Baseline: 26045
Humidity: 34.70%  Temperature: 20.00°C 
0110 0101 1011 1101

Baseline: 62652
Humidity: 37.70%  Temperature: 18.40°C 
1111 0100 1011 1100

Baseline: 28604
Humidity: 41.90%  Temperature: 16.40°C 
0110 1111 1011 1100

Baseline: 444
Humidity: 46.60%  Temperature: 14.40°C 
0000 0001 1011 1100

After turning back into my room, the baseline value didn't changed again.
Feels like, the upper byte (most left) are an indicator for warming up the sensor. The lower byte (left) kept constant before opening the window and changed (slightly) after I placed sensor outdors.
With raising temperature, the eCO2 values raised a lot. Before the window-experiment I was at 410 ppm, after the window-experiment I'm now at 1730 ppm. I don't think, that opening the window polluted my room air in such a way.

I will monitor this behavior for the next days and will do some experiments. I guess, I will include a "calibration-button" in my project, so when I press it while starting, the system will run into a calibration mode. Then it will heat-up for 30 minutes, test, if the upper byte is equal "1" and will record the threshold. Then it will set the threshold right before every measurement.

Anyone else with more knowledge about this "encoded threshold" and how it is build?

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

I'm not sure what you want to achieve.

The baseline register contains ... the ... baseline. That is, the highest resistor value seen in the last day. The resistor has a large dynamic range, so maybe it is coded in a sort of floating point format. Likely, another parameter is also stored (time?). All of this is packed, and maybe encrypted.

Why do you care?

You retrieve it before the ccs811 is switched off, and restore it after the ccs811 is switched on and is stable again.

from ccs811.

BlackEdder0815 avatar BlackEdder0815 commented on August 25, 2024

You retrieve it before the ccs811 goes to sleep, and restore it after the ccs811 wakes up and is stable again.
depends on what "go to sleep" means. Switch off and let cool down, and switch it on again later?

Or do yo mean during runtime, pushing ccs811 to sleep, wake up, restore, measure and sleep again?
If you mean the second one, then the pushing to sleep and waking up is handled by your library. So if I request a measure, the lib automatically wake-up, get measurements and set to sleep again.
Nevertheless, it's quite interesting, how this baseline behaves.
In an additional test-round (after a night of cool-down) I monitored the changes on the baseline again.
It changed a lot during the warm-up (20 minutes), but changed another 17 times right after this 20 minutes - in a period of another half an hour.
Every 2-3 minutes a new baseline was stored/calculated by the ccs811.
After this, the baseline kept constant for hours.

I still stay with the idea of "calibration" or "nullification". So add a button to my measure box. If this button was pressed during start, warm-up for 20 minutes and then watch the baseline till there is no change (for 20 minutes?). Then record this baseline value, store it in a non-volatile register and check right before every requested measurement, if the baseline is still the same. If not, push the stored to ccs811.
If the whole system was switched off and on again, wait for 20 minutes and restore the "calibrated" baseline into the ccs811 (if the calibration button was not pressed at start-up).

But it would be still interesting, what exactly this two bytes about. Looking to the last record of base-lines, the lower byte stayed quite constant, and the upper byte decreased from record to record (just in the first few seconds, the upper byte jumped a bit around, but still lower byte kept more or less constant)

from ccs811.

nordicp avatar nordicp commented on August 25, 2024

BL save and restore is a nice feature to speed up the tie the sensor needs to get used to the environment. In case the sensor is not moved to another location and a previously saved BL is available the readings will be close to the readings before power off. The BL itself carries information about sensor resistance and air quality at the time the BL was saved.
A guideline is available here:
https://www.sciosense.com/wp-content/uploads/2020/01/Application-Note-Baseline-Save-and-Restore-on-CCS811.pdf
Copied from page #4: "The baseline value is not simply the raw resistance value of the sensor in clean air, it also includes some additional factors used by the internal algorithms. It is not in a human readable format..."
The BL save and restore feature is not meant for power saving but to cover maintenance or power outage.
For checking the warm-up I read sensor resistance and write back the BL when resistance data starts leveling out, a well run-in sensor typically does not need more than 5min of warm-up.
I like the idea of "nulling", unfortunately CCS811 does not offer setting the reading to a self defined air quality. If the sensor would run in a room and it would be possible to press button and restore a BL coded from resistance and "good air" 400ppm eCO2 (or another value of choice) the sensor could be set to perceived or measured air quality from another device.
Unfortunately I can not find further information on how the BL is calculated and the development team is no longer available.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Indeed I didn't use the correct wording. Baseline extract and restore is over power down and up (I edited the wording in my previous post). If you put the ccs811 to sleep with the wake pin it turns itself on now and then to heat up (see Figure 10: CCS811 Power States).

from ccs811.

rost12345 avatar rost12345 commented on August 25, 2024

Tried to flash a chinese version of ccs811 sensor and it failed for some reason.

Starting CCS811 flasher
setup: library version: 10
ccs811: Wrong HW_ID: FD
setup: CCS811 begin FAILED
setup: hardware version: 12
setup: bootloader version: 1000
setup: application version: FFFFFFFF
setup: starting flash of 'CCS811_FW_App_v2-0-0.bin' in 5 seconds

ccs811: ping ok
ccs811: reset ok
ccs811: status (reset1) 20 ERROR - ignoring
ccs811: app-erase ok
ccs811: status (app-erase) 40 ok
ccs811: writing 5120 ...........................ccs811: app data failed
setup: CCS811 flash FAILED

pin WAK connected to GND, the version of firmware was 1100 (before flashing),
flashing on pro mini atmega168*16Mhz, what can I do to make it flash?

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

from ccs811.

rost12345 avatar rost12345 commented on August 25, 2024

Tried on another arduino board (at328) and it flashed OK.
But now I have weird reading from sensor :

setup: Starting CCS811 basic demo
setup: ccs811 lib version: 10
setup: hardware version: 12
setup: bootloader version: 1000
setup: application version: 2000
CCS811: waiting for (new) data
CCS811: errstat=1091=--vHxmrwF--Ad-iE
CCS811: errstat=1091=--vHxmrwF--Ad-iE
CCS811: errstat=1891=--vHXmrwF--Ad-iE
CCS811: errstat=1899=--vHXmrwF--AD-iE
CCS811: errstat=1899=--vHXmrwF--AD-iE
CCS811: errstat=1899=--vHXmrwF--AD-iE

from ccs811.

jluisalvarez avatar jluisalvarez commented on August 25, 2024

Hello, I have had the same problem with two CJMCU-811 sensors (Chinese modules).

The first one connected (I2C, 3v3) to a Raspberry Pi 4 worked correctly until after about two months (approx.) it began to give read errors.
The second one connected (I2C, 3v3) in a Blue Pill also worked correctly and after two months (approx.) it also began to fail to read.

This shows up on both sensors with Arduino Uno and ccs811basic.ino:

CCS811: errstat = 1091 = - vHxmrwF - Ad-iE
CCS811: errstat = 1091 = - vHxmrwF - Ad-iE
CCS811: errstat = 1891 = - vHXmrwF - Ad-iE
CCS811: errstat = 1899 = - vHXmrwF - AD-iE
CCS811: errstat = 1899 = - vHXmrwF - AD-iE
CCS811: errstat = 1899 = - vHXmrwF - AD-iE

As I have read, the sensors may be bad, the transducer heater could be broken, but I have a hunch that it is a problem with this module that after a while the heater breaks.

It can be that? Any other idea?
Any solution?

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

The uppercase HX in errstat are explained in the datasheet.

  • The sensor resistance measurement has reached or exceeded the maximum -- MAX RESISTANCE
  • The Heater current in the CCS81 I is not in range -- HEATER FAULT

(By the way, a status string has 5 times a "-", in yours I see only three)

I have had css811 sensors in use for more than two month, and they didn't burn their heater. Isn't the raspberry pi 5 volt? That is too much for the ccs811.

from ccs811.

jluisalvarez avatar jluisalvarez commented on August 25, 2024

Hi Maarten, thank you for your quick reply.

Actually the status string has 5 times "-", during "copy and paste" process it would be changed. Here it is:

setup: Starting CCS811 basic demo
setup: ccs811 lib version: 10
setup: hardware version: 12
setup: bootloader version: 1000
setup: application version: 2001
CCS811: waiting for (new) data
CCS811: errstat=1091=--vHxmrwF--Ad-iE
CCS811: errstat=1091=--vHxmrwF--Ad-iE
CCS811: errstat=1891=--vHXmrwF--Ad-iE
CCS811: errstat=1899=--vHXmrwF--AD-iE
CCS811: errstat=1899=--vHXmrwF--AD-iE
CCS811: errstat=1899=--vHXmrwF--AD-iE
CCS811: errstat=1899=--vHXmrwF--AD-iE

I connected the sensor (on both boards: RPI4 and BluePill) to 3v3 and used a level shifter module (5v - 3v3) for I2C bus.

Pictures show the two sensors (addresses 0x5A and 0x5B) connected (to I2C via 4 way Level converter module) to my Arduino UNO in order to the current tests.

picture1

picture2

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

You covered everything - I'm out of options... :-( sorry

from ccs811.

pgrisu avatar pgrisu commented on August 25, 2024

I believe the new firmware uses special algorithm at the early life of the sensor. When early life is over, it uses the standard algorithm. The firmware knows when early life is over by persistently storing the run time on the sensor. The special algorithm at early life is needed, because the chemicals in the sensor are not yet "baked" to stability. Again, all this is what I mentally model from the documentation.

Since the old firmware did not have this algorithm, it also did not store the run time.

So, the 2.0.0 firmware is good for fresh "non-baked" sensors. But if you would use it on a baked sensor, the firmware would (incorrectly) apply the special algorithm the first couple of days, giving suboptimal readings. However, after the first couple of days, the persistent timer reaches the end-of-early-life value and switches to the standard algorithm, so your readings will be good from then onwards.

Hello Maarten, first of all, I appreciated a lot your work! Thanks!
We included your library on several thousands of our ESP32 based Indoor Environment Monitors (see https://www.aircare.it/en/home-eng/ and also https://www.daikinapplied.eu/news-center/introducing-the-new-daikin-iaq-sensor/ ).
We recently upgraded CCS811 firmware on field (from 1.1 to 2.0.x) using our FOTA service and your CCS811 firmware update code.
Your code worked fine and firmware is properly upgraded on thousands of sensors on field. Thank you again!
Our application software selects the rigth new firmware (2.0.0 or 2.0.1) based on single device/sensor working time, stored on device file system at baseline save time as stated in AMS application note.
Now we gain larger TVOC/eCO2 range compared with 1.1 sensor firmware, but we aren't so confident that now the sensor works well on first 48/60 hours after a power-cycle.

Are you sure/confident that the 2.0.0 firmware uses internal persistent storage for accounting sensor early-life, or it's just your guess?
If so, why don't use the internal persistent storage also for tracking baseline without host save/restore needs?
It'seems that using the 2.0.0 firmware on new sensor the measurements are higher than expected during first 48/60 hours after a power-on then, suddently TVOC drops (and stays) to more plausible values.
We never seen such amplified behaviour while using 1.1 firmware in more or less three years on the field
Your opinion on such behaviour will be appreciated

Thanks
Paolo

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

Hi Paolo,

Thanks. The monitors look great. It scares me a bit that you use my hobby project for so many products!

The difference between 2.0.0 and 2.0.1 is how I interpreted the documents, so my guess.

I believe the internal storage is not reliable enough for many write cycles; so it is good enough for recording the first couple of days the time, but not good enough for recording baselines for 10 years.

I believe you can downgrade the 2.0.x firmware back to 1.1.

Good luck!

from ccs811.

JoEVos47 avatar JoEVos47 commented on August 25, 2024

I have a quick question. I am using the CCS811 chip to measure TVOC and CO2 only, as I have a temp reader set up separately. In demos/dry runs, the CCS811 chip works well for ~14 hours. However around that 14th hour, the chip experiences a massive drift upwards for approx 10-15 min usually to near its max values, before slowly dropping down to normal levels over the course of the next few hours. Using many different chips to test the issue, I have found that it does in fact drift for all them. Reviewing cameras and such, I have found that nothing has actually changed to affect the TVOC or CO2 levels. Is this a common issue found by everyone? Have I set the baseline incorrectly causing the large shift? I have not recently (read ever) updated the firmware on the chips, would possibly upgrading it to 2.0.0 or 2.0.1 or downgrading it back solve it? Is it another issue that I am unaware of? Obviously I have many solutions to test but was wondering if anyone had this issue and knew how to fix it quickly.

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

I do not believe the baseline is involved here. Roughly the baseline works as follows.

A sensor has a resistance depending on the gases in the air. The cleaner the air the lower the resistance. Unfortunately, this relation is not stable in time (resistance changes due to what happened in the past). So what the firmware of a mox sensor does is record the lowest resistance it has seen - the cleanest air. Let's call this R0. When you perform a measurement, the sensor measures the current resistance, let's call it Rc, and it roughly outputs Rc/R0. The problem is, that the sensor resistance for clean air changes in time, so the sensor needs to adapt R0. The firmware has algorithms to measure R0 on a daily basis (24 hour cycle). R0 is called the "baseline", and can also be set manually. So setting the baseline might cause a jump at that moment, and they might be changes at the 24hr cycle. I do not expect jumps after 14 hours, due to baseline management.

from ccs811.

shooorf avatar shooorf commented on August 25, 2024

After turning back into my room, the baseline value didn't changed again. Feels like, the upper byte (most left) are an indicator for warming up the sensor. The lower byte (left) kept constant before opening the window and changed (slightly) after I placed sensor outdors. With raising temperature, the eCO2 values raised a lot. Before the window-experiment I was at 410 ppm, after the window-experiment I'm now at 1730 ppm. I don't think, that opening the window polluted my room air in such a way.

I will monitor this behavior for the next days and will do some experiments. I guess, I will include a "calibration-button" in my project, so when I press it while starting, the system will run into a calibration mode. Then it will heat-up for 30 minutes, test, if the upper byte is equal "1" and will record the threshold. Then it will set the threshold right before every measurement.

Anyone else with more knowledge about this "encoded threshold" and how it is build?

Baseline is encoded as big-endian uint16, just swap bytes with __builtin_bswap16

from ccs811.

stas-sl avatar stas-sl commented on August 25, 2024

Seems like I solved baseline mystery finally.

image

  1. As @shooorf mentioned, you should swap 2 bytes: 0x48B6 -> 0xB648
  2. Then invert it bitwise ~baseline: 0xB648 -> 0x49B7. After that you already will see some sensible correlations between resistance and baseline.
  3. Finally using modified baseline we can calculate R0 as: R0 = 2 ** (baseline / 2 ** 10), or the other way if current resistance is higher than baseline, baseline could be updated as: baseline = 2 ** 10 * log2(R)

So, when sensor is exposed to fresh air, the baseline gets updated to store higher resistance level, however if you monitor baseline for some time, you'll notice that it also changes continuously in not so fresh air. If you apply those 3 transformations above, you can easily spot, that when air is not fresh, baseline gets decreased every few minutes with a steady pace equivalent to ~2,5 kOhms/hour or 60 kOhms/day. It means, that if you will put your sensor in very dirty space and keep it there for a few days, eventually the baseline will reach current resistance level corresponding to dirty air, and it will report that the air is fresh (tVOC=0, eCO2=400). In more realistic scenario, if you open window before going to bed and keep it closed for the whole night, then R0_night used to calculate tVOC in the beginning of night will be different from R0_morning by 2500 * 8 hours = 20 kOhms. So, to have tVOC & eC02 measurements comparable and realistic, you need either ventilate your place quite frequently or restore baseline periodically (maybe every hour or even minute), especially if your place not being ventilated too often.

Knowing R and R0, we can see pretty simple relationship between R/R0 and tVOC:

image

Also, I faced similar "fence" as @ullix mentioned:
image

I already started to blame CCS811, however after some experiments I found that if I removed the other sensor (Senseair S8), that was connected to same ESP32 GND pin, the fence went away. I don't know why it is so, and whether or not there was a similar issue in @ullix case, but that's just my experience.

Update:

After running the sensor for more than a week, I should correct a bit my previous findings:

  1. Resistance calculated as 2 ** (baseline / 2 ** 10) perfectly matches resistance peaks only with default temp=25C and humidity=50%. However, if you set environment parameters to something else, then if you plot 2 ** (baseline / 2 ** 10) (as red line in my example), then it could be shifted up or down by up to 50 kOhms, though it still will follow current resistance, just shifted by some value depending on env correction.
  2. After a week baseline doesn't decrease that rapidly as I said before. In fact it stays constant for quite long time now. I haven't run it uninterruptedly for longer than 1-2 days, so I don't know if there is any dynamics over longer periods. Seems like it decreases once a day(?), but I'm not sure.

This is how raw resistance value changes in first few weeks of usage:
image

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

from ccs811.

wookash avatar wookash commented on August 25, 2024

My first feeling is that the ccs811 library is not part of your project/build. I see "undefined reference to" many library functions: set_i2cdelay begin hardware_version bootloader_version Are you sure the ccs811 library is downloaded and found by your compiler?

Thanks. I since deleted my comment as I managed to update the firmware from 2.0.0 to 2.0.1, included your library in platformio and worked well. On another note - as this sensor is mostly an indicator of co2 (I have it working together with Vindrikting from IKEA) and calibrated with external sonoff temp sensor - is there any “true” co2 sensor you would recommend?

from ccs811.

wookash avatar wookash commented on August 25, 2024

Thanks @nordicp. I can see various models of MH-Z19 - MH-Z19b, MH-Z19c and MH-Z19e. Is the cheapest version (e) ok?

from ccs811.

nordicp avatar nordicp commented on August 25, 2024

The variants differ in warm-up time and max. ppm. Have a look to the datasheets and pick the sensors most suited for your application. Version "e" measures up to 10,000ppm, a pretty high value not expected in normal indoor air applications. If it is a real bargain then go for it. I bought the MH-Z19b some years ago before other models were launched (at least I do not remember that I came across other variants).

from ccs811.

wookash avatar wookash commented on August 25, 2024

The variants differ in warm-up time and max. ppm. Have a look to the datasheets and pick the sensors most suited for your application. Version "e" measures up to 10,000ppm, a pretty high value not expected in normal indoor air applications. If it is a real bargain then go for it. I bought the MH-Z19b some years ago before other models were launched (at least I do not remember that I came across other variants).

Thanks, it seems MH-Z19e is the cheapest of them all..
https://www.aliexpress.com/item/4001296615950.html?spm=a2g0o.productlist.main.1.3cc04Jbn4Jbnfa&algo_pvid=2d2a76b0-0811-4b63-b023-8679edd55fe9&algo_exp_id=2d2a76b0-0811-4b63-b023-8679edd55fe9-0&pdp_npi=3%40dis%21GBP%2122.15%2113.28%21%21%21%21%21%40214527fd16817537803758772d06e0%2112000024558309219%21sea%21UK%210&curPageLogUid=aii07uyY0eNG

from ccs811.

maarten-pennings avatar maarten-pennings commented on August 25, 2024

from ccs811.

wookash avatar wookash commented on August 25, 2024

no worries, thanks @nordicp and @maarten-pennings !

from ccs811.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.