Raspberry Pi Advanced Gpio Library, wiringpi2 for Python use notes (iv) actual combat DHT11 decoding

Source: Internet
Author: User
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



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.