dotnet / iot

This repo includes .NET Core implementations for various IoT boards, chips, displays and PCBs.
MIT License
2.15k stars 581 forks source link

DHT22 often get Nan and temperature is wrong #818

Closed oblin closed 4 years ago

oblin commented 4 years ago

Code:

        using (Dht22 dht = new Dht22(4))
        {
            for(int i = 1; i < 100; i++)
            {
                Console.WriteLine($"Temperature: {dht.Temperature.Celsius.ToString("0.0")} °C, 'Humidity: {dht.Humidity.ToString("0.0")} %");

                Thread.Sleep(5000);
            }
        }

Result: Temperature: NaN °C, 'Humidity: NaN % Temperature: 3.9 °C, 'Humidity: 54.8 % Temperature: 4.0 °C, 'Humidity: 54.9 % Temperature: 3.9 °C, 'Humidity: 54.8 % Temperature: NaN °C, 'Humidity: NaN % Temperature: NaN °C, 'Humidity: NaN % Temperature: 14.3 °C, 'Humidity: 3304.3 %

But using Adafruit_Python is: Temp=28.5* Humidity=54.0%

Which python is corrected.

Please help, thanks.

ghost commented 4 years ago

Im getting the same behaviour. Just installed a fresh Raspberry Pi 3 Model A+ with Raspbian Buster(Debian 10).

Installed .net core SDK and trying out the sample code just like above.

Getting readings after the first two tries. Looks like some delay before measurements gets recieved.

Temperature: NaN °C, 'Humidity: NaN % Temperature: NaN °C, 'Humidity: NaN % Temperature: 23.4 °C, 'Humidity: 44.7 % Temperature: 23.3 °C, 'Humidity: 44.7 %

krwq commented 4 years ago

This is similar to https://github.com/dotnet/iot/issues/748

@maloo do you perhaps know if https://github.com/dotnet/iot/pull/793 will give us a way to make DHTxx 1-wire sensors more reliable?

The culprit here is that 1-wire isn't exactly easy to support with non-real time OS since it's very timing based and therefore unreliable. We're expecting using linux kernel driver will improve the state but so far the easiest solution is to try use sensors which don't use 1-wire (I2C/SPI will work fine) - you can find some over here: https://github.com/dotnet/iot/tree/master/src/devices#thermometers

maloo commented 4 years ago

@krwq #793 is using the Linux kernel driver. It can use different types of interfaces, like i2c bridges. I have only used the gpio bit bang driver. I have close to 100% success rate in that config using the MAX31820. I have not tried longer wires. But doing bit banging in user space like the DHT binding is a very bad idea. After a quick Google, it looks like DHT is using a proprietary 1-wire protocol, not Dallas one used by kernel driver. So my binding will probably not help.

maloo commented 4 years ago

There seems to be an Industrial IO driver for DHT11/12. So might be possible to do a similar binding as Dallas 1-wire, but for IIO devices.

https://github.com/torvalds/linux/blob/master/drivers/iio/humidity/dht11.c

krwq commented 4 years ago

@maloo linux kernel is GPL so we can't even look at the source code :disappointed: Is it possible to use linux driver just for the timing but implement protocol ourselves? (i.e. your OneWireDevice having Read/Write)

maloo commented 4 years ago

Can you elaborate? Any binding in user space would use a kernel driver at some point. Iio is similar to 1-wire in the sense that you can use sysfs/procfs to interact with it. That is, read/write files is enough.

maloo commented 4 years ago

Maybe you can access this if you can't read the driver source code. https://wiki.st.com/stm32mpu/wiki/How_to_use_the_IIO_user_space_interface

Ellerbach commented 4 years ago

I guess this one should be closed: #984 seems like it's the same issue. It was specific issue with DHT22 calculation for temperature.

joperezr commented 4 years ago

Closing as dupe and because the other one was fixed already.