树莓派通过DHT11读取气温

功能可以用C(WringPi库)和Python(RPi.GPIO)实现

基本流程:

  • 给DHT11的data引脚一个18ms的低电平信号,然后给高电平信号,DHT11开始传回数据
  • 接受DHT11传回的数据(bits)
  • 再对数据进行处理变成可阅读的十进制数字

DHT11传回数据格式:
一次传输40位数据=8bits湿度整数数据 + 8bits湿度小数数据 + 8bits温度整数数据 + 8bits温度小数数据 + 8bits校验位

首先要将DHT11接到树莓派的GPIO引脚上,WringPi官网的引脚映射信息:Pins | Wring Pi

注意引脚的对应的编码有两种,BCM(Python的RPi.GPIO使用)和WiringPI(C语言使用)

引脚接入后需要记住DHT11 data引脚对应的树莓派引脚的BCM和WPi编码

C语言代码:(Wring Pi官网Reference: Reference )

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define MAXTIMINGS 85
#define DHTPIN [Your Pin]

int dht11_dat[5] = {0, 0, 0, 0, 0};

void read_dht11_dat () {
    uint8_t laststate = HIGH;
    uint8_t counter = 0;
    uint8_t j = 0, i;
    float f; /* fahrenheit */

    dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;

/* pull pin down for 18 milliseconds */
    pinMode (DHTPIN, OUTPUT); //set PIN7 as output
    digitalWrite (DHTPIN, LOW); //write in a LOW(0) signal to PIN7 ["must have been previously set as an output"]
    delay (18);
/* then pull it up for 40 microseconds */
    digitalWrite (DHTPIN, HIGH); //write in a HIGH(1) signal to PIN7
    delayMicroseconds (40);
/* prepare to read the pin */
    pinMode (DHTPIN, INPUT); //set PIN7 as input

/* detect change and read data */
    for( i = 0; i < MAXTIMINGS; i++ ) {
        counter = 0;
        while( digitalRead (DHTPIN) == laststate ) { //digitalRead (DHTPIN) read the data return from PIN7
            counter++;
            delayMicroseconds (1);
        if( counter == 255 ) break;
    }
    laststate = digitalRead (DHTPIN);

    if( counter == 255 ) break;

/* ignore first 3 transitions */
    if( ( i >= 4 ) && ( i % 2 == 0 ) ) {
/* shove each bit into the storage bytes */
        dht11_dat[j / 8] <<= 1;
        if( counter > 16 ) dht11_dat[j / 8] |= 1;
        j++;
        }
}

/*
* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
* print it out if data is good
*/
    if( ( j >= 40 ) && ( dht11_dat[4] == ( ( dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3] ) & 0xFF ) ) ) {
        printf ("Humidity = %d.%d %% Temperature = %d.%d *C\n",dht11_dat[0],dht11_dat[1],dht11_dat[2],dht11_dat[3]);
    } else {
        printf ("Data not good, skip\n");
    }
}

int main () {

    if( wiringPiSetup () == -1 ) exit (1);

    while( 1 ) {
        read_dht11_dat ();
        delay (1000); /* wait 1sec to refresh */
    }

    return 0;
}

Python代码:

import RPi.GPIO as GPIO
import time

channel = [Your Pin]
data = []


def setup():
    GPIO.setmode(GPIO.BCM)
    time.sleep(1)

    GPIO.setup(channel, GPIO.OUT)
    GPIO.output(channel, GPIO.LOW)
    time.sleep(0.02)
    GPIO.output(channel, GPIO.HIGH)
    GPIO.setup(channel, GPIO.IN)

    while GPIO.input(channel) == GPIO.LOW:
        continue
    while GPIO.input(channel) == GPIO.HIGH:
        continue


def get_data():
    j = 0
    while j < 40:
        k = 0
        while GPIO.input(channel) == GPIO.LOW:
            continue
        while GPIO.input(channel) == GPIO.HIGH:
            k += 1
            if k > 100:
                break
        if k < 8:
            data.append(0)
        else:
            data.append(1)
        j += 1


def show():
    humidity_bit = data[0:8]
    humidity_point_bit = data[8:16]
    temperature_bit = data[16:24]
    temperature_point_bit = data[24:32]
    check_bit = data[32:40]
    humidity = 0
    humidity_point = 0
    temperature = 0
    temperature_point = 0
    check = 0

    for i in range(8):
        humidity += humidity_bit[i] * 2 ** (7 - i)
        humidity_point += humidity_point_bit[i] * 2 ** (7 - i)
        temperature += temperature_bit[i] * 2 ** (7 - i)
        temperature_point += temperature_point_bit[i] * 2 ** (7 - i)
        check += check_bit[i] * 2 ** (7 - i)

    tmp = humidity + humidity_point + temperature + temperature_point

    if check == tmp:
        print "Temperature :", temperature, "*C, Humidity :", humidity, "%"
    else:
        print "Wrong"

    GPIO.cleanup()


def main():
    setup()
    get_data()
    show()


if __name__ == "__main__":
    main()

实际测试中,C语言代码执行较快,隔100ms取一次的数据都比较准确,可以配合LED或者数码管显示温度

Python代码快速读取出的数据不准确,大概隔几秒读一次比较准确

原因可能是代码优化不行