esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 36 forks source link

SHT3X-D reports too high temp / too low humidity readings #2887

Closed phrozen77 closed 1 year ago

phrozen77 commented 2 years ago

The problem

As per the title, i've rebuilt a few sensors https://www.airgradient.com/diy/ and flashed them with ESPHome (project: https://github.com/ajfriesen/ESPHome-AirGradient ).

I've built 3 of these sensors and all are reporting figures in the same ballpark:

Readings should be (sensors placed in the cellar, these values come from a Homematic HM-WDS40-TH-I-2):

Edit to add:

I've reflashed one of the sensors with the "original" Airgradient firmware - the values it displays are different (slightly more correct - instantly) than with ESPHome:

So, clearly, Airgradient does - in the very same location - something different with the sensors readings - but imho not entirely correct. I'd still consider the Temperature being off by 2°C and Humidity being off by 10% not being acceptable.

I've found an old, stale bug report that is about the heater being on that may be responsible for such stark difference in readings, even after leaving them to their own for more than 24 hours: #1465

So, as such, i'd like to re-open / re-report the same finding and would like to request a way to query / set the heater status.

Thanks!

Which version of ESPHome has the issue?

2021.12.1

What type of installation are you using?

Home Assistant Add-on

Which version of Home Assistant has the issue?

2021.12.6

What platform are you using?

ESP8266

Board

Wemos D1 mini

Component causing the issue

SHT3X-D

Example YAML snippet

No response

Anything in the logs that might be useful for us?

No response

Additional information

No response

Warter21 commented 2 years ago

Flashed yesterday with 12.2 and the values are correct.

jesserockz commented 2 years ago

The code has not changed for the sht3xd component for a while now.

All ESPHome does is takes the raw data and offsets it by a fixed value:

float temperature = 175.0f * float(raw_data[0]) / 65535.0f - 45.0f;
float humidity = 100.0f * float(raw_data[1]) / 65535.0f;
phrozen77 commented 2 years ago

Well, l'm currently (since about 5 hours) conducting a small-ish experiment - i've enclosed the two SHT31-D based sensors along with the aforementioned Homematic HM-WDS40-TH-I-2 and another cheap noname humidity/temp sensor in an airtight container, along with a 72% Boveda (basically a 2-way membrane, absorbing and "exhaling" humidity, usually used to condition cigars - https://bovedainc.com/ ).

This is the setup (yes, those USB cables are suffering, all 4 flaps are locked in place):

IMG_7801

So, what do we have here?

lower left: Airgradient middle: ESPHome

Funny enough, being locked in a container next to each other, at least both do agree on what to display.

right, silver: Homematic HM-WDS40-TH-I-2 upper left, white: cheap noname h/t sensor (433Mhz)

Homematic: 22,5°C - 73% Cheap nn: 23,7°C - 74% Airgradient: 29°C - 50% ESPHome: 29°C - 50%

It's pretty warm in the living room now, however sure as hell its nowhere near 29°C, i and my SO would be melting.... Also the 50% humidity reading, while both do agree on something, also is pretty certainly off...

I'll keep them that way for a little while longer....

phrozen77 commented 2 years ago

Any thoughts?

jesserockz commented 2 years ago

Unfortunately I am unable to help as I do not have these sensors and not sure how they work.

jckkk commented 2 years ago

I guess that the sensor is just being heated by the ESP. You could try checking the readings right after the start (when ESP is cold). If that's the case using deep sleep could work around the issue. Or increasing the distance between the sensor and the ESP.

phrozen77 commented 2 years ago

Really? I don't think the ESP gives off any kind of noticeable heat...

Also, fwiw, the measured values don't change much after plugging in the whole contraption :(

jckkk commented 2 years ago

Really? I don't think the ESP gives off any kind of noticeable heat...

It does and in my experience it can alter the readings by a few degrees.

jpcornil-git commented 2 years ago

FWIW, I received my M5stick Cplus + ENV III hat yesterday and observed the same things, i.e. temperature too high (~5C in my case)/humidity too low => ran an experiment with a "floating" ENV III and you can clearly see a difference, see picture below (USB charging or not is also playing a role):

HA-sht3x graph

I also ran a test without esphome (I started yesterday with esphome and have therefore no ideas about CPU usage and related power consumption) and temperature reading matches what esphome reports:

HA-sht3x i2ctools

phrozen77 commented 2 years ago

Ok, lets see what i can come up with - i've just placed a piece of corrugated cardboard between the sensor and the ESP.

I've measured the ESP (Wemos D1 Mini) with an IR Heat "gun-style" thermometer and it was a little under 30°C after running continously... So, yes, in close proximity this may have an effect...

jpcornil-git commented 2 years ago

The heat is radiated but also propagated by conduction thru supply/ground wires, latter is the likely main contributor in my case (more of a "sidecar" than a 'hat')

DannyN2222 commented 2 years ago

hi, according to the datasheet (https://www.mouser.com/datasheet/2/682/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital-971521.pdf - section 4.10) the heater can be turned on and off by i2c command 0x30 then 6D for on and 66 for off, i have no idea how the compensation will work as again according to the datasheet (section 2.1) the heater power consumption depends "on the supply voltage" while will almost certainly affect the heat output and therefore the offset required, this however can be eaisly offset by the sensor filters tho, and possibly if people contribute how far offset there sensors are we may be able to build up a table of typical values to put as a starting point for others to use on the wiki? however one thing im not sure if all of us are missing tho is that according to the datasheet (section 4.10) "After a reset the heater is disabled (default condition)." so if the heater is never told to be on by esphome, it will be off so i dont think this is the root cause of this issue (tho the heater should still be added as it will be useful for when this sensor is used outdoors) unforchanelty I've barely done any coding so while i can read the datasheet i cant really contribute to achally adding this to the code but once i add a bme280 right next to my sht31 ill be able to provide the offset for my sensors at 5v (since its comming from china it will take a while tho)

DannyN2222 commented 2 years ago

ok so had a quick look at the code to see if there is anything i may be able to suggest (maybe copy paste from the sht40 sensor which does have the heater in esphome) and in sht3xd.cpp (https://github.com/esphome/esphome/blob/dev/esphome/components/sht3xd/sht3xd.cpp) on line 11 and 12 the commands to turn the heater on and off are literally right there but im guessing never called or exposed on the yaml, looking at how the heater function works in sht4x.cpp and how other commands are sent in sht3xd.cpp i think all you would need to add would be ( void SHT3XDComponent::heater() { if( IDK what to put here) { ESP_LOGD(TAG, "Turning heater on"); this->write_command(SHT3XD_COMMAND_HEATER_ENABLE); } else { ESP_LOGD(TAG, "Turning heater off"); this->write_command(SHT3XD_COMMAND_HEATER_DISABLE);

andf then make the changes in sht3xd.h but i really do not get how this file works (im tring to use the sht4x file as a reference but dont see how heater_power = High in yaml is converteted to the value "SHT4X_HEATERPOWER_HIGH" so cant relly do anything to suggest anything here as my non-existant programming knowledge is well past its limits at his point anyways i hope im on the right tracks and have made the changes needed really easy for someone who knows what they are doing to make the changes to fix this bug

jpcornil-git commented 2 years ago

@DannyN2222 Not sure heater is related to this issue (system heat leading to a temperature offset, not a device/code bug).

Heater should be off after reset and may be used to mitigate effect of condensing moisture when reading humidity, good description here: https://web.cecs.pdx.edu/~gerry/class/feather_sense/on-board/tempRH/#run-the-sht31testino-sketch-from-the-adafruit-library

DannyN2222 commented 2 years ago

heater is related as this bug superceds bug https://github.com/esphome/issues/issues/1465 and it states in the original report "So, as such, i'd like to re-open / re-report the same finding and would like to request a way to query / set the heater status."

jpcornil-git commented 2 years ago

OK, I'll have a look at this (default state for heater is off and nothing as I can see in the code is turning it on but I'll read status to make sure it is what it is supposed to be and enable/disable it to see how it affects temperature/humidity).

DannyN2222 commented 2 years ago

TY, ill be honest im 99% sure its not running, expacally if you power it with 3.3V as on the datasheet it lists the min operating voltage of the heater as 4.5V, but it would be a nice thing to be able to turn the heater on and off so you can have the option and use the sensor more reliably in high humidity low temperature environments (like outdoors in winter) as i said before it looks like the commands are already in ESPHome it just needs to be called and brought to the GUI (im sure this is easier said than done tho) i had as much of a go as i can but ive never really coded and cant see how esphome brings stuff to the yaml ether

jpcornil-git commented 2 years ago

Just checked (added a heater status sensor and set heater on/off as configuration parameter) and default heater status is off as expected, temperature increase by a few degrees when enabled.

sht3x and sht4x heater implementations are different; the former is just a switch with no settings (see sht3x datasheet 4.10 p12) while the latter is a timer enabling the heater at some level for some time (see sht4x datasheet 4.9 p12).

You can't leave sht4x heater on all the time for reliability reasons (max 10% of sensor's lifetime for sht4x) and I guess it is the same for sht3x. You would therefore have to mimic sht4x timer/activation duty-cycle in esphome (without heater_power option) and it is not clear from sht3x datasheet how heater and measurement are affecting each others wrt e.g accuracy

DannyN2222 commented 2 years ago

TYSM i do have a second of the SHT31 in the mail so once i get this ill have a bme280 and 2xSHT31's so once i get the offsets vaguely in line with each other i should be able to test this and provide my results here
I can say that i defo think that it does affect it as you can see on the graph at the bottom on the link that jpcornil-git sent a fe comments back (https://web.cecs.pdx.edu/~gerry/class/feather_sense/on-board/tempRH/#run-the-sht31testino-sketch-from-the-adafruit-library) unforchanelty its a sample size of 2 but its a start and should hopefully make this sensor one of the few thats useable outdoors long term, as it seems all humidiy sensors without heaters have problems with dying due to condensation / dew building up inside them - the enabling the heater should prevent this from happening. ofc now all i need if you the change to be merged and the sensor to come

mdunda commented 2 years ago

I also encoutered this problem. My SHT3xD sensors report approx 2.5 °C too high. Today I put three of them in the same spot and all three reported approx. 23.5 °C. As the room does not "feel" that warm, I cross-checked with an IR-thermometer and an off-the-shelf LCD thermometer which both showed slightly above 20°C.

I then attached one of the three sensors to a Raspberry Pi and read it out using the Adafruit_Python_SHT31 example. With this setup I get appropriate results of 20.2 °C.

As the method (command 0x2400) and the conversion are the same in both libs, there might be an issue in the asynchronous retrieval of ESPhome (set_timeout method of the Scheduler class).

Edit: This is with version 2022.8.3 of ESPhome. Sensor is connected to a Wemos D1 mini ESP8266, and there's nothing else connected to the board.

jpcornil-git commented 2 years ago

@mdunda Did you attach the SHT3xD sensors to the RPi and Wemos D1 mini ESP8266 the same way, e.g. flying wires, or are the sensors attached directly to the Wemos pin header ?

If the latter it will be much easier for heat to flow from the Wemos board to the sensor and affect/increase its temperature while flying wires should help with that as well a priori.

Why do you suspect set_timeout (read sensor value 50ms after issuing the SHT3XD_COMMAND_POLLING_H/0x2400 command while datasheet says 15ms max., cfr. 2.2 Timing Specification for the Sensor System page 5) ?

mdunda commented 2 years ago

Hi, in both cases the sensor was attached with flying wires. I also took care of placing the sensor to the side of the board, so it is outside of potentially warm air going up from the CPU/MCU.

I suspect set_timeout because it is the only difference at this point. set_timeout with the included lambda makes the retrieval asynchronous, doesn't it?

I plan to record some curves with a scope later this day for both cases...

jpcornil-git commented 2 years ago

Yes, from what I can see, the set_timeout function put the lambda function/code and associated timeout parameters as a new item in the scheduler queue and the scheduler is executer from the main app loop.

All of this seems to run properly, i.e. consistent sensor values/no data corruption but you could use an active wait/blocking code to challenge the current implementation.

I guess that the Wemos board and therefore pins of the header are probably running at a higher temperature than the RPi ones given its (smaller) size.

mdunda commented 2 years ago

Retrieval is indeed different in the Adafruit example. Both send a write command with address 0x2400. Then for querying the answer, ESPhome sends a read command and received 6 bytes (two 16bit words with 8 bit CRC) - just like written in the datasheet. The Adafruit lib on the other hand first sends a write command and transmits a 0x00 byte followed by the read command and reception of 6 bytes. Maybe some older Sensirion sensors required this - IDK. Anyhow there is nothing spooky to see in the curves.

jpcornil-git commented 2 years ago

Could you comment out the extra write command in the adafruit case to check if it make à différence ?

mdunda commented 2 years ago

I guess there's no further need to investigate: I changed my program in the sense that the module isn't alive all the time reporting the temperature every 60 seconds, but instead uses the deep sleep to wake up every 5 minutes and make one measurement, thus not heating up that much. And surprise, surprise: measured temperature is at an appropriate level.

Honestly I didn't expect that because the sensor is about 5 cm away from the D1 mini board. I know the MCU heats up to around 30°C but I thought the distance would be sufficient.

Because I'm curious I will take one of my sensors to my workplace and take a look with a FLIR camera to see if this really is thermal conduction over the wires.

Generally I will change all my temp/hum sensors to a deep sleep 5 min duty cycle. In the end this also saves energy.

jpcornil-git commented 2 years ago

Thanks for the feedback; this seems to confirm that heat flowing from the Wemos module is indeed the root cause (metal is a good thermal conductor ...).

I'm interested by your FLIR camera measurements (curious to see if this is coming from gnd/most likely [pcb T] or from signals [die T]) and see if a heatsink (on gnd) could help to mitigate this (when deepsleep is not an option)

mdunda commented 2 years ago

FLIR2978 The heat is mostly evenly conducted over all wires.

mdunda commented 2 years ago

FLIR2974 Detail view of the wires without the hot D1 mini. The sensor breakout is obviously a lot warmer than the ambient temperature is.

mdunda commented 2 years ago

FLIR2976 And to make it complete a picture of the hottest parts on the bottom of the PCB. ;-)

mdunda commented 2 years ago

FLIR2972

jpcornil-git commented 2 years ago

Thanks for the pictures Matthias, great job; you clearly see that the sensor breakout temperature is close to the temperature of the vdd/gnd/sda/scl wires (rather than ambient) and heat is conducted from the wemos pcb.

Adding a heatsink to the wemos pcb (Rhs1 below) and/or sensor pcb (Rhs2 below) to lower temperature should help mitigate this a bit as natural pcb (Rca1/2 below) to ambiant thermal resistance is high.

Thermal circuit diagram:

image

CoryMnvl commented 1 year ago

I'm leaving this here in case someone else has a similar issue, and the related pull request mentions this issue.

I updated ESPHome from 2023.8.3 to 2023.9.1 today and my 3 sht3xd sensors immediately jumped between 3.1 and 4.9 degrees Fahrenheit (the low one is outside). The device logs show an elevated Celsius number. I tried rebooting the devices, and sending another update, but neither made a difference.

I noticed on the ESPHome sht3xd page that "heater_enabled" defaults to true. Adding heater_enabled: false to my configuration restored the old expected temperatures.

lexiconzero commented 1 year ago

I'm leaving this here in case someone else has a similar issue, and the related pull request mentions this issue.

I updated ESPHome from 2023.8.3 to 2023.9.1 today and my 3 sht3xd sensors immediately jumped between 3.1 and 4.9 degrees Fahrenheit (the low one is outside). The device logs show an elevated Celsius number. I tried rebooting the devices, and sending another update, but neither made a difference.

I noticed on the ESPHome sht3xd page that "heater_enabled" defaults to true. Adding heater_enabled: false to my configuration restored the old expected temperatures.

This solved my exact issue - I was seeing a 4 degree Celsius increase. Adding a few more words to increase searchability

I have the sht3xd in an airgradient device and the temperature was reading too high.

kevin-david commented 1 year ago

Thanks @CoryMnvl and @lexiconzero for reporting this issue - I was also surprised to see this increase (and corresponding decrease in relative humidity) after a firmware upgrade on my AirGradient DIY device. I created https://github.com/esphome/esphome-docs/pull/3237 to at least document this behavior.

Strangely, this only affect one of my two devices. Not sure what logic is deciding to turn it on or off. edit: was looking at the wrong thing

jcastro commented 1 year ago

I'm experiencing the same, setting heater_enabled: false fixed the problem. platform: sht3xd

Markup 2023-10-08 at 16 40 50
MallocArray commented 1 year ago

Why is heater_enabled defaulted to true, when the datasheet shows in section 4.10 and in the Bit table under 13 that it defaults to 0 or disabled? https://www.mouser.com/datasheet/2/682/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital-971521.pdf

CoryMnvl commented 1 year ago

Why is heater_enabled defaulted to true, when the datasheet shows in section 4.10 and in the Bit table under 13 that it defaults to 0 or disabled? https://www.mouser.com/datasheet/2/682/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital-971521.pdf

I too would have really preferred having heater_enabled default to false to reflect the hardware default as well as minimize disruption for existing users. I may have missed it, but I also didn't find any mention of a potentially breaking change, or any change at all, for SHT3X-D before applying the update. So this change seems to have slipped through unnoticed.

aarontc commented 1 year ago

Why is heater_enabled defaulted to true, when the datasheet shows in section 4.10 and in the Bit table under 13 that it defaults to 0 or disabled? https://www.mouser.com/datasheet/2/682/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital-971521.pdf

I too would have really preferred having heater_enabled default to false to reflect the hardware default as well as minimize disruption for existing users. I may have missed it, but I also didn't find any mention of a potentially breaking change, or any change at all, for SHT3X-D before applying the update. So this change seems to have slipped through unnoticed.

I also eagerly awaited a "fix" for this, as I presumed ESPHome 2023.8/9 had introduced an erroneous breaking change that went undocumented. After updating, I noticed all my AirGradient devices registered impossibly high temperatures and assumed a bug had been introduced into ESPHome driver code. I finally found this thread and understand now what the problem is. I must say, introducing a new feature with a default that doesn't conform to how the hardware normally works is, at best unexpected and, at worst, a bug as it causes a poor user experience. Not mentioning it in the changelog made it very difficult for me to track down what was going on. Thanks for adding the search keywords!

kevin-david commented 1 year ago

@rufuswilson based on the links to this issue - it seems like you may have authored this change? was the change in default to true intentional?

ChillingSilence commented 1 year ago

Ohman, this explains why things have been going so horrifically poorly lately! 🤦‍♂️ Before: image

After adding heater_enabled: false (and waiting ~90 seconds): image

I couldn't work out why it started happening all of a sudden, and why the M5Stack ENV.III sensor that had previously been pretty spot on was now absolutely terrible. Where normally the QMP6988 is only +/- 0.1C out from the SHT30, it was now showing differences of ~4C. It was also impacting the QMP6988s readings in my circumstance too, being that they're in the same ENV.III unit (as shown by the ~1.5C drop there too).

I was almost the point of ripping them a dozen or so of them out, and installing SCD40s instead, especially as accurate humidity calculation is quite important to me.

No idea why heater_enabled is on by default now when it never was before, that's a pretty breaking change that is no doubt also causing MANY headaches for others. Would support that change being reverted back to heater_enabled: false, by default.

And hey I'd be more than happy to mail you some M5stack sensors @jesserockz if you ever wanted to play with them (and keep), I'm in Auckland so it's no trouble.

jesserockz commented 1 year ago

Apologies to all those having an issue with this. 2023.10.0 already switches the heater_enabled to false by default. https://beta.esphome.io/changelog/2023.10.0.html#breaking-changes

@ChillingSilence DM me on discord? Same username.

ChillingSilence commented 1 year ago

Brilliant! Will give the beta a whirl, thankyou @jesserockz

ChillingSilence commented 1 year ago

Confirming that things are happy / fixed with the change. Many thanks @jesserockz