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.72k stars 4.72k forks source link

DHT11 fractional temperature is ignored #3164

Closed hydrogen18 closed 5 years ago

hydrogen18 commented 6 years ago

Describe the bug

I bought some Sonoff Basic from AliExpress along with DHT11 sensors. I got Tasmota installed and a DHT11 installed. I saw temperature readings immediately, but they have only 1 C resolution while the device is capable of higher.

I tracked this down in the code to this line https://github.com/arendst/Sonoff-Tasmota/blob/v6.1.0/sonoff/xsns_06_dht.ino#L161

t = dht_data[2];

So the conversion consists of promoting a uint8_t to a float and calling it done. As far as I can tell the internet believes these devices don't output anything but zero for the last byte. For example: http://sheepdogguides.com/arduino/ar3ne1humDHT11.htm

But here are my log lines from that file I see in the web console.

18:03:53 DHT: Received 53, 00, 1B, 05, 73 =? 73
18:03:55 DHT: Received 56, 00, 1B, 06, 77 =? 77
18:03:59 DHT: Received 58, 00, 1B, 09, 7C =? 7C
18:04:02 DHT: Received 5B, 00, 1C, 03, 7A =? 7A
18:04:05 DHT: Received 4F, 00, 1C, 04, 6F =? 6F
18:04:09 DHT: Received 45, 00, 1C, 06, 67 =? 67

So obviously I am seeing non-zero for the last byte. It is 0x0 - 0x9 in value. So it's fractional decimal. I refactored the code to be the following

      t = dht_data[2];
      for(uint8_t i = dht_data[3]; i != 0; i--){
        t+= 0.1f;    
      }

And the readings I get now have tenth of a C resolution and make sense as well.

The DHT11s I got are nothing special, just the cheapest thing on AliExpress as of a week or two ago.

Here are images of my setup

img_20180708_115708 img_20180708_115635

If you will accept this change, I will submit a pull request

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

To Reproduce Use a DHT11 sensor, observe you only get 1C resolution

Expected behavior Use a DHT11 sensor, get the 0.1C resolution the sensor provides

reloxx13 commented 6 years ago

read the wiki, read the user_config.h file, search for resolution. TempRes 0..3 stop wasting your time, drink a beer 🍺

hydrogen18 commented 6 years ago

All that does is become the "precision" that is passed into this function

https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42

That number could be 100, it'd just show 100 zero's after the decimal. You cannot create the fractional component of a temperature sensor with a library function.

andrethomas commented 6 years ago

I'm not sure fractional precision on a DHT11 is useful anyway - the value will just jump all over the place anyway... the DHT11 is about as stable as a donkey on steroids!

If you want precision rather use a BMPxxx/BMExxx sensor or even an LM75AD - they are fairly cheap and much more reliable in terms of accuracy and hysteria on temperature reporting.

andrethomas commented 6 years ago

@hydrogen18 Did you do some output logging to check the stability of results when adding 0.1-degree resolution?

andrethomas commented 6 years ago

Mine outputs 00's

image

Frogmore42 commented 6 years ago

I don't have any DHT11s. I read about their accuracy (or rather lack there of) and decided there were better choices. Years ago, I got a really good deal (for the time) on SHT-15 sensors. I think I got them for $15/each when they were normally about $50/each. Today, I can get an HTU21 for about $8 with two day shipping and a BMP280 for a dollar or two more. They are all worth the extra money over the DHT11 or even DHT2x.

If you are interested in learning more about the accuracy of different sensors, I suggest looking here: http://www.kandrsmith.org/RJS/Misc/hygrometers.html Robert has done an excellent job of documenting his experience and experments with many different sensors.

If the sensors you have are repeatable and reasonably stable having greater resolution can be a good thing, even if absolute accuracy is not so good. As an example, the DS18B20 has an accuracy spec of about +/-1 deg F. Given that, one might think it would make no sense to see/use anything smaller than full degrees. But, I have found them to be very stable. So I use the full resolution and make heater control decisions based on the smallest difference from the set point. Since I am not using a large furnace for heated, I am not concerned about short cycling and prefer it. However, for my dehumidifier, it is most efficient when it runs for a long time. So, I make sure it has been running for at least 30 min. This means that the actual humidity differs from the set point most of the time, but average is close to it. Since it is for moisture control, this works well and saves money.

So, if I had a DHT11 and I found it had stable and repeatable readings, I would think your change makes sense.

arendst commented 6 years ago

@hydrogen18 nice write-up but...

hydrogen18 commented 6 years ago

@arendst I haven't read the spec sheet for the DHT22 but the code used to compute its value is different. Here's the code for the DHT22

t = (((dht_data[2] & 0x7F) << 8 ) | dht_data[3]) * 0.1;
      if (dht_data[2] & 0x80) {
        t *= -1;
      }

This looks rather different, don't you agree? I'm not sure what they are trying to implement.

With respect to your comment about the sensor, I think you are confusing accuracy vs precision ( I don't know the Dutch words) . Here is a good example of the difference:

https://labwrite.ncsu.edu/Experimental%20Design/accuracyprecision.htm

I don't have any equipment other than a typical Type K thermocouple, so it'd be difficult for me to characterize one of these sensors. But my point is they can have very high precision while still having a poor accuracy of +/- 2 C.

andrethomas commented 6 years ago

@hydrogen18

t = (((dht_data[2] & 0x7F) << 8 ) | dht_data[3]) * 0.1; ** gets byte 2 and 3 to get 10th fractions as you would expect
      if (dht_data[2] & 0x80) { ** checks if the temperature is negative?
        t *= -1;
      }

Again, the results on the DHT11's I have appear to contain nothing in data[3] as quoted earlier up

image

andrethomas commented 6 years ago

@arendst @hydrogen18 I guess since there is contrast in information available on the DHT11 insofar that some of them provide data in data[3] and others provide a 0 in data[3] (such as the ones I have tested)

Knowing this, adding a PR or manual edit to add code of @hydrogen18 would not imact negatively on sensors which provide a 00 on data[3] anyway, so it will either have 10th temperatures, or not have them depending on whether the sensor sends datain [3]

The two lines suggested by @hydrogen18 will not negatively impact so either add it manually or @hydrogen18 must make a PR for it - Then its fixed at least for those people who are lucky enough to have sensors that provide data in data[3]

Suggestion is therefore to add the following code as it has no negative impact on sensors that do not produce data in data[3] but may have befits for those that do.

for(uint8_t i = dht_data[3]; i != 0; i--){
        t+= 0.1f;    
      }
arendst commented 6 years ago

Updated DHT driver.

Give it a try and let me know the results.

andrethomas commented 6 years ago

@hydrogen18

I think the original code was written with this one in mind: https://osepp.com/wp-content/uploads/2015/04/DHT11-Technical-Data-Sheet-Translated-Version.pdf

In that, it only mentions 1degC image

I think it may be possible that your DHT11 actually contains the same chipset as a DHT12, which has been referenced to provide 0.1 deg C resolution... e.g.

http://www.robototehnika.ru/file/DHT12.pdf

image

In either event, let us know what happens with the code change that was made.

hydrogen18 commented 5 years ago

Hi, I have not had time to test your changes yet.

@andrethomas I agree this is probably a DHT12 labeled as a DHT11. No real reason for a factory to bother manufacturing both.

ascillato2 commented 5 years ago

Hi,

If your question has been addressed, please close this issue. Thanks :+1: