arendst / Tasmota

Alternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at
https://tasmota.github.io/docs
GNU General Public License v3.0
21.96k stars 4.77k forks source link

CCS811 stops working #3364

Closed Chaot1 closed 5 years ago

Chaot1 commented 6 years ago

Make sure these boxes are checked [x] before submitting your issue - Thank you!

(Please, remember to close the issue when the problem has been addressed)

Thank you for implementing the CCS811 . But i have a small Problem: When i start the CCS811 it reads the correct status an i can see him on the SonoffDEV website. But after 1 or 2 Hours the CCS811 disappears. When i restart the Sonoff it appears again.

Connected on GPIO 4 and 5 Bridge between WAK and GND (on CCS 811 to activate) No other items connected

martin072 commented 6 years ago

HI,

I have seen strange behaviour with the CCS on the ESP. In the end this worked for me:

./Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/core_esp8266_si2c.c" Line 74: Changed twi_setClockStretchLimit(230) to twi_setClockStretchLimit(460);

It does not seem to affect other i2c devices I use (Oled and BME260), maybe this helps?

reference: https://github.com/AKstudios/CCS811-library/issues/3#issuecomment-336360650

gemu2015 commented 6 years ago

in Tasmota Adafruit Lib Clockstretchlimit is already set to 1000 =>

ifdef ESP8266

Wire.setClockStretchLimit(1000);

endif

I use this Sensor since a couple of month without any problems. also the new Tasmota implementation runs without problems. however i use a very stable 3.3 V power supply with an Esp07, (no sonoff) may be it is a power supply issue? is use these pins => GPIO12 = SDA (d6) GPIO14 = SCL (d5)

ascillato2 commented 6 years ago

Hi,

Closing this issue as there is no feedback. Please, ask to reopen if needed. Thanks

Chaot1 commented 6 years ago

Ok, i think this Sensor is not usable for me. Exactly after 50 Minutes it stops working and i have to restart the whole board to get actual data. I think it is a problem on the "Awake" signal. I use a wire to hold it on GND. Maybe it must be switched every n-minutes

moneybag commented 5 years ago

Same problem here, after a couple of hours the sensor is gone. /awake to ground. Interesting: i have to connect and disconnect to usb power a few times until the sensor is recognized.

qingz2004 commented 5 years ago

I have the same problem with version 6.3.0.5. My work around is to connect the rst to a GPIO, and use a rule to toggle the rst every half hour.

pesone commented 5 years ago

I have got it working now for more then 10 Days without any reset or power reboot.

What i did is to increase the value for updating CCS811 to 30 seconds in

sonoff/xsns_31_ccs811.ino > line 43

as my teleperiod is set 30 and i dont need no more measurements meanwhile.

...
#define EVERYNSECONDS 30

void CCS811Update(void)  // Perform every n second
{
...

and to adjust > line 73

  } else {
    // failed, count up
    ecnt++;
    if (ecnt > 2) { 
      // after 60 seconds, restart 
      ccs.begin(CCS811_ADDRESS);
    }

I have set sleep to 250.

qingz2004 commented 5 years ago

I tried it. It does not freeze any more, but the data I got is not realistic. screenshot_5

pesone commented 5 years ago

I have two of them. Both with similar values

22:04:23 MQT: tele/Test/SENSOR = {"Time":"2019-01-25T22:04:23","CCS811":{"eCO2":1309,"TVOC":138}}

22:13:53 MQT: tele/Test/STATE = {"Time":"2019-01-25T22:13:53","Uptime":"11T00:22:33","SleepMode":"Dynamic",...

If open a window for a couple of minutes tvoc value goes near 0

qingz2004 commented 5 years ago

Flash back to original firmware, I get this. screenshot_4

pesone commented 5 years ago

i would suggest to

As said before, my two sensors (Adafruit and a chinese product with no label) seems to work fine and measurements are similar. Another SGP30 delivers completly different values but the curve and peaks are very similar, when i open a window or expose the sensor to voc

Good luck

qingz2004 commented 5 years ago

Grabbed a new Wemos, erased and flashed Tasmota with updated CCS811 driver. I2C were frozen after a few minutes, and the data read out was still bad before frozen.

12:48:18 CMD: i2cscan 12:48:18 MQT: stat/sonoff/RESULT = {"I2CScan":"Device(s) found at 0x5a"} 12:53:13 MQT: tele/sonoff/SENSOR = {"Time":"2019-01-26T12:53:13","CCS811":{"eCO2":7426,"TVOC":1070}} 13:00:32 CMD: I2cscan 13:00:32 RSL: stat/sonoff/RESULT = {"I2CScan":"Error 4 at 0x01"}

mike2nl commented 5 years ago

@Chaot1 @martin072 @gemu2015 @ascillato2 @moneybag

knipsel

andrethomas2 commented 5 years ago

re-opening on request from @mike2nl

mike2nl commented 5 years ago

@gemu2015 Update: there is possible a I2C bus freezing after a certain time. Yes you read it right... I came to that because with another CCS811 sensor i got hat event from all the users too. So far i have seen there are some changings in the core 2.5.0-beta 3 too. When i understand that right and possible that brings other things up.

I found things in the adafruit cpp file in wire.begin. About the use of i2c timeing stretching it can freeze the bus. A certain wwit time (delay) is needed for that to overcome that issue.

And i won't believe it but i found it in the Sparkfun library. Yeah so as always you can't trust all ada libs for 100% because the most libraries are not tested against the esp8266, we all know that ;-)

I will test that tomorrow with the other library from Sparkfun with some changes in the code i think. When this works i will rewrite the whole driver without using a library at all.

Next part we miss a value. Named millis, see data sheet. Have to investigate what that means. We have eCO2 in ppm and TVOC in ppb. So there are more changes to get this straight.

But 1st the timing issue fix. Possible we can fix it shortly (cross my fingers)

andrethomas commented 5 years ago

The datasheet seems to suggest that the host controller needs to have clock stretching enabled.

The behaviour could be because this is not being done and that the CCS811 is holding the I2C bus ransom.

I see it is in the library for the CCS811 as follows

void Adafruit_CCS811::_i2c_init()
{
    Wire.begin();
    #ifdef ESP8266
    Wire.setClockStretchLimit(1000);
    #endif
}

Its not uncommon for slow I2C sensors to require clock stretching so this is fine, but it may be worth playing with a higher value... I cannot find anything specific in the datasheet which should have specified the clock stretch period required and I do not have this sensor so I cannot hook it up to a scope to see if the conditions are met.

The timing mentioned by @mike2nl also seems to be a bit picky as outlined in the datasheet

image

I'm sure @mike2nl has taken all the above into consideration so I'm actually just posting for posterity purposes with the view that it might spark other ideas of what could be going wrong.

pesone commented 5 years ago

Tasmota Version | 6.4.1(sonoff) 2_4_2/2.2.1(cfd48f3)

This is status of my CCS811 adafruit breakout board on a sonoff basic

21:29:03 MQT: tele/Abluft/STATE = {"Time":"2019-01-31T21:29:03","Uptime":"16T04:17:42","SleepMode":"Dynamic","Sleep":250,"LoadAvg":3,"POWER":"OFF",...
21:29:03 MQT: tele/Abluft/SENSOR = {"Time":"2019-01-31T21:29:03","CCS811":{"eCO2":530,"TVOC":19}}

I can't do any measuring, because it is too much effort to remove tit from its place. But i remember that i have to connect

Status of a other breakoutboard CJMCU-8118 see above.

As im not a developer and i don't know what im doing, i can only put in the History of my observations:

what i've done is

It can't be just a coincidence that two different boards start working with no issues, and if i flash back to "standard-tasmota-master" they show the freezing behaviour. This is reproducable at least for me.

andrethomas commented 5 years ago

@pesone Thanks for sharing - I'm sure @mike2nl will find it useful... really wish I had one of these to help out though.

mike2nl commented 5 years ago

@pesone @andrethomas @arendst @ascillato2 @gemu2015 Update for today:

Have to do some things in code to test the first test steps. When the debugging tells me what i wish to see i will look further in it. Also i found out that some of the CCS811 breakout boards have a NTC on board for the temperature compenstation. There is a register to set and i think i have found a way to check for a NTC. Next step will be read the values and after that a define will be given to use a BME280 which is possible used in the same setup. So lots of work but i hope i get it done. BTW: Andre has looked ones over the first idea of code. He means give it a go.

gemu2015 commented 5 years ago

@mike2nl sorry that i can not contribute. i bought this sensor about a year ago together with the sgp30, adapted both drivers and from the beginning i did not have any issues. ( the ccs811 is compensated with a sht3x) i then sealed the sensors with hot glue so that i can not even verify the exact hardware parts involved. comparing both parts at the same location gave very similar curves but sometimes shifted values for both signals.

mike2nl commented 5 years ago

@gemu2015 - no issue at all ;-) @pesone @gemu2015 @ascillato2 @andrethomas Short Update:

Last but not least we have progress now!

qingz2004 commented 5 years ago

Any news on this?

Frogmore42 commented 5 years ago

Most likely this sensor has the same issues I ran into on the SCD30. I believe the underlying issue is poor handling of clock stretching by the esp8266. Even core 2.5.0 does not handle this correctly. Many of the implementations of sensors ignore CRC and other errors which can completely lock up the i2c bus. The good news is that it is possible to recover from that. The library I created for the SCD30 shows one way of checking and reporting errors. The implementation in sensor 42 shows one way of handling the errors and resetting the i2c bus when things get really bad.

gemu2015 commented 5 years ago

there must be sensor hardware differences too. my ccs has absolutely no issues. it now ran for 178 days without any reset.

Tasmota 6.1.1.7, core 2.3, sleep 0

the ccs811 firmware should not be the reason because until recently there was only version 1.1 available.

CCS811 Firmware - Revision History Version Changes

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

Frogmore42 commented 5 years ago

Could be. I believe it is a timing issue. When I had the sensor set to deliver updates every 2 seconds and checked every second it was much more likely to run into the issue. When I had it update every 30 seconds it never happened. When I ignored CRC errors it happened more frequently. When I soft reset the SCD30 after a CRC error I actually got more issues than if I just waited till the next second to check again.

Both sensors use clock stretching and the esp8266 implementation of i2c has known issues, so it is not surprising the sensors have issues on the esp8266.

gemu2015 commented 5 years ago

according to maarten pennings the CSS811 issues on ESP8266 can be solved by a wait just before Wire.requestFrom in the CSS811 read sequence in file Adafruit_CCS811.cpp (see below) since i can not reproduce the issue, may be someone with the issue may test this fix.

void Adafruit_CCS811::read(uint8_t reg, uint8_t *buf, uint8_t num) { uint8_t value; uint8_t pos = 0;

//on arduino we need to read in 32 byte chunks
while(pos < num){

    uint8_t read_now = min((uint8_t)32, (uint8_t)(num - pos));
    Wire.beginTransmission((uint8_t)_i2caddr);
    Wire.write((uint8_t)reg + pos);
    Wire.endTransmission();
            delayMicroseconds(50); // maarten pennings suggestion
    Wire.requestFrom((uint8_t)_i2caddr, read_now);

    for(int i=0; i<read_now; i++){
        buf[pos] = Wire.read();
        pos++;
    }
}

}

qingz2004 commented 5 years ago

Tried. No luck.

Frogmore42 commented 5 years ago

The code show is doing no error checking, so it is not surprising that it is not working. Many examples in the Arduino world are quite simplistic and work great as long as everything goes down the "happy path" (where everything just works all of the time). The CCS811 and the SCD30 are NOT sensors that work with the esp8266 in the "happy path". If you want success with them, the code has to handle the things that can and do happen that are outside the "happy path".

The specific code sample above is only waiting 50 uSec for data to be available before requesting it. That is likely not enough time for the CCS811 to prepare it (at least some of the time). When it does request the data, it doesn't bother to see if the request was actually fulfilled. It just blindly reads the data.

This was what I found in the available libraries for the SCD30. The official library for the SCD30 from Sensiron was a little better, but it had too many dependencies to be easily usable with Tasmota. So, I wrote a new library for it. The code window is not working for me, so look at this: image

The key thing here is checking the result from requestFrom(). The check for available() is not really necessary, since the result from requestFrom() pretty much assures there is data available.

But, this is the section that made it start working for me: image

The key piece is waiting (1ms worked fine for me) between sending the command to the sensor which requests it to send data and actually trying to read data. The examples I saw for Arduino did no waiting and all had issues working with the esp8266. I believe this is due to the underlying issue in the libraries for the esp8266. Waiting seems to work around the issue, at least most of the time.

The code for the SCD30 and the sensor code has additional retry methods and the really big hammer of resetting the whole i2c bus. When I slowed things down for the SCD30, I rarely have to use the really big hammer. Before getting the code working well, I would have to reset every few min at the most. Now, it can go for days without needing to reset the i2c bus.

I don't have a CCS811 and given what I have seen of it and the SCD30, I have no desire to have one. But, the technique I used for the SCD30, should also work the CCS811.

jpduhen commented 5 years ago

@Frogmore42 Since I’m not a programmer, could you please show the particular file to edit and what lines need to change for the CSS811 to get working, when using Platformio to compile Tasmota?

Frogmore42 commented 5 years ago

@jpduhen that would not be easy. The code for the CSS811 does not follow best practices for dealing with hardware (it takes quite a few shortcuts, not a problem … until it is). A quick look at the code shows this function: void Adafruit_CCS811::read(uint8_t reg, uint8_t *buf, uint8_t num)

add a delay between: Wire.endTransmission(); and Wire.requestFrom((uint8_t)_i2caddr, read_now);

I used delay(1); this was enough for the scd30 most of the time. To really solve the problem is going to take someone who is really interested in solving it who has one and enough time and patience to figure out exactly what is going wrong. Making i2c work reliably is not easy in the best of circumstances. Since it seems there are issues with the esp8266 implementation/support of clock stretching, it might be better to get a different sensor.

jpduhen commented 5 years ago

@Frogmore42 I’ll 1st try suggestion one, and let you know if it fixes things, if not, I’ll go for suggestion 2 ;-)

jpduhen commented 5 years ago

@Frogmore42 SUCCESS!! Now 4 hrs stable. I think you nailed it! Schermafbeelding 2019-03-23 om 15 10 55 This is what I edited: Schermafbeelding 2019-03-23 om 15 33 13

Frogmore42 commented 5 years ago

Glad it worked out. I suspect that it will still have issues, but they won't be as frequently.

qingz2004 commented 5 years ago

Does not work form me. Disappeared in 3 hours.

jpduhen commented 5 years ago

14 hours here and still going OK. Do you use 6.5.0 with the 2.3.0-core?

qingz2004 commented 5 years ago

6.4.1.22 with 2.4.2 core. Last not even one hour.

jpduhen commented 5 years ago

I had massive problems with core 2.4.2. Half a year of instability in Wifi connections from my sensors and switches, socket-errors in mosquitto-MQTT. Glad the 6.5.0 release is on core 2.3.0 again. Perhaps you should try it also.

qingz2004 commented 5 years ago

Just tried. Still no luck. Less than 18 minutes. image

Jason2866 commented 5 years ago

@qingz2004 you can try i2c clock streching fix for arduino core https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix Core 2.3.0 is for pitty I2C devices in general not a good choice. Try latest Arduino core stage with the I2C fix It will be finally nailed when the complete rewrite of the driver from @mike2nl is done. When? It is done when it is done ;-)

jpduhen commented 5 years ago

You can also try this fix, then compile Tasmota with Arduino IDE, worked for me earlier: Schermafbeelding 2019-03-24 om 11 09 23

where you can change dir-names according to the core you're using in Ardoino IDE (core 2.3.0, 2.4.2 or 2.5.0) whatever you like using. You have to install these "boards" in Arduino IDE via Board selection - Board manager menu:

Schermafbeelding 2019-03-24 om 11 20 32

and then select your core (here I'm using 2.3.0:

Schermafbeelding 2019-03-24 om 11 21 29

qingz2004 commented 5 years ago

@Jason2866 @jpduhen Thanks for the suggestions, but I'm using PlatformIO.

joba-1 commented 5 years ago

Pio uses the same esp cores, just search for the file yourself. For me it is somewhere below $HOME/.platformio -- iphone so i typo

Jason2866 commented 5 years ago

@qingz2004 i use Platformio too... Search where @joba-1 wrote. It is there ;-)

jpduhen commented 5 years ago

@qingz2004 Yes, found it too:

Schermafbeelding 2019-03-24 om 20 32 49

Frogmore42 commented 5 years ago

Doesn't really do anything since this code follows that: 'void Adafruit_CCS811::_i2c_init() { Wire.begin();

ifdef ESP8266

Wire.setClockStretchLimit(1000);
#endif

}'

jpduhen commented 5 years ago

OK, then this is not a possible solution. @Frogmore42 twi_setClockStretchLimit() is the same variable as Wire.setClockStretchLimit()? I guessed it was a different one. As I said, I'm not a programmer.

Frogmore42 commented 5 years ago

If you want it longer, just change it in the CCS811 code. The SCD30 code I wrote uses a VERY large number. It sort of helps but does not solve the problem always. Maybe when the underlying issue is resolved in the core things will work better. But, errors happen. Not dealing with them doesn't make them go away 😉. Example code rarely deals with errors. That is left as an exercise for the reader.

jpduhen commented 5 years ago

CCS811 still working on my TH10 by the way, 1 day and 14 hrs now:

Schermafbeelding 2019-03-24 om 23 30 43

23:23:29 MQT: tele/TH10/STATE = {"Time":"2019-03-24T23:23:29","Uptime":"1T13:55:34",".... 23:23:29 MQT: tele/TH10/SENSOR = {"CCS811":{"eCO2":1872,"TVOC":224},"PressureUnit":"hPa","TempUnit":"C"}

qingz2004 commented 5 years ago

@Jason2866 Tried i2c clock streching fix for arduino core https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix. Tried both core 2.3.0 and 2.50.0 with PlatformIO, none of them works for me.

jpduhen commented 5 years ago

@qingz2004 That’s frustrating. If you like I can try to build a tasmota-version for you on Arduino IDE, maybe that will fix things for now?