Pure Python library for reading DHT sensor on Pycom boards
-
hello,
from a raspberry pi python library project , i have created a pure python library for pycom board to read the temperature and humidity from a DHT sensor (DTH11, DTH22). I have only tested my library on a pycom sipy esp32 module with a DTH11 sensor. It seems OK , no crash, no error. If someone can try this library with a DTH22 and another pycom board (lopy, wipy), it would be nice.
The library is on github hereUpdate (28/07/2017) :
There is a new branch in my github repository (pulses_get) here
only usable from the firmware v1.7.7.b1
Constructor of the class has changed only pin number is necessary :
new usage example :import pycom import time from machine import Pin from dth import DTH pycom.heartbeat(False) pycom.rgbled(0x000008) # blue th = DTH('P3',0) time.sleep(2) result = th.read() if result.is_valid(): pycom.rgbled(0x001000) # green print("Temperature: %d C" % result.temperature) print("Humidity: %d %%" % result.humidity)
Friendly, J.P
-
@Jurassic-Pork I have an AMT2301/DHT21 sensor. Google says that it is similar to the DHT22 and should work with the same code. However, your library with DHT22 as the set sensor does not work.
Do you know anything about if the sensor is supported or are you planning to add it in the future?
-
@Jurassic-Pork The good news is my DHT11 works fine with read(). However I think I bust my DHT22 at some point as reading no data from it. Will have to order another to test..!
-
@robmarkcole
put this code in the dht.py file and try a read2 in place of a read function. Show me the result (tuples and length) .def read2(self): #time.sleep(1) # send initial high #self.__send_and_sleep(1, 0.025) # pull down to low self.__send_and_sleep(0, 0.019) data = pycom.pulses_get(self.__pin,100) self.__pin.init(Pin.OPEN_DRAIN) self.__pin(1) print(data) #enable_irq(irqf) 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: return DTHResult(DTHResult.ERR_MISSING_DATA, 0, 0) print(bits) # we have the bits, calculate bytes the_bytes = self.__bits_to_bytes(bits) # calculate checksum and check checksum = self.__calculate_checksum(the_bytes) if the_bytes[4] != checksum: return DTHResult(DTHResult.ERR_CRC, 0, 0) # ok, we have valid data, return it [int_rh, dec_rh, int_t, dec_t, csum] = the_bytes if self.__dhttype==0: #dht11 rh = int_rh #dht11 20% ~ 90% t = int_t #dht11 0..50°C else: #dht21,dht22 rh = ((int_rh * 256) + dec_rh)/10 t = (((int_t & 0x7F) * 256) + dec_t)/10 if (int_t & 0x80) > 0: t *= -1 return DTHResult(DTHResult.ERR_NO_ERROR, t, rh)
PS : i have created a new branch in my DHT_pycom github repository (see at the end of my first message in this thread)
-
@Jurassic-Pork I just updated my firmware today :-) How to use the new function?
-
hello,
@robmarkcole have you still your problem ? the new firmware release v1.7.7.b1 have a new function pulses_get that can improve my DHT library.
-
-
@robmarkcole
try this :import machine import os machine.freq() # get the CPU frequency os.uname().release
for me :
import machine
import os
machine.freq() # get the CPU frequency
160000000
os.uname().release
'1.6.12.b1'
-
- it's a Wipy 2.0,
- will check firmware tonight but only updated 2 days ago so presumably the latest,
- how to check the frequency?
-
hello,
@robmarkcole
Ok it's not good because you have only 39 values (last line)
it's seems that your module is slower than mine because the max value for length of 1 level is 4 and for me 5 (or it is the dht ) . What is exactly your Pycom Module ? frequency ? firmware ?
-
@Jurassic-Pork said in Pure Python library for reading DHT sensor on Pycom boards:
state = STATE_INIT_PULL_DOWN
Thanks JP. Making this change I get:
entry 0x4009fd9c ('192.168.0.23', '255.255.255.0', '192.168.0.1', '192.168.0.1') [1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] [1, 1, 3, 2, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 3, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 3, 1, 1, 3, 4, 3] 39
And nothing more
-
hello,
@robmarkcole
May be you have the Delay DHT in your first data and not me.
In the parse data function :
def __parse_data_pull_up_lengths(self, data): STATE_INIT_PULL_DOWN = 1 STATE_INIT_PULL_UP = 2 STATE_DATA_FIRST_PULL_DOWN = 3 STATE_DATA_PULL_UP = 4 STATE_DATA_PULL_DOWN = 5 state = STATE_INIT_PULL_UP lengths = [] # will contain the lengths of data pull up periods current_length = 0 # will contain the length of the previous period for i in range(len(data)): current = data[i] current_length += 1 if state == STATE_INIT_PULL_DOWN: if current == 0: # ok, we got the initial pull down state = STATE_INIT_PULL_UP continue else: continue if state == STATE_INIT_PULL_UP: if current == 1: # ok, we got the initial pull up state = STATE_DATA_FIRST_PULL_DOWN continue else: continue if state == STATE_DATA_FIRST_PULL_DOWN: if current == 0: # we have the initial pull down, the next will be the data pull up state = STATE_DATA_PULL_UP continue else: continue if state == STATE_DATA_PULL_UP: if current == 1: # data pulled up, the length of this pull up will determine whether it is 0 or 1 current_length = 0 state = STATE_DATA_PULL_DOWN continue else: continue if state == STATE_DATA_PULL_DOWN: if current == 0: # pulled down, we store the length of the previous pull up period lengths.append(current_length) state = STATE_DATA_PULL_UP continue else: continue return lengths
try to put the state variable to STATE_INIT_PULL_DOWN at the begining of the function :
state = STATE_INIT_PULL_DOWN
Friendly, J.P
-
@Jurassic-Pork Appears to always start with 1..
-
hello,
@robmarkcole
look at this this timing for the AM2302 data acquisition :
the acquisition begins when the start signal after 19 ms is put to level 1 :def read(self): #time.sleep(1) # send initial high #self.__send_and_sleep(1, 0.025) # pull down to low self.__send_and_sleep(0, 0.019) # collect data into an array data = self.__collect_input()
def __collect_input(self): # collect the data while unchanged found unchanged_count = 0 # this is used to determine where is the end of the data max_unchanged_count = 100 last = -1 data = [] m = bytearray(800) # needs long sample size to grab all the bits from the DHT irqf = disable_irq() self.__pin(1)
then we store the level values :
for i in range(len(m)): m[i] = self.__pin() ## sample input and store value
your samples data begin with a 1 and me with a zero (begining of the response signal)
try to see if you have always a 1 for the first data.
-
Hi @Jurassic-Pork thanks for the tips. Here is what I get. The temp and humidity values change each time I reset the board, but look incorrect. E.g. humidity went from 18 to 37 on a restart.
Cheersentry 0x4009fd9c
('192.168.0.23', '255.255.255.0', '192.168.0.1', '192.168.0.1')
[1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1,
1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,
1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[2, 2, 3, 2, 1, 4, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 4, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 4, 4, 1, 4, 4, 4]
40
[37, 0, 18, 0, 55]
8
Temperature: 18 C
Humidity: 37 %
-
hello,
@robmarkcole
to see what is wrong, you can uncomment some lines in the file dht.py. The lines 49, 53, 54, 63 with the print function.
you must see something like that for the dht11 :
the last line in the photo (line 63 print(the_bytes)) has the values for the humidity (32) and for the temperature (22).
May be something is wrong with the WiPy module :
i use a SiPy module and the other people who have used the library seems to use a LoPy module. If someone can try to use the library with a WiPy module to see if it is OK.Friendly, J.P
-
Annoyingly I am unable to upload the code, as it is 'marked as spam' when I try. Nevertheless I am just using the examples in your Github repo
-
@RobTuDelft I would, but I only have 1 and 10 k Ohm available at the moment.
-
@robmarkcole Can you try it with a 4k7 resistor, maybe 10k is too much? You could also post a picture of your setup and the code fragments you are using.
-
@RobTuDelft Yes used those. Humidity and temp constant. Swapped in a DHT11 now and seeing same behaviour. Any tips on how to debug?
Cheers