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 hereif 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.