DHT11 is a temperature and humidity sensor with a calibrated digital signal output. Accuracy humidity + -5% RH, temperature + -2 ℃, range humidity 20-90% RH, temperature 0 ~ 50 ℃.
The packaged module I bought has a pull-up resistor on it. You can directly find the data on the Raspberry Pi. The gray, purple, and blue represent data, 3.3V, and 0V, respectively, and you receive 3, 1, 10 from the Raspberry Pi. Pin, corresponding to PIN8, 3.3V, 0V respectively.
The communication protocol between DHT11 and the microcontroller is a 1-wire protocol. In fact, the single-wire protocol is very powerful. One GPIO can read data. However, this protocol does not have synchronization pulses, so the timing requirements are relatively high. Ping is defined as follows:
Low level 50us, then a high level of 26-28us, representing 0
Low level 50us, then a high level of 70us, which represents 1
In other words, you need to be able to distinguish the time below 40us to accurately measure it. Let's look at the specific timing below:
The bus idle state is high. The host pulls the bus low and waits for DHT11 to respond. The host pulls the bus low must be more than 18 milliseconds to ensure that DHT11 can detect the start signal. After receiving the start signal from the host, DHT11 waits for the end of the start signal from the host, and then sends an 80us low-level response signal. After the host sends the start signal, waits for 20-40us after a delay, reads the response signal from DHT11, and the host sends the start signal After that, you can switch to input mode or output high level. The bus is pulled up by a pull-up resistor.
The number 0 means:
The number 1 means like:
It can be seen that each bit includes the initial response signal, which is composed of a low level and a high level, where the response signal is 80us + 80us = 160us
The number 0 is 50 + 26 = 76us
The number 1 is 50 + 70 = 120us
To read the status of DHT11, I wrote the following program:
import wiringpi2 as gpio
owpin = 8 # 8 pin is 1-wire pin
tl = [] #Time for storing each data bit
gpio.wiringPiSetup () #Initial wiringpi library
gpio.pinMode (owpin, 1) #Set the pin to the output state
gpio.digitalWrite (owpin, 1) #output high
gpio.delay (1)
### Issue start command, request DHT11 to transmit data
gpio.digitalWrite (owpin, 0) #pull 25ms to start instruction
gpio.delay (25)
gpio.digitalWrite (owpin, 1) #Output high level, start instruction ends
gpio.pinMode (owpin, 0) #Set the pin to the input state
### After the start command is sent, set the pin to high level and wait for DHT11 to pull the pin low. transfer data
while (gpio.digitalRead (owpin) == 1): pass #If the pin is always 1, wait forever.
### If pulled low, it indicates the start of the transmission, the response signal + 40 bits of data + the end flag total 42 bits
### Cycle 45 times below, intentionally cycle several times to see the result.
for i in range (45): #Test the time of each data cycle (including 40bit data plus a transmission start flag
tc = gpio.micros () #Note down the current number of us (calculated from the beginning of the initialization, re-initialize if necessary)
‘‘ ‘
One data cycle, including a low level and a high level, starting from the first time the DHT11 pulls down the signal line
Until the end of DHT11 sending the last low level of 50us (then pulled high, it has remained high, so
The final completion flag is always high, more than 500ms)
‘‘ ‘
while (gpio.digitalRead (owpin) == 0): pass #One bit of data is set by a low level
while (gpio.digitalRead (owpin) == 1): #Add a high level
if gpio.micros ()-tc> 500: #If it exceeds 500us, this cycle ends.
break # will be pulled high by a pull-up resistor to prevent it from entering an infinite loop
tl.append (gpio.micros ()-tc) #Record the number of us in each cycle time and save it to the tl list
print (tl) #Print the result
There is a detailed explanation in the program, I will not repeat it here, and here is the result of my execution:
[116, 68, 74, 67, 124, 64, 120, 120, 76, 71, 73, 73, 73, 73, 73, 73, 74, 67, 73, 73, 123, 120, 70, 72, 73 , 79, 71, 73, 73, 74, 73, 74, 73, 70, 73, 122, 74, 117, 120, 119, 70, 508, 506, 512, 512)
Now analyze the results:
The first 116us is a response signal. According to the description, it should be 160us. It is estimated that the DHT11 in my hand is not very standard. The next 40 (from 68us to the last 70us) are 40-bit data. Because no data was received later, So they all exceeded 500us (time out of 500us, jump out of the loop to prevent the infinite loop)
Regardless of the first 116us, 60-80us is 0, and about 120 is 1, the received data is:
Humidity integer Humidity decimal Temperature integer Temperature decimal Check
0001 0110 0000 0000 0001 1000 0000 0000 0010 1110
16 + 4 + 2 = 22 0 16 + 8 = 24 0 32 + 8 + 4 + 2 = 46
Therefore, the reading result is 22% humidity, temperature 24 degrees, checksum is 22 + 24 = 46, and the reading is successful.
I added some data processing, and additional code that failed to read again. The final code is as follows:
import wiringpi2 as gpio
owpin = 8 # 8 pin is 1-wire pin
def getval (owpin):
tl = [] #Time for storing each data bit
tb = [] #Store data bits
gpio.wiringPiSetup () #Initial wiringpi library
gpio.pinMode (owpin, 1) #Set the pin to the output state
gpio.digitalWrite (owpin, 1) #output high
gpio.delay (1)
gpio.digitalWrite (owpin, 0) #pull 20ms to start instruction
gpio.delay (25)
gpio.digitalWrite (owpin, 1) #Raise 20-40us
gpio.delayMicroseconds (20)
gpio.pinMode (owpin, 0) #Set the pin to the input state
while (gpio.digitalRead (owpin) == 1): pass # wait for DHT11 to pull low
for i in range (45): #Test the time of each data cycle (including 40bit data plus a transmission start flag
tc = gpio.micros () #Note down the current number of us (calculated from the beginning of the initialization, re-initialize if necessary)
‘‘ ‘
One data cycle, including a low level and a high level, starting from the first time the DHT11 pulls down the signal line
Until the end of DHT11 sending the last low level of 50us (then pulled high, it has remained high, so
The final completion flag is always high, more than 500ms)
‘‘ ‘
while (gpio.digitalRead (owpin) == 0): pass
while (gpio.digitalRead (owpin) == 1):
if gpio.micros ()-tc> 500: #If it exceeds 500ms, it is over
break
if gpio.micros ()-tc> 500: #Jump out of the entire loop
break
tl.append (gpio.micros ()-tc) #Record the number of us in each cycle time and save it to the tl list
# print (tl) #Print time list after uncommenting
tl = tl [1:] #Remove the first item, leaving 40 data bits
for i in tl:
if i> 100: #If the data bit is 1, the time is 50us low level + 70us high level = 120us
tb.append (1)
else:
tb.append (0) #If the data bit is 0, the time is 50us low level + 25us high level = 75us
#Here greater than 100us is 1
# print (tb) #Uncomment to see the status of each bit
return tb
def GetResult (owpin):
for i in range (10):
SH = 0; SL = 0; TH = 0; TL = 0; C = 0
result = getval (owpin)
# print (len (result))
if len (result) == 40:
for i in range (8):
#Calculate the status of each digit, 8 digits per word, using this as the humidity integer, humidity decimal, temperature integer, temperature decimal, checksum
SH * = 2; SH + = result [i]
SL * = 2; SL + = result [i + 8]
TH * = 2; TH + = result [i + 16]
TL * = 2; TL + = result [i + 24]
C * = 2; C + = result [i + 32]
if ((SH + SL + TH + TL)% 256) == C and C! = 0:
break
else:
print ("Read Sucess, But checksum error! retrying")
else:
print ("Read failer! Retrying")
gpio.delay (200)
return SH, SL, TH, TL
SH, SL, TH, TL = GetResult (owpin)
print ("Humidity:", SH, SL, "Temperature:", TH, TL)
The results are as follows:
Humidity: 20 0 Temperature: 24 0
Raspberry Pi advanced GPIO library, wiringpi2 for python use notes (four) combat DHT11 decoding