LoPy - Library for DHT22



  • Dear All,

    Does anybody know if there is a working library for the DHT22 temperature and humidity sensor?

    Thanks and regards.



  • This post is deleted!


  • @Jurassic-Pork thanks! Will give it a try.

    Best regards.



  • hello,
    there is my Pure Python library for reading DHT sensor on Pycom boards.
    Since the firmware version release v1.7.7.b1 there is a new function pulses_get that have improved my DHT library.
    the old version is here
    the new version with pulses_get used is here

    if you have sometimes some errors (wrong number of bits read) i can improve the library with
    this code (retry) in my library :

        def read(self):
            # pull down to low
            r=0
            #loop for retry if needed
            while True:
                self.__send_and_sleep(0, 0.019)
                data = pycom.pulses_get(self.__pin,100)
                self.__pin(1)
                self.__pin.init(Pin.OPEN_DRAIN)
                #print(data)
                bits = []
                for a,b in data:
                    if a ==1 and 18 <= b <= 28:
                        bits.append(0)
                    if a ==1 and 65 <= b <= 75:
                        bits.append(1)
                #print("longueur bits : %d " % len(bits))
                if len(bits) != 40:
                    print("length error : %d " % len(bits),end='')
                    #print(data)
                    r +=1
                    print("-> retry %d" % r)
                    # return error if too much retries
                    if r==3:
                        return DTHResult(DTHResult.ERR_MISSING_DATA, 0, 0)
                    time.sleep_ms(200)
                else:
                    break
    

    friendly J.P



  • @fuzzy Yes, that#s possible, but difficult. There is a DHT module in the micropython.org variant. One could consider to carry that over, but it is a little bit tricky, since the underlying architecture of the SW is totally different, and it is not just copying the interface part.



  • @robert-hh thanks! I will have a look at the SHT31. Just out of curiosity: is there a way to make a native ESP32 function to read fast the transitions and then make it available (somehow) as a micro python module?

    Thanks!



  • @fuzzy The problem with the DHT22 and DHT11 is, that they require fast reading of the transitions. For the usual implementation of setting up an IRQ handler Python code is too slow. That's the reason why the actual code first reads in a burst of data and then tries to decode the 1/0 transitions. That fails sometimes. For the moment, you can simply retry if you get an checksum error.
    Alternatively, you could used sensors with an I2C or SPI interface, for which there is better support by XxPy devices, like SHT31. @maamar has also implemented code for that device https://forum.pycom.io/topic/1622/deepsleep-and-sht31-d-alarm



  • @robert-hh thanks (once more...!) Do you know of any other components from which I could get reliable temperature and humidity reading using the LoPy? Or you think that detecting and ignoring the checksum errors from reading the DHT22 suffice for most (non-critical) applications?

    Thanks and regards.



  • @fuzzy There is a lengthy thread about this with some sample code: https://forum.pycom.io/topic/1172/pure-python-library-for-reading-dht-sensor-on-pycom-boards
    One of the samples is one of mine, shown below:

    from machine import enable_irq, disable_irq,  Pin
    import time
    _LIMIT = const(8)
    _BUFFERSIZE = const(1000)
    
    def getval(pin) :
        ms = [1] * _BUFFERSIZE
        mslen = len(ms)
        pin(0)
        time.sleep_us(20000)
        pin(1)
        irqf = disable_irq()
        for _ in range(mslen):
            ms[_] = pin()      ## sample input and store value
        enable_irq(irqf)
        return ms
    
    def decode(inp):
        res= [0]*5
        bits=[]
        ix = 0
        try:
            if inp[0] == 1 : 
                ix = inp.index(0, ix) ## skip to first 0
            ix = inp.index(1,ix) ## skip first 0's to next 1
            ix = inp.index(0,ix) ## skip first 1's to next 0
            while len(bits) < len(res)*8 : ##need 5 * 8 bits :
                ix = inp.index(1,ix) ## index of next 1
                ie = inp.index(0,ix) ## nr of 1's = ie-ix
                bits.append(ie-ix)
                ix = ie
        except Exception as err:
            print (err, ix, len(bits))
            return([0xff,0xff,0xff,0xff])
    
        for i in range(len(res)):
            for v in bits[i*8:(i+1)*8]:   #process next 8 bit
                res[i] = res[i]<<1  ##shift byte one place to left
                if v > _LIMIT:
                    res[i] = res[i]+1  ##and add 1 if lsb is 1
    
        if (res[0]+res[1]+res[2]+res[3])&0xff != res[4] :   ##parity error!
            print("Checksum Error")
            res= [0xff,0xff,0xff,0xff]
    
        return(res[0:4])
    
    def DHT11(pin):
        res = decode(getval(pin))
        temp = 10 * res[0] + res[1]
        hum = 10 * res[2] + res[3]
        return temp, hum
    
    def DHT22(pin) :
        res = decode(getval(pin))
        hum = res[0]*256+res[1]
        temp = res[2]*256 + res[3]
        if (temp > 0x7fff):
            temp = 0x8000 - temp
        return temp, hum
    
    def run():
        dht_pin=Pin('G7', mode=Pin.OPEN_DRAIN)
        dht_pin(1)
    
        temp, hum = DHT22(dht_pin)
    
        temp_str = '{}.{}'.format(temp//10,temp%10)
        hum_str = '{}.{}'.format(hum//10,hum%10)
    
        # Print or upload it
        print(temp_str, hum_str)
    
    run()
    

    I did NOT test that recently again. It supports both DHT22 and DHT11
    Edit: Just tested it again and it seems to work as good and bad as before. Sometimes it returns checksum error, in which case the results are not valid.


Log in to reply
 

Pycom on Twitter