#!/usr/bin/python3.5 # # This is the Python module implementing access to the DHT11 # U. Raich UCC, Nov.2017 import sys import RPi.GPIO as GPIO import time,datetime class Dht11: SUCCESS= 0 INIT_FAILED= -1 MISSING_INIT= -2 NO_MEAS_YET= -3 NO_VALID_MEAS_YET= -4 MEM_ALLOC_ERROR= -5 PROTOCOL_ERROR= -6 BAD_CHECKSUM= -7 BAD_TIME_STAMP= -10 PROTOCOL_TIMEOUT= 100 PROTOCOL_SIZE= 800 PROTOCOL_SIZE_MARGIN= 200 MAX_UNCHANGED_COUNT= 100 HIGH= 1 LOW= 0 ON= 1 OFF= 0 errorMsg={ SUCCESS: "library call returned successfully", INIT_FAILED: "Failed to initialize the pigpiod connection", MISSING_INIT : "init was not called yet", NO_MEAS_YET: "No measurement was made yet", NO_VALID_MEAS_YET: "No valid measurement was made yet", MEM_ALLOC_ERROR: "Could not allocate enough memory to hold the data", PROTOCOL_ERROR: "Protocol error: the data stream was probably not read entirely", BAD_CHECKSUM: "Checksum error on protocol data", BAD_TIME_STAMP: "The time stamp was invalid", } temperature = -1 humidity = -1 validTemperature = -1 validHumidity = -1 timeStamp = -1 validTimeStamp = -1 checksum = -1 tramsittedChecksum = -1 dht11Pin = 17 dht11Data = [] def __init__(self,pinNo): dht11Pin = pinNo; GPIO.setmode(GPIO.BCM) GPIO.setwarnings(True) def measure(self): # # set the dht11 control pin to output to start the measurement # GPIO.setup(self.dht11Pin,GPIO.OUT) GPIO.output(self.dht11Pin,self.LOW) time.sleep(0.018 ) # wait for 18 ms GPIO.output(self.dht11Pin,self.HIGH) time.sleep(0.000040) # wait for 40 us # now switch the pin to input GPIO.setup(self.dht11Pin,GPIO.IN) last = -1 count = 0 while True: current=GPIO.input(self.dht11Pin) self.dht11Data.append(current) if (current != last): last = current count = 0 else: count += 1 if count > self.MAX_UNCHANGED_COUNT: break self.__decode() # for i in range(0,len(self.dht11Data)): # print(self.dht11Data[i]) # # this decodes the protocol read from the dht11 # it first waits for the response signal from the DHT11 to pass # and then reads the protocol data bit by bit # def __decode(self): # this function reads a single bit from the protocol # pointer is an index into the data array which is pass back to the calling # decode() function (use a nonlocal variable) # def __readBit(): nonlocal pointer if int(self.dht11Data[pointer+10]) == self.HIGH: dataBit=1 else: dataBit=0 for index in range(0,50): if pointer > len(self.dht11Data): return self.PROTOCOL_ERROR # print("dht11Data[",pointer, "] : ",self.dht11Data[pointer]); try: if int(self.dht11Data[pointer]) == self.HIGH: pointer += 1 else: break except IndexError: print("protocolError") return self.PROTOCOL_ERROR pointer += 1 if index == 50: print("protocol error") return self.PROTOCOL_ERROR for index in range(0,50): if pointer > len(self.dht11Data): return self.PROTOCOL_ERROR # print("dht11Data[",pointer, "] : ",self.dht11Data[pointer]); if pointer > len(self.dht11Data): return self.PROTOCOL_ERROR try: if int(self.dht11Data[pointer]) == self.LOW: pointer += 1 else: break except IndexError: print("protocolError") return self.PROTOCOL_ERROR if index == 50: print("protocol error") return self.PROTOCOL_ERROR else: # print("bit: ",dataBit) return dataBit # # end of readBit # # must advance this far enough to skip to start with the response signal # from the DHT11 pointer=25 # # wait until response from dht11 is finished # for index in range(0,50): if int(self.dht11Data[pointer]) == self.HIGH: pointer += 1 continue # print("# pointer when signal goes down: ",pointer) if index == 50: print("Did not see DHT11 start signal") return self.PROTOCOL_ERROR pointer += 1 for index in range(0,50): if int(self.dht11Data[pointer]) == self.LOW: pointer += 1 continue # print("# pointer when signal goes high again: ",pointer) if index == 50: print("Did not see DHT11 start signal") return self.PROTOCOL_ERROR pointer +=1 # print("# pointer after DHT11 start signal: ",pointer) humTempData = [] for humTemp in range(0,5): data = 0 for bits in range(0,8): # print("pointer: ",pointer) data <<= 1 data |= int(__readBit()) # print("data byte: ",format(data,'02x')) humTempData.append(data); # for index in range(0,len(humTempData)): # print("data[",index,"] = 0x",format(humTempData[index],'02x')) checksum = 0 for index in range(0,4): checksum += humTempData[index] checksum &= 0xff self.checksum = checksum self.transmittedChecksum = humTempData[4] self.temperature = humTempData[2] self.humidity = humTempData[0] self.timeStamp = time.time() # print("Checksum calculated: ",format(checksum,'02x'), # " transmitted: ",format(humTempData[4],'02x')) if checksum == humTempData[4]: # print("Checksums match") self.validTemperature = self.temperature self.validHumidity = self.humidity self.validTimeStamp = self.timeStamp else: print("Bad checksum") # print("Humidity: ",humTempData[0], " Temperature: ",humTempData[2]) def getTemperature(self): return self.temperature def getHumidity(self): return self.humidity def getValidatedTemperature(self): return self.validTemperature def getValidatedHumidity(self): return self.validHumidity def getTimeStamp(self): return self.timeStamp def getValidTimeStamp(self): return self.validTimeStamp def getValidTimeString(self): return(datetime.datetime.fromtimestamp(self.validTimeStamp).strftime('%Y-%m-%d %H:%M:%S'))