树莓派从温度传感器DHT11读取数据

简介: 这里有个校验位,是为了确保数据传输的准确性的。如果byte1+byte2+byte3+byte4 == byte0,数据传输就是正确的。不过DHT11小数位是不工作的,所以只需要考虑byte2+byte4就行了。

树莓派作为一个完整的主机,除了能在上面跑系统外,也提供了40个引脚提供电路开发的功能。本来我在工作中常接触linux,但没啥机会接触硬件,正好手头上有一台raspberry 3b,本来是用来学linux相关的包的,闲的没事,网上买了几个传感器玩玩。很短时间就能上手从dht11读取数据了,虽然也看了好多文档,GPIO学起来还是挺简单的。

 第一次写gpio程序, 我还是参考了别人的代码,主题代码基本一样,这里我多解释下我的代码吧。 重要的是这里有几个magic number,比如cnt 小于100和cnt > 12。  

 首先我们可以在网上找下DHT11的相关文档。你向传感器发送一个复位信号(大于18us的低电位,然后高电位),然后传感器会传送40-50us的低电位,紧接着40-50us的高电位。在往后就是以12-14us间隔的40个数据位了。

 40个数据位编码方式如下。


byte4     byte3     byte2     byte1     byte0 
01010101  00000000  10101010  00000000  01010101
--------  --------  --------  --------  -------- 
整数       小数       整数      小数       校验位
------------------  ------------------   
湿度                 温度

 这里有个校验位,是为了确保数据传输的准确性的。如果byte1+byte2+byte3+byte4 == byte0,数据传输就是正确的。不过DHT11小数位是不工作的,所以只需要考虑byte2+byte4就行了。

 26-28us的高电平为0,116-118us的高电平为1。我代码里并没有以时间间隔作为判断,而是用了cnt 这个while循环计数器,因为我尝试过用时间。测试得到一次while空循环带计数器+1,基本上需要0.8us左右,但如果while循环里加上接口数据读取,一次循环基本上就要6us左右了,果然外部IO的速度比较慢。

 这里我经过多次测试,发现计数器cnt>=12作为1的判断准确率较高。这就是我magicnumber 12的由来。 还有另外一个magicnumber 100,这个数字主要是用来应对复位信号没发送成功,程序陷入死循环的情况。我用的是树莓派3B,不同版本的树莓派性能不一样,可能magicnumber也不一样。

 我用的是BCM模式的4引脚,也就是板子上的7号引脚作数据传输,另外两根引脚接地和3.3v电压即可。

 

下面就是代码了

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
pin = 4 
data = []
GPIO.setmode(GPIO.BCM)
time.sleep(2)
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.HIGH)
GPIO.output(pin, GPIO.LOW)
time.sleep(0.04)
GPIO.output(pin, GPIO.HIGH)
GPIO.setup(pin, GPIO.IN)
while GPIO.input(pin) == GPIO.LOW:
    continue
while GPIO.input(pin) == GPIO.HIGH:
    continue
i = 0
while i < 40:
    cnt = 0
    while GPIO.input(pin) == GPIO.LOW:
        continue
    while GPIO.input(pin) == GPIO.HIGH:
        cnt += 1
        if cnt > 100:
            break    
    if cnt < 12:
        data.append(0)
    else:
        data.append(1)
    i += 1
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()
目录
相关文章
|
4月前
|
传感器 数据安全/隐私保护 数据格式
STM32CubeMX DHT11温湿度传感器
STM32CubeMX DHT11温湿度传感器
267 11
|
5月前
|
传感器 数据格式
【STM32】DHT11温湿度模块传感器详解&代码
【STM32】DHT11温湿度模块传感器详解&代码
|
物联网 芯片 计算机视觉
树莓派开发笔记(十):Qt读取ADC模拟量电压(ADS1115读取电压模拟量)
树莓派开发笔记(十):Qt读取ADC模拟量电压(ADS1115读取电压模拟量)
树莓派开发笔记(十):Qt读取ADC模拟量电压(ADS1115读取电压模拟量)
|
传感器 芯片 数据格式
stm32读取DHT11温湿度传感器
stm32读取DHT11温湿度传感器
270 1
|
传感器
野火RA6M5开发板 DHT11温湿度传感器 OLED显示测试学习
野火RA6M5开发板 DHT11温湿度传感器 OLED显示测试学习
121 0
野火RA6M5开发板 DHT11温湿度传感器 OLED显示测试学习
STM32+ESP8266+QT客户端上位机显示DHT11温湿度与点灯
STM32+ESP8266+QT客户端上位机显示DHT11温湿度与点灯
STM32(HAL库)驱动SHT30温湿度传感器通过串口进行打印
STM32(HAL库)驱动SHT30温湿度传感器通过串口进行打印
|
传感器 Linux
linux驱动——dht11温湿度传感器驱动(5.4版本内核)
linux驱动——dht11温湿度传感器驱动(5.4版本内核)
736 0
|
传感器 芯片
51单片机读取DS18B20温度传感器
51单片机读取DS18B20温度传感器
264 0
|
传感器
【Renesas RA6M4开发板之DHT11温湿度读取】
【Renesas RA6M4开发板之DHT11温湿度读取】
96 0
【Renesas RA6M4开发板之DHT11温湿度读取】