树莓派基础实验27:温湿度传感器DHT11 实验

一、介绍

   数字温湿度传感器DHT11是一种复合传感器,包含温度和湿度的校准数字信号输出。采用专用数字模块采集技术和温湿度传感技术,确保产品具有高可靠性和优异的长期稳定性。
   该传感器包含一个电阻湿感元件和一个NTC温度测量设备,并与一个高性能8位微控制器连接。其精度:湿度±5%RH, 温度±2℃。量程:湿度20-90%RH, 温度0~50℃。采样周期:大于等于1秒/次。
   在我们刚开始练习写传感器的时序时,DHT11非常适合新手入门练习如何写时序。


二、组件

★Raspberry Pi 3主板*1

★树莓派电源*1

★40P软排线*1

★湿度传感器DHT11模块*1

★面包板*1

★跳线若干

三、实验原理

温湿度传感器

温湿度传感器模块原理图

   DHT11是一款价格便宜,易于使用的温度湿度测量二合一传感器。它具有超小体积、极低功耗的特点。它使用单根总线与单片机进行双向的串行数据传输,信号传输距离可达20米以上。非常适用于对精度和实时性要求不高的温湿度测量场合。

DHT11硬件原理图

   数据总线DATA使用上拉电阻拉高,因此总线空闲时为高电平。上拉电阻阻值推荐范围:4.7K~5.1K。必要时在VDD和GND之间并一个100nF的去耦电容。

1. DHT11的数据格式:

  DATA 用于树莓派与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,操作流程如下:

   DHT11用的是单总线协议,一次传送40位的数据。 注意了,看到这一句话,也就是说我们每次读取DHT11的数据时,都要一次性读取40次,也就是读取40位。并且数据前16位是与湿度相关的,中间16位是与温度相关的,最后八位是用来校验的,当我们校验成功后,证明这一次的温湿度结果正确的,我们的树莓派就可以使用这个温湿度值;如果校验不通过,那么就代表我们这次读取出来的温湿度值,是错误的(也许是我们的时序错误了,也许是传感器的问题),我们不进行采样。

 DHT11数据格式示例

2. DHT11的工作原理:

数据时序图

DHT11的总体通信流程:
第一步:主机(树莓派)先发送开始信号,从机(DHT11)会返回一个相应信号进行应答。
第二步:主机信号线拉高准备接收数据。
第三步:开始接收数据(一次接收40位)。

   DHT11使用单一总线通信,即DATA引脚和单片机连接的线。总线总是处于空闲状态和通信状态这个2个状态之间。当树莓派没有与DHT11交互时,总线处于空闲状态,在上拉电阻的作用下,处于高电平状态。

   当单片机和DHT11正在通信时,总线处于通信状态,一次完整的通信过程如下:

   第一步: DHT11 上电后(DHT11 上电后要等待 1秒以越过不稳定状态在此期间不能发送任何指令),测试环境温湿度数据,幵记录数据,同时 DHT11 的 DATA 数据线由上拉电阻拉高一直保持高电;此时 DHT11 的DATA 引脚处于输入状态,时刻检测外部信号。

   第二步: 微处理器的 I/O 设置为输出,同时输出低电平,且低电平保持时间不能小于 18ms,然后输出高电平20~40us,再树莓派的 I/O设置为输入状态,等待 DHT11 作出回答信号,发送信号如图所示:

主机发送起始信号

   第三步: DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA引脚处于输出状态,输出 80 微秒的低电平作为应答信号,紧接着输出 80 微秒的高电平通知外设准备接收数据,树莓派的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11 回应信号)后,等待 80 微秒的高电平后的数据接收,发送信号如图所示:

DHT11应答信号

   第四步: 由 DHT11 的 DATA 引脚输出 40 位数据,树莓派根据 I/O 电平的变化接收 40 位数据,位数据“0”的格式为: 50 微秒的低电平和 26-28 微秒的高电平;位数据“1”的格式为: 50 微秒的低电平加 70微秒的高电平。位数据“0”、“1”格式信号如图所示:

位数据“0”、“1”的格式

   我们可以把这一段的时序理解为,DHT11先把数据线拉低50us,然后我们再去对比高电平持续的时间,如果持续时间较短,则为位“0”;如果持续时间较长,则为位“1”。

   结束信号: DHT11 的 DATA 引脚输出 40 位数据后,继续输出低电平 50 微秒后转为输入状态,由于上拉电阻随之变为高电平。但 DHT11 内部重测环境温湿度数据,幵记录数据,等待外部信号的到来。

注意事项:

1、DHT11上电后,要等待 1秒 以越过不稳定状态,在此期间不能发送任何指令。

2、DHT11属于低速传感器,两次通信请求之间的间隔时间不能太短,一般来说要不能低于1秒。

对DHT11的时序做一个总结:
一. 主机(单片机)发送起始信号:
  1.主机先拉高data。
  2.拉低data延迟18ms。
  3.拉高data(单片机引脚设置为输入)。

二. 从机(DHT11)收到起始信号后进行应答:
  从机拉低data,主机读取到data线被拉低持续80us后从机拉高data线, 持续80us,直到高电平结束,意味着主机可以开始接受数据。

三. 主机开始接收数据:
  1.主机先把data线拉高(io设置为输入)。
  2.从机把data线拉低,主机读取data线电平,直到低电平结束(大约50us)从机拉高data线后,对比高电平持续的时间,如果持续时间较短,则为位“0”;如果持续时间较长时,则为位“1”。
  3.继续重复上述1,2步骤累计40次。

四. data线拉低50us代表读取结束

五. 校验数据

更多资料请参考DHT11 官方手册:
https://www.dfrobot.com.cn/image/data/DFR0067/DFR0067_DS_10.pdf

四、实验步骤

  第1步: 连接电路。

树莓派T型转接板温湿度传感器
GPIO0G17OUT(DATA)
5V5VVCC
GNDGNDGND

温湿度传感器DHT11 实验电路图

温湿度传感器DHT11 实验实物接线图

  第2步: 编写控制程序。将提取的二进制数据转化为十进制数据,校验后打印出来。
  本次编程中将用到NumPy(Numerical Python)扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。详情参考NumPy 教程:
  https://www.runoob.com/numpy/numpy-tutorial.html

  为便于对比DHT11高电平持续的时间,我们设置了一个计数器参数k,如果持续时间较短,则k值较小;如果持续时间较长时,则k值较大。当然,也可以使用时间函数直接对比时间长短,但是程序相对要复杂一些。比如使用GPIO.add_event_detect()和time.time()函数

执行结果截图

  从上面的截图中可以看出,高电平持续的时间较短,26-28 微秒时,参数k等于5或6;高电平持续的时间较长,70 微秒时,参数k等于17或18。

#!/usr/bin/env python
import RPi.GPIO as GPIO
import numpy as np
import time
 
DHTPIN = 17			#引脚号17

GPIO.setmode(GPIO.BCM)		#以BCM编码格式

def read_dht11_dat():
	
	GPIO.setup(DHTPIN, GPIO.OUT)
	GPIO.output(DHTPIN, GPIO.LOW)
	#给信号提示传感器开始工作,并保持低电平18ms以上
	time.sleep(0.02)				#这里保持20ms	
	GPIO.output(DHTPIN, GPIO.HIGH)  #然后输出高电平
	
	GPIO.setup(DHTPIN, GPIO.IN)    
	# 发送完开始信号后得把输出模式换成输入模式,不然信号线上电平始终被拉高
 
	while GPIO.input(DHTPIN) == GPIO.LOW:
		continue
	#DHT11发出应答信号,输出 80 微秒的低电平
	
	while GPIO.input(DHTPIN) == GPIO.HIGH:
		continue
	#紧接着输出 80 微秒的高电平通知外设准备接收数据
	
	
	#开始接收数据
	j = 0				#计数器
	data = []			#收到的二进制数据
	kk=[]				#存放每次高电平结束后的k值的列表
	while j < 40:
		k = 0
		while GPIO.input(DHTPIN) == GPIO.LOW:  # 先是 50 微秒的低电平
			continue
		
		while GPIO.input(DHTPIN) == GPIO.HIGH: # 接着是26-28微秒的高电平,或者 70 微秒的高电平
			k += 1
			if k > 100:
				break
		kk.append(k)
		if k < 8:		#26-28 微秒时高电平时通常k等于5或6
			data.append(0)		#在数据列表后面添加一位新的二进制数据“0”
		else:			#70 微秒时高电平时通常k等于17或18
			data.append(1)		#在数据列表后面添加一位新的二进制数据“1”
 
		j += 1
 
	print("sensor is working.")
	print '初始数据高低电平:\n',data	#输出初始数据高低电平
	print '参数k的列表内容:\n',kk		#输出高电平结束后的k值
	
	m = np.logspace(7,0,8,base=2,dtype=int)	#logspace()函数用于创建一个于等比数列的数组
	#即[128 64 32 16 8 4 2 1],8位二进制数各位的权值
	data_array = np.array(data)	#将data列表转换为数组

	#dot()函数对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为内积)
	humidity = m.dot(data_array[0:8])			#用前8位二进制数据计算湿度的十进制值
	humidity_point = m.dot(data_array[8:16])
	temperature = m.dot(data_array[16:24])
	temperature_point = m.dot(data_array[24:32])
	check = m.dot(data_array[32:40])
	
	print humidity,humidity_point,temperature,temperature_point,check
	
	tmp = humidity + humidity_point + temperature + temperature_point
	#十进制的数据相加
 
	if check == tmp:	#数据校验,相等则输出
		return humidity, temperature
	else:		        #错误输出错误信息
		return False
 
def main():
	print "Raspberry Pi DHT11 Temperature test program\n"
	time.sleep(1)			#通电后前一秒状态不稳定,时延一秒
	while True:
		result = read_dht11_dat()
		if result:
			humidity, temperature = result
			print "humidity: %s %%,  Temperature: %s  ℃" % \
			      (humidity, temperature)
			print '\n' 
			time.sleep(1)

		if result == False:
			print "Data are wrong,skip\n"
			time.sleep(1)
			
def destroy():
	GPIO.cleanup()

if __name__ == '__main__':
	try:
		main()
	except KeyboardInterrupt:
		destroy() 



  

<think>好的,用户现在想了解如何使用micro:bit通过继电器驱动直流风扇,并实现温度控制,包括连线方式和阈值设置。用户之前已经问过类似的问题,但这次可能希望得到更详细的步骤或者不同的角度。需要参考用户提供的引用,但注意到引用中的传感器树莓派的GPIO连接可能与micro:bit不同,所以需要调整到适合micro:bit的引脚。 首先,硬件部分需要明确micro:bit的扩展板接口,因为不同的扩展板引脚可能不同。用户提到继电器、温度传感器和风扇的连接,需要确认每个模块的正确接线方式,特别是电源部分,避免过载。例如,继电器可能需要5V供电,而micro:bit的扩展板是否能提供足够的电流,否则需要外接电源。 接着是温度传感器的选择,用户之前提到了DS18B20,但引用中提到了DHT11,可能需要说明两种传感器的不同连接方式。不过根据之前的回答,DS18B20更常见,所以继续使用DS18B20可能更合适,但需要明确数据引脚连接和上拉电阻的问题。 然后是关于继电器的触发方式,用户之前提到了低电平触发,需要确保代码中的控制信号正确。同时,用户可能关心如何测试继电器是否正常工作,比如用LED代替风扇进行测试,这部分需要包含在注意事项中。 代码部分需要基于MakeCode或Python,根据用户之前的示例,使用MakeCode比较合理。需要包括温度读取、阈值判断和继电器控制的基本逻辑,同时添加适当的延时和可能的校准提示。 用户还提到了阈值设置,可能需要解释如何调整阈值,并考虑温度传感器的误差,建议用户通过串口输出实时温度数据以便调试。另外,故障排查部分需要涵盖常见问题,如风扇不转、温度读数异常等,确保用户能自行解决基本问题。 最后,需要生成相关问题,引导用户进一步学习,比如多级风速控制、PWM调速或远程监控。这些问题应基于当前项目可能的扩展方向,帮助用户深入探索。</think>### 使用micro:bit通过继电器控制风扇的详细教程(含温度阈值联动) --- #### 一、硬件连接方案(基于扩展板) 1. **核心硬件清单** - micro:bit主板 + 扩展板(如Edge Connector Breakout) - 5V继电器模块(建议选择光耦隔离型) - DS18B20温度传感器(防水型或普通型) - 直流风扇(5V/12V,功率≤10W) - 杜邦线(母对母) 2. **接线映射表** | 模块 | 扩展板接口 | 物理引脚说明 | 注意事项 | |---------------|------------------|----------------------|------------------------------| | 继电器VCC | 扩展板5V输出 | 红色线 | 避免与micro:bit直接共电源[^1]| | 继电器GND | 扩展板GND | 黑色线 | 必须共地 | | 继电器IN | P0 | 白色/黄色线 | 控制信号线 | | DS18B20 VCC | 扩展板3.3V | 红色线 | 需4.7KΩ上拉电阻至DATA引脚 | | DS18B20 GND | 扩展板GND | 黑色线 | 与继电器共地 | | DS18B20 DATA | P1 | 蓝色线 | 单总线通信 | | 风扇正极 | 继电器NO(常开) | 红色线 | 继电器断开时风扇断电 | | 风扇负极 | 外部电源GND | 黑色线 | 独立供电时与扩展板GND连接 | > **连线验证工具** ```python # 快速测试继电器(需先连接P0) from microbit import * while True: pin0.write_digital(1) # 继电器吸合 sleep(1000) pin0.write_digital(0) # 继电器断开 sleep(1000) ``` --- #### 二、温度控制代码实现(Python版本) ```python from microbit import * import onewire, ds18x20 # 初始化DS18B20 ds_pin = pin1 ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin)) roms = ds_sensor.scan() threshold = 25 # 温度阈值(单位:℃) while True: ds_sensor.convert_temp() sleep(750) # 等待温度转换 temp = ds_sensor.read_temp(roms[0]) if temp > threshold: pin0.write_digital(1) # 触发继电器 else: pin0.write_digital(0) sleep(5000) # 每5秒检测一次 ``` --- #### 三、进阶配置技巧 1. **阈值动态调整** 添加按钮控制阈值增减(使用A/B键): ```python threshold = 25 while True: if button_a.was_pressed(): threshold += 1 if button_b.was_pressed(): threshold -= 1 display.scroll(str(threshold)) ``` 2. **温度显示优化** 在micro:bit LED矩阵实时显示温度: ```python display.show(Image.ARROW_N) if temp > threshold else display.show(Image.ARROW_S) ``` 3. **安全保护机制** ```python if temp > 50: # 过热保护 pin0.write_digital(0) display.show(Image.SKULL) break ``` --- #### 四、常见问题解决方案 | 故障现象 | 诊断步骤 | 工具验证方法 | |------------------|---------------------------------------|----------------------------------| | 继电器不动作 | 测量P0引脚电压(应有0V→3.3V跳变) | 万用表直流电压档 | | 温度显示-127℃ | 检查DS18B20接线顺序和上拉电阻 | 替换4.7KΩ电阻 | | 风扇启动延迟 | 增加`ds_sensor.convert_temp()`等待时间| 将sleep(750)改为sleep(1000) | | 继电器异常发热 | 检查风扇功率是否超过继电器触点容量 | 改用SSD固态继电器 | --- #### 五、扩展应用方向 1. **多传感器融合** 添加湿度传感器实现干湿双条件控制(如温度>25℃且湿度<60%时启动) 2. **云端监控** 通过蓝牙模块发送温度数据至手机APP(如Bitty Data Logger) 3. **能耗优化** 使用PWM控制风扇转速:`pin0.write_analog(512)`(需换用MOSFET模块) ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Maker 张

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值