maarten-pennings / CCS811

Arduino library for the CCS811 gas sensor for monitoring indoor air quality.
MIT License
165 stars 46 forks source link

Error code #17

Open bill-orange opened 5 years ago

bill-orange commented 5 years ago

I am getting this error code randomly between good readings. If it starts generating errors they keep coming. I am clock stretching on an ESP32 with a generic Chinese CS811 (ver. 2 firmware)

errstat=899=--vhXmrwF--AD-iE

How do I translate this? I can probably track this down on my own if I know what's going on. Interestingly, the first reading after setup is always good.

maarten-pennings commented 5 years ago

As you can see in the .h file ERRSTAT is a merge of two hardware registers: ERROR_ID (bits 15-8) and STATUS (bits 7-0)

So, we have to split the hex value (899 or rather 0899) and the string (--vhXmrwF--AD-iE) ERROR has hex value 08 which corresponds to --vhXmrw and STATUS has hex value 99 which corresponds to F--AD-iE Capitals mean bit-is-set, lowercase means bit-is-clear, dash means bit has no meaning. See function CCS811::errstat_str for details

What does this mean?

Most part of STATUS is ok (see datasheet page 18 on ams.com/ccs811): The F tells that the firmware is in application mode (not bootmode) , the A means that the application image is valid (flashed correctly), D means there is new measurement data. But you also have an E - for Error. This should not happen.

When you have an E/error, the ERROR register gives details. You have X (datasheet page 24) meaning "The sensor resistance measurement has reached or exceeded the maximum range". I'm not sure what does means, maybe your sensor is broken. Is your supply voltage correct?

bill-orange commented 5 years ago

Supply voltage is correct. It is possible that my chip is bad. I ordered another for testing.

Also, I am testing the strong possibility of WiFi interference between the ESP32 and the sensor. I have placed a small tantalum cap on the power supply and shielded the backside of the board. I have reduced Tx power on the ESP32 to 50%. No errors so far. I started down this path when I discovered that the errors we are discussing disappeared when I removed WiFi.begin() from the sketch. I don’t know that anyone else with CCS811 issues has tried this.

Another possibility is that more power is available to the CCS811 when WIFI is off.

mjsqu commented 5 years ago

I am also seeing this issue with an AMS sensor (the one that comes with the USB evaluation kit). I have tried it with:

I have got readings of eCO2 = 400ppm and eTVOC = 0ppb, but that is only if I use your library and ignore the errors that are received when getting ALG_RESULT_DATA, and the values never move from 400,0.

I get the 899 error as mentioned by @bill-orange, but the difference is I don't ever see any good readings.

When I use the CCS811 with the USB evaluation kit in Windows the sensor operates normally.

Thanks @maarten-pennings for your development of this library, it's the best one I've found which aligns with the programming and interfacing guide and reports the meanings of the errors back from the sensor! :+1:

Going to attempt running with pull-up resistors on SDA, SCL later.

bill-orange commented 5 years ago

@mjsqu Please try running the sensor in your application but with WiFi turned off. Let’s see what happens. Comment out WIFi.begin(); in my case, pull-ups did not matter.

mjsqu commented 5 years ago

No change unfortunately, I never had WiFi.begin(); in my code. But I added WiFi.mode(WIFI_OFF); just to make sure and it still fails. Will be checking with another sensor once it arrives in the post.

bill-orange commented 5 years ago

For test purposes you might try the SparkFun library while you are waiting.

Sent from my iPhone

On May 27, 2019, at 12:32 PM, mjsqu notifications@github.com wrote:

No change unfortunately, I never had WiFi.begin(); in my code. But I added WiFi.mode(WIFI_OFF); just to make sure and it still fails. Will be checking with another sensor once it arrives in the post.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

mjsqu commented 5 years ago

Yep, I've tried that one and the Adafruit one!

ngttai commented 4 years ago

Hi, I am a newbie about ccs811 I download this library, update firmware for ccs811 and run example ccs811basic. recently, I get an error code 1899 in terminal, I know it as CCS811_ERRSTAT_HEATER_FAULT and CCS811_ERRSTAT_MAX_RESISTANCE I use platformIO and hardware is BluePill(stm32f103c8)

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
maarten-pennings commented 4 years ago

Hmm - max resistance could be a symptom of heater fault. And heater fault looks like defect hardware to me ... :-(

mbilalyigit commented 4 years ago

I have same only error CCS811_ERRSTAT_MAX_RESISTANCE.

I have two CCS811. Using the same code, one of them returns always (400,0). Even RAW data resistance value is 1023( 10 bit max value ). Did anyone solved this issue? Bill's solution didn't work for me.

Only way I am getting different value is blowing air to device. It decreases baseline value. And I can read some meaningful value with really bad resolution. But error is still there.

Note: Reading LSB first, makes baseline linear in my case.

pilakito commented 3 years ago

I have nearly same issue,

I set up the circuit for arduino nano as indicated. In addition i am using logic level converter TXS0108E. Because, i see "The CCS811 datasheet specifies that logic high is at most 1.0 x VDD (i.e. 3v3), connecting the CCS811 to the I2C pins of the Nano (at 5V) is thus a risk for the CCS811." note.

When i started the arduino program, in serial terminal i see these.

setup: Starting CCS811 basic demo setup: ccs811 lib version: 11 setup: hardware version: 12 setup: bootloader version: 1000 setup: application version: 1100 CCS811: errstat=0=--vhxmrwf--ad-ie

if errstat is 0 why my is my code running. If I didn't get it wrong, it shouldn't be an error.

I didn't edit the library or cs811basic code.

bill-orange commented 3 years ago

How is you CC811 getting power? Perhaps it is not getting enough current when it is trying to read.

maarten-pennings commented 3 years ago

Hi @pilakito, The level shifter makes sense. I assume you run the basic example, the output looks good. You get bootloader and application version, so nano and ccs are working, and the i2c communication too. So everything good

However, after the startup, things go wrong. The library should return CCS811_ERRSTAT_OK, which is the OR of the flags: CCS811_ERRSTAT_DATA_READY, CCS811_ERRSTAT_APP_VALID, and CCS811_ERRSTAT_FW_MODE .

# CCS811_ERRSTAT_DATA_READY          0x0008 // A new data sample is ready in ALG_RESULT_DATA
#define CCS811_ERRSTAT_APP_VALID           0x0010 // Valid application firmware loaded
#define CCS811_ERRSTAT_FW_MODE             0x0080 // Firmware is in application mode (not boot mode)

So, somehow, after getting versions, communication goes wrong.

Do you use the wakeup pin?

pilakito commented 3 years ago

Hello @maarten-pennings

I connected it to pin 13 with level shifter. I didn't connect directly.

@bill-orange It connected to my computer.

maarten-pennings commented 3 years ago

If you did not modify the library or examples, the begin() method also checks the status (eg see line 169 in cpp file) and it is not 0. So, I'm puzzled

pilakito commented 3 years ago

I am going to download library and i will try it again.

pilakito commented 3 years ago

I think i changed something wrongly and this happened. Thanks for support.

setup: Starting CCS811 basic demo setup: ccs811 lib version: 10 setup: hardware version: 12 setup: bootloader version: 1000 setup: application version: 1100 CCS811: waiting for (new) data CCS811: waiting for (new) data CCS811: eco2=0 ppm etvoc=0 ppb
CCS811: eco2=0 ppm etvoc=0 ppb
CCS811: eco2=0 ppm etvoc=0 ppb
CCS811: eco2=400 ppm etvoc=0 ppb

shivapower1985 commented 2 years ago

I connected ESP8266 and CCS811 module. I did the connection correctly and I get the below error. Help needed to get the data.

Error CCS811: errstat=99=--vhxmrwF--AD-iE CCS811: errstat=99=--vhxmrwF--AD-iE .. .. ..

Please suggest help

maarten-pennings commented 2 years ago

This is very funny. When you have a normal working sensor, it should have either of these two

--vhxmrwF--Ad-ie // No errors (e), app valid (A), and running (F), but no data yet (d)
--vhxmrwF--AD-ie // No errors (e), app valid (A), and running (F), and data available (D)

If there is an error (last e becomes E as in your case), then one of (vhxmrw) should be high indicating which error.

From the datasheet (note the last line):

STATUS.ERROR This bit is cleared by reading ERROR_ID (it is not sufficient to read the ERROR field of ALG_RESULT_DATA and STATUS ) 0: No error has occurred 1: There is an error on the I²C or sensor, the ERROR_ID register (0xE0) contains the error source

kubawlo commented 2 years ago

Hello Maarten,

I was using your library to read sensor data with Arduino Uno - it worked wonderfully, without any issues. However, when I connected it to my ESP32 dev1 as the destination project board (and activated the respective line in the ccs811basic CCS811 ccs811(23); // nWAKE on 23 ), I obtain the following error: errstat=10=--vhxmrwf--Ad-ie

The sensor address 0x5A is visible on ESP32 with i2c scanner. If I restart the ESP 32 with WAKE pin of CCS811 pulled to GND, I receive error: CCS811: I2C error If I restart the ESP 32 with WAKE pin disconnected, I initially get of course CCS811 start FAILED, then CCS811: I2C error. Next, when I connect WAKE pin to GND again, I receive the most meaningful error errstat=10=--vhxmrwf--Ad-ie.

What do you think could be the issue here?

maarten-pennings commented 2 years ago

Hi, this sounds a bit puzzling.

If you connect the nWake pin to ground the ccs811 is always wake so that should simply work.

Second observation: the F-flag is low in errstat, which seems to suggest the ccs811 is running the bootloader, not the gas app. I'm confused that the A-flag is up though. Full output of the basic example would be good.

Thirdly, you say the ccs811 was first connected and working with an UNO. This scares me, the UNO is a 5V device, and the ccs811 is destroyed by that voltage. Did you take and precautions?

Success

kubawlo commented 2 years ago

Thanks for your reply. To begin with, I actually started testing the ccs811 with ESP32 and not with Arduino UNO, and it did not work properly from the first try, so I think I rather did not damage the sensor from the very beginning.

With Arduino UNO (I power the CCS811 from the 3V3 pin and connect to SCL and SDA of Arduino), with nWake to ground from the beginning, I receive this output below, which seems just right (reacts to breathing on the sensor and also to petrol fumes in the air)

02:07:17.990 -> setup: Starting CCS811 basic demo
02:07:17.990 -> setup: ccs811 lib  version: 12
02:07:17.990 -> setup: hardware    version: 12
02:07:18.023 -> setup: bootloader  version: 1000
02:07:18.023 -> setup: application version: 2000
02:07:18.023 -> CCS811: waiting for (new) data
02:07:19.009 -> CCS811: waiting for (new) data
02:07:19.999 -> CCS811: waiting for (new) data
02:07:21.009 -> CCS811: waiting for (new) data
02:07:22.012 -> CCS811: eco2=400 ppm  etvoc=0 ppb  
02:07:23.033 -> CCS811: eco2=400 ppm  etvoc=0 ppb  
02:07:24.028 -> CCS811: eco2=400 ppm  etvoc=0 ppb  
02:07:25.019 -> CCS811: eco2=400 ppm  etvoc=0 ppb  
02:07:26.037 -> CCS811: eco2=400 ppm  etvoc=0 ppb  
02:07:27.033 -> CCS811: eco2=400 ppm  etvoc=0 ppb  
02:07:28.013 -> CCS811: eco2=400 ppm  etvoc=0 ppb  
02:07:29.036 -> CCS811: eco2=708 ppm  etvoc=46 ppb  
02:07:30.044 -> CCS811: eco2=508 ppm  etvoc=16 ppb 

Now I disconnected all other I2C devices (I had a couple of other sensors hooked up) from the ESP 32 and it started working! So I am guessing this might have been some kind of conflict with other slaves. I reconnected all the slaves again as before and now all three work well...

BTW, with the comment about destruction by the voltage - did you mean that the logic levels of 5V instead of 3.3V or the supply voltage?

Cheers

maarten-pennings commented 2 years ago

Hi, good to hear everything is working.

If you look at Figure 6 in the ccs811 datasheet (Electrical Characteristics) we see that Supply Voltage (VDD) min is 1.8 and max is 3.3 V; those are the limits for supply. So good you hooked the supply of the CCS811 to the 3v3 pin.

However that same table tells us that Logic High Input (nRESET, nWAKE, ADDR, SCL and SDA) min is VDD-0.5 and max is VDD. So the logic levels of I2C should also not exceed 3v3, and I'm afraid the Uno has logic levels of 5v0.

In practice, ICs have ESD protection in the form of diodes from every I/O pin to the internal VDD rail. This means that a voltage on such a pin which is higher than VDD actually propagates to the VDD rail. I once had an IC with such low power requirements (ENS210 from same company) that it worked by only hooking up SCL and SDA (I forgot VDD): the pull ups on the I2C lines and the internal diodes supplied the power.

So, maybe not hook up ccs811 to uno without a level shifter...

Cheers

kubawlo commented 2 years ago

Thank you for your valuable "insider's" comments. It seems I was lucky, or the module had some kind of foolproof protection against such cases, but the sensor seems to be working fine now, at least reacting to high concentration of organics. Maybe I'll just add here what helped in my case of 3 I2C-based sensors (one of them was the disobedient ccs811, the rest did not have the stretched clock). In the code, I initialise the ccs811 as the very last sensor. Then, in the loop() I first put the line ccs811.set_i2cdelay(50); again, then read the sensor data as usual, and I finish this block with ccs811.set_i2cdelay(0); so that whatever later I2C devices have the "fast" I2C again. At least this quick fix helped with communication of all 3 sensors and the strange errors disappeared.

By the way, I was just curious how the sensor handles the case when no baseline is provided explicitly in the code? Does it just save the baseline after power-on (or reset) and then it stays as it is? I am wondering now about the proper solution for airborne VOC measurements for an external air quality sensor... I thought I could read the baseline everyday, say at 3 am when there is no traffic or (less) chimney fumes and write it once per 24 hr into the chip.

Cheers!

maarten-pennings commented 2 years ago

Roughly, the baseline is the cleanest air seen since power on (but "reset" every 24hr). So, if you switch the sensor on in a dirty environment it will give a wrong reading. That's why the advice is to record the baseline (if the sensor is running long enough!) and reuse that when switching on the sensor later.

maarten-pennings commented 2 years ago

Did you try to use without ccs811.set_i2cdelay(0). I forgot about this, I believe this was only needed in the esp8266 because it had an i2c software implementation ("bit bang") with a bug.

The ESP32 has a proper I2C hw block, so I believe the call is not needed here. The ESP8266 software implementation is fixed in the mean time (after my complaints :-) so also there it is no longer needed. Could you check for the ESP32?

kubawlo commented 2 years ago

Did you try to use without ccs811.set_i2cdelay(0).

I now commented out all the lines containing ccs811.set_i2cdelay() and it seems to be working fine indeed! Thanks! Sometimes, which is still weird, the ccs811 is detected with other two sensors, but still gives the "CCS811: I2C error" when read from in parallel with other sensors. What helps, oddly, is running an i2c_scan.ino by Rui Santos (it then gives three I2C addresses, as expected), and then again my sketch which reads from the three sensors... Maybe the i2c_scan.ino somehow helps to "reset" the CCS811? Powering down and up the board or pressing the reset button on the ESP32 does not have such a healing effect like running the scanner script... :)

maarten-pennings commented 2 years ago

You might want to try my https://github.com/maarten-pennings/I2Cbus

kubawlo commented 2 years ago

Thank you, Maarten, I might implement this to automatically clear the bus when the sensor is unresponsive again!