DHT library bug

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
Divergentti
Posts: 67
Joined: Fri Sep 04, 2020 9:27 am
Location: Hanko, Finland
Contact:

DHT library bug

Post by Divergentti » Wed Dec 09, 2020 7:01 am

With ESP32 Wroom, import dht, sensor.read()-mehod must be broken. FW esp32-idf3-20200902-v1.13.bin.

When temperature is below 0C, temperature value for dht.read is -3276.7. Moisture information seems to be OK. Setup has been running fine since June, but now when temperature outside is below 0C, problem arised.

Problem is not new: https://forum.arduino.cc/index.php?topic=129531.0.

Giving a try for this https://github.com/micropython/micropyt ... dht/dht.py

Code: Select all

    def temperature(self):
        t = ((self.buf[2] & 0x7F) << 8 | self.buf[3]) * 0.1
        if self.buf[2] & 0x80:
            t = -t
        return
Problem seems to be following: buffer (self.buf) when measure():
-> Humidity 87.2
- >Temperature = blank

bytearray(b'\x03h\xff\xfcf')

If I understand this correctly, first byte shall bring 3 x 256 (MSB), then add FF (LSB) and last two are temperature ([2] and [3]. Seems that 3 is missing. Perhaps first bytecode 03 + h means that because second bytecode is overflow, h (is not hexadecimal) is generated?

In other hand, I do not understand why measure(): passes this (unless if last byte is missing):

Code: Select all

    def measure(self):
        buf = self.buf
        dht_readinto(self.pin, buf)
        if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xFF != buf[4]:
            raise Exception("checksum error")
so, problem is in the dht_readinto:

Code: Select all

>>> from machine import Pin                                                          
>>> from esp import dht_readinto                                                     
>>> buffer = bytearray(5)                                                           
>>> dht_readinto(Pin(4), buffer)                                                    
>>> buffer                                                                          
bytearray(b'\x03k\xff\xfdj')                                                         
>>> dht_readinto(Pin(4), buffer)                                                    
>>> buffer                                                                          
bytearray(b'\x03r\xff\xfdq')  
872 (87.2) -> MSB:0000 0011 LSB:0110 1000 = hex 368 and negative value shall be bit 7 of byte 2, but it is 0.

Perhaps someone understand better what is wrong there. Meanwhile I made change to code:

Code: Select all

    if tempin < -40:
        ttemp = str(tempin).split('.')
        msb = int(ttemp[0]) * -1
        lsb = ttemp[1]
        belowzero = str(3276 - msb) + "." + lsb
        if float(belowzero) > 0.0:
            tempin = float(belowzero) * -1
        else:
            tempin = float(belowzero)
Edit: 10.12.2020:

dht.c in micropython-master/drivers/dht seems to read 40 bits as it should, so, this should be not problem after all:

Code: Select all


// time 40 pulses for data (either 26us or 70us)
    uint8_t *buf = bufinfo.buf;
    for (int i = 0; i < 40; ++i) {
        ticks = machine_time_pulse_us(pin, 1, 100);
        if ((mp_int_t)ticks < 0) {
            goto timeout;
        }
        buf[i / 8] = (buf[i / 8] << 1) | (ticks > 48);
    }
 

Post Reply