Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for SGP41 TVOC/NOx Sensor #18880

Merged
merged 3 commits into from
Jun 29, 2023
Merged

Conversation

precurse
Copy link
Contributor

@precurse precurse commented Jun 14, 2023

Description:

This adds support for the SGP41 TVOC/NOx sensor and uses the official driver from Sensirion. I was hoping to merge this with the existing SGP40 driver, but it seems that this is non-trivial at this time.

Since this device uses the same I2C ID as the SGP40, it must be enabled with i2cdriver 82 after disabling i2cdriver98 0

Related issue (if applicable): N/A

Checklist:

  • The pull request is done against the latest development branch
  • Only relevant files were touched
  • Only one feature/fix was added per PR and the code change compiles without warnings
  • The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9
  • The code change is tested and works with Tasmota core ESP32 V.2.0.10
  • I accept the CLA.

NOTE: The code change must pass CI tests. Your PR cannot be merged unless tests pass

@precurse precurse changed the title Sensor support for SGP41 Add support for SGP41 TVOC/NOx Sensor Jun 14, 2023
Copy link
Collaborator

@s-hadinger s-hadinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR. It's unfortunate that the official lib does delay() in the code which has very bad effect on the rest of Tasmota. If each sensor lib did the same, devices with multiple sensors could become unusable.

lib/lib_i2c/arduino-i2c-sgp41/src/SensirionI2CSgp41.cpp Outdated Show resolved Hide resolved
lib/lib_i2c/arduino-i2c-sgp41/src/SensirionI2CSgp41.cpp Outdated Show resolved Hide resolved
tasmota/tasmota_xsns_sensor/xsns_109_sgp41.ino Outdated Show resolved Hide resolved
@precurse
Copy link
Contributor Author

precurse commented Jun 17, 2023

Hey @s-hadinger I've managed to split out most of the functions so far. I used the 50ms function to send the sendReadingCmd if there needs to be a reading, which initiates a reading. Then every 1 second, it attempts to read from the device, if there's one pending. This works, for a bit of time, and then finally the whole I2C bus seems to crap out with a {"I2CScan":"Error 4 at 0x01"} error message when I run an i2cscan.

I ran a logic analyzer to trace what was happening, and it seems at some random point, the SGP41 seems to respond with a NACK when the ESP8266 attempts to perform a read command, about 921ms (well after the 50ms minimum requirement) after the write command was issued. After this point the SDA line goes low until I restart Tasmota.

Screenshot here:
image

I'm still learning I2C, but wanted to check if this was behavior you've seen before. I'll keep troubleshooting, but it's very strange behavior. Thanks!

@s-hadinger
Copy link
Collaborator

Thanks, I'm not familiar enough with I2C but this doesn't seem familiar

@precurse
Copy link
Contributor Author

precurse commented Jun 18, 2023

Thanks, I'm not familiar enough with I2C but this doesn't seem familiar

The SGP41 board I bought had a pull-up resistor for SDA and SCL, which I'm sure was causing the issue. The ESP8266 already has an internal I2C pull-up, so having 2 in parallel is not good. I cut the traces to it on my SGP41 board and so far it's been stable. Once I know it's stable, I'll update my PR with the new code :)

@precurse precurse force-pushed the sgp41 branch 3 times, most recently from fc0ef41 to 9428cc6 Compare June 19, 2023 01:35
@precurse
Copy link
Contributor Author

precurse commented Jun 19, 2023

Alright, I got it @s-hadinger . I've had this driver running for a while and it's running nicely. I removed the delay() and Serial.print() use. Let me know if there's anything else that you'd like to see fixed.

I've also found a clever way of testing for an SGP40 vs SGP41, so I'm going to work on that next. The drivers are nearly identical, except for one function that SGP40 uses differently. This should allow for a universal SGP4x driver, without the need to manually handle drivers.

This is the change I made to add the SGP40 detection in this driver, in case anyone wants to test it: precurse@f877b20 -- I'm confident it'll work, but need to be 100% sure before I PR it.

@precurse
Copy link
Contributor Author

Hey @s-hadinger , the SGP41 sensor has been running for quite a few days and working reliably.

I just cleaned up some of the other Tasmota markdown files, JSON/web output to use i18n values, and confirmed the driver works on the ESP32 platform. I started to use SGP4X consistently throughout, which is the basis for the universal driver once I receive my SGP40 to confirm.

Let me know if anything else needs to be fixed up!

@Jason2866
Copy link
Collaborator

The SGP41 board I bought had a pull-up resistor for SDA and SCL, which I'm sure was causing the issue. The ESP8266 already has an internal I2C pull-up, so having 2 in parallel is not good. I cut the traces to it on my SGP41 board and so far it's been stable. Once I know it's stable, I'll update my PR with the new code :)

Thats weird. Since i2c is a bus it needs terminating. The internal pull up resistor of the esp8266 is so high that it is not enough to terminate the i2c bus correctly. AND it is no problem to have both active.

@Jason2866
Copy link
Collaborator

@TD-er Do you have experience with the Sensirion SGP41?

@precurse
Copy link
Contributor Author

Thats weird. Since i2c is a bus it needs terminating. The internal pull up resistor of the esp8266 is so high that it is not enough to terminate the i2c bus correctly. AND it is no problem to have both active.

I thought the D1 Mini had an internal I2C pull-up, but may have been mistaken then. It's possible the SHT3X board I have soldered has an I2C pull-up as well, since I'm reading 10K ohms across VCC and SDA/SCL.

@Jason2866
Copy link
Collaborator

Thats explains it.

@s-hadinger s-hadinger merged commit eb655a4 into arendst:development Jun 29, 2023
@hoanglongutc
Copy link

hoanglongutc commented Aug 27, 2023

I thought the D1 Mini had an internal I2C pull-up, but may have been mistaken then. It's possible the SHT3X board I have soldered has an I2C pull-up as well, since I'm reading 10K ohms across VCC and SDA/SCL.

Hi,
Have you tested on nodemcu esp8266?

@sfromis
Copy link
Contributor

sfromis commented Aug 29, 2023

Should simply be the standard I2C SCL and I2C SDA pins, nothing special for each type of I2C sensor.

@hoanglongutc
Copy link

Should simply be the standard I2C SCL and I2C SDA pins, nothing special for each type of I2C sensor.

Thank you for your reply, I am putting sgp41 sensor, not sure if I2C will run stably on ESP8266 nodemcu?
image

@sfromis
Copy link
Contributor

sfromis commented Aug 29, 2023

I2C works fine on my ESP8266 devices, including NodeMCU dev boards.

@hoanglongutc
Copy link

I2C works fine on my ESP8266 devices, including NodeMCU dev boards.

HI, I am using version "Program Version 13.1.0(sensors)" does it support sgp41 sensors?
I have connected and configured i2c, however I don't see the sensor appear
when running the i2cscan command:
MQT: stat/xxx/RESULT = {"I2CScan":"No devices found"}
Looking forward to your support. Thanks

@barbudor
Copy link
Contributor

barbudor commented Sep 6, 2023

"No device found" start very bad
Whether the right driver is there or not, whether it is enabled or not, i2cscan should return a result
Start by fixing your hardware

@hoanglongutc
Copy link

hoanglongutc commented Sep 7, 2023

"No device found" start very bad
Whether the right driver is there or not, whether it is enabled or not, i2cscan should return a result
Start by fixing your hardware

I also suspect the hardware is faulty, I'm ordering another piece of hardware. Thank you

@TD-er
Copy link

TD-er commented Sep 7, 2023

Some tips for I2C:

  • Not too long wires (typically upto few decimeters)
  • Use wires of same length for SDA and SCL
  • Use pull-up resistors between SDA/VCC and SCL/VCC. Typically 4k7 or 10k.
  • When using longer cables, you may consider twisted cable, where you twist SDA with GND in a pair and SCL with GND in another twisted pair. Something like UTP cable is fine for this.
  • Lower I2C clock to 100 kHz when seeing lots of errors and/or using long cable.

@hoanglongutc
Copy link

hi,
I changed a new sensor, when I ran i2scan the results came back, but tasmota still hasn't recognized the sensor. Look forward to the help
image

image
image

@sfromis
Copy link
Contributor

sfromis commented Sep 19, 2023

As visible on the I2CDriver output, the driver number 82 is not included in the binary you're running, You need a custom build including
#define USE_SGP4X
(The driver is also default-included for ESP32 builds)

@sfromis
Copy link
Contributor

sfromis commented Sep 19, 2023

https://tasmota.github.io/docs/Compile-your-build/

@hoanglongutc
Copy link

I tried using ESPHOME, everything worked normally (this proves that the hardware and connection are not the problem causing the error).
image

@Jason2866
Copy link
Collaborator

https://tasmota.github.io/docs/Compile-your-build/

really confusing, when I rebuild the custom version i2cscan can't find the device. image

Disable all other i2c drivers. See https://tasmota.github.io/docs/I2CDEVICES/#management

@precurse
Copy link
Contributor Author

precurse commented Sep 19, 2023

https://tasmota.github.io/docs/Compile-your-build/

really confusing, when I rebuild the custom version i2cscan can't find the device. image

Disable all other i2c drivers. See https://tasmota.github.io/docs/I2CDEVICES/#management

Specifically the 69 driver (for the SGP40): i2cdriver69 0 should do it.

I'm working at merging both SGP40 and SGP41 drivers together, so we can avoid having to do this. I just haven't got around to it quite yet :)

@hoanglongutc
Copy link

Based on your suggestion I solved the problem, thank you very much

@deepbass909
Copy link

deepbass909 commented Apr 10, 2024

I believe the driver is sending out the wrong value for Domoticz. I've configured the value of Sensor idx 9 AirQuality for Domoticz, but receive the raw sensor-value, which isn't of any use in Domoticz. Instead the "SGP40 Air quality" is needed.

I believe the issue lines in the file xsns_109_sgp4x.ino lines 222 - 224, that state the wrong parameter for Domoticz. If I'm reading the source code correctly, the value needs to be the calculated voc_index_sgp4x.

#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) DomoticzSensor(DZ_AIRQUALITY, srawVoc);
#endif // USE_DOMOTICZ

Could this me changed, or make all 3 values available for the SGP40 and 4 for the SGP41?

arendst added a commit that referenced this pull request Apr 11, 2024
RaphDaMan pushed a commit to RaphDaMan/Tasmota that referenced this pull request Sep 10, 2024
* Initial support for SGP41

* Removing delay() use from SGP4x driver

* Using i18n for TVOC/NOx raw values as well
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants