Android手机HC-05蓝牙连接Arduino nano获取DHT-11温湿度传感器数据

如果您觉得本文对您有用,希望您点赞,收藏并且把它分享出去,不明白的可以在评论区留言,我会一一解答,感谢您的支持!!

目标

Android手机HC-05蓝牙连接Arduino nano获取DHT-11温湿度传感器数据
在这里插入图片描述

我以为的串口输出等于蓝牙输出,其实并不是

起初我所理解的,应该是这样连接
HC-05 nano
 TX----RX
 RX----TX
 5V----5V
GND----GND

HC-05蓝牙3.3V即可,5V蓝牙可以自适应不会烧掉

DHT-11 nano
 Out----D2
 5V----5V
GND----GND

DHT-11温湿度传感器5V没问题,3.3V也能用

我认为温湿度传感器输出到了串口,那么就等于输出到了蓝牙。
通电以后:DHT-11输出到蓝牙,安卓手机app接收蓝牙传过来的数据以文本显示在前端变量上

结果测试了很多次以后,发现输出是乱码。

于是我就怀疑起蓝牙到底发过来的是什么,蓝牙到底是怎样传输,我所认为的对不对。后来我发现蓝牙输出并不一定要用串口输出,所以就改变了接线。
HC-05 nano
 TX----D6
 RX----D5
 5V----5V
GND----GND

这时,nano即使USB串口连着电脑也可以正常烧录代码,不用拔插蓝牙的RX,TX了(主要是当蓝牙RX,TX连接了nano的TX,RX时,占用串口无法烧录,nano烧录的时候是使用这两个端口进行数据传输的)

单说nano DHT-11串口输出

#include <dht11.h> //引用dht11.h文件,头文件必须要有,如果没有后面输出会报错,必须放到工程文件夹下。
dht11 DHT11;	//实例化,我虽然不明白啥叫实例化,但这一句可能就是把dht11实例化给一个常量进行声明,以方便后面的参数调用吧。
#define DHT11PIN 2	//定义dht11输出引脚给一个变量,变量名可以修改,这里结尾没有";",不需要加分号
void setup() {
	Serial.begin(38400);	//串口对频
}	
void loop() {
  char chk = DHT11.read(DHT11PIN);		//读取温度传感器发出来的值
  Serial.println(DHT11.temperature);	//单行串口输出温度值
  Serial.println(DHT11.humidity);		//单行串口输出湿度值
  delay(1000);		//间隔1秒输出一次
}

那么我在想串口是啥呢?串口其实就是Serial,串口输出就是Serial.print
如果是蓝牙输出那就是Bluetooth.print,要是屏幕输出那就是LCD.print,扬声器输出那就是Sound.print,其实这个前缀(Serial,Bluetooth,LCD,Sound当然也可以改名,只要你知道就行)这些变量,应该就是在dht11.h里面定义的,不然的话没办法输出。

dht11.h源码

#ifndef dht11_h
#define dht11_h
#if defined(ARDUINO) && (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

#define DHT11LIB_VERSION "0.4.1"

#define DHTLIB_OK			0
#define DHTLIB_ERROR_CHECKSUM	-1
#define DHTLIB_ERROR_TIMEOUT	-2

class dht11
{
public:
    int read(int pin);
	int humidity;
	int temperature;
};
#endif

这里面太深我也看不懂,里面还包含了<Arduino.h>,<WProgram.h>文件,所以你的arduino编辑器也得加载这些库文件吧,不然的话无法运行
除此之外还有一个文件,也要放到工程目录下,不然的话无法运行

dht11.cpp源码

#include "dht11.h"
int dht11::read(int pin)
{
	// BUFFER TO RECEIVE
	uint8_t bits[5];
	uint8_t cnt = 7;
	uint8_t idx = 0;

	// EMPTY BUFFER
	for (int i=0; i< 5; i++) bits[i] = 0;

	// REQUEST SAMPLE
	pinMode(pin, OUTPUT);
	digitalWrite(pin, LOW);
	delay(18);
	digitalWrite(pin, HIGH);
	delayMicroseconds(40);
	pinMode(pin, INPUT);

	// ACKNOWLEDGE or TIMEOUT
	unsigned int loopCnt = 10000;
	while(digitalRead(pin) == LOW)
		if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;

	loopCnt = 10000;
	while(digitalRead(pin) == HIGH)
		if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;

	// READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
	for (int i=0; i<40; i++)
	{
		loopCnt = 10000;
		while(digitalRead(pin) == LOW)
			if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;

		unsigned long t = micros();

		loopCnt = 10000;
		while(digitalRead(pin) == HIGH)
			if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;

		if ((micros() - t) > 40) bits[idx] |= (1 << cnt);
		if (cnt == 0)   // next byte?
		{
			cnt = 7;    // restart at MSB
			idx++;      // next byte!
		}
		else cnt--;
	}
	humidity    = bits[0]; 
	temperature = bits[2]; 
	uint8_t sum = bits[0] + bits[2];  
	if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;
	return DHTLIB_OK;
}

我把大部分英文备注都去了,我也看不懂,我觉得是根据电路图
往引脚pin输出低电平,18毫秒后,输出高电平,40微秒后再往pin引脚输入,来获取传感器数值,并且放到一个数组里面,这个数组是bits,前两位是湿度值,后两位是温度值,uint8_t 代表无符号整形,8位=1字节,t是啥意思?typedef。代表他是通过typedef定义的头文件。其他的自己联想吧,不想看C的可以略过

再说nano HC-05蓝牙输出

以前我以为串口输出=蓝牙输出,其实不然,蓝牙可以是蓝牙,串口可以是串口。
之前还发过蓝牙调试,我当时写了其实也没太明白,现在感觉明白点了。

重点:HC-05蓝牙默认频率是38400,所以最好设置成这个,不然的话我感觉输出的内容可能会是乱码

之前输出到安卓手机的时候,始终是一个菱形框里面有个问号,要么就是多个菱形框里面有问号,大家可以手机下载蓝牙串口SPP连接蓝牙进行调试,看看输出的是什么。
当时还输出0x80啥的,我网上查了也查不到是啥,我起初以为是16进制输出需要转换成UTF-8,后来可能是我多想了。

#include <SoftwareSerial.h>		//引用库文件,这个文件应该是用于软件串口输出的
#include <dht11.h>
dht11 DHT11;
#define DHT11PIN 2
//Pin5为RX,接HC05的TX针脚
//Pin6为TX,接HC05的RX针脚
SoftwareSerial BT(6, 5);		//定义蓝牙输入输出引脚
char val;	//定义一个字符变量用于数据传输
void setup() {
  Serial.begin(38400); 		//串口输出,最终目标是温湿度传感器通过蓝牙发送到安卓手机,这两句其实可以不用写
  Serial.println("Buletooth is ready!");		//可以不写
  BT.begin(38400);		//定义蓝牙频率,nano连接蓝牙,他就用这个频率输出,无论是nano连蓝牙,还是蓝牙连串口都用这一个频率就对了,就好像nano连串口,输出频率要设置成9600,那么arduino软件串口的频率也要调成38400一样才能正确接收数据不会出现乱码一样。
}

void loop() {
  char chk = DHT11.read(DHT11PIN);	//之前已经实例化过了,现在是读取dht11数据
  BT.print(DHT11.temperature);		//蓝牙输出温度值
  BT.print("a");
  BT.print(DHT11.humidity);			//蓝牙输出湿度值
  BT.println("a");
  //当串口接收到数据读取串口赋值给val变量,并且蓝牙输出
  if (Serial.available()) {
    val = Serial.read();
    BT.print(val);
  }
  //当蓝牙接收到数据读取蓝牙赋值给val变量,并且串口输出
  if (BT.available()) {
    val = BT.read();
    Serial.print(val);
  }
  //我觉得上面两个if不用写也可以吧
  delay(1000);		//延迟1秒
}

以上就是传到nano上的源码了,还有一句没有说明,BT.print("a");就是这个,后面的App Inventor会用到。

蓝牙到底输出了什么,输出的是什么

我现在也没搞懂他到底输出了什么,我只知道他输出了温度值和湿度值,至于这个温度值和湿度值是什么格式我也不知道(后来知道能就是1个字节的8位整形无符号数),应该是int。

App inventor前端设计

在这里插入图片描述
样式就不说什么了,"连接蓝牙"是一个列表选择框,点击以后就会弹出蓝牙的列表,选择以后就建立蓝牙和手机的连接。
在这里插入图片描述
蓝牙客户端:
这里的蓝牙客户端所指的就是手机
字符编码:
默认设置为UTF-8,当然也可以支持ASCII,或者Unicode啥的,当然还有GBKBig5,其他的我都没测试,有可能是蓝牙发送中文的时候会用得到。这里蓝牙到底发的啥我也不知道,所以就UTF-8吧。
分隔符字节码:
我的理解是,因为蓝牙每间隔1秒发送一次数据给手机,那么他给手机的就是例如:2430,其中24表示温度值,30表示湿度值,但是我显示在前端应该是两个数据,在这1秒钟里,所以我对于蓝牙发送过来的数据进行拆分。如何进行拆分呢?那么就要在数据之间加入分隔符,我下位机加入分隔符的方法就是BT.print("a");加入了a字符,但在这个分隔符字节码选项里面我试了,#号不行,其他符号也不行,英文也不行,只能是0-9,所以我认为,它是按照字节进行分隔的,于是我就填入了1,按照1个字节进行分割,所以在程序中加入了,PS:这个a也可以是其他字母,最好不要是数字,因为会跟温湿度值混淆,避免出错,也就是蓝牙会输出成这样:24 a 30 a,那么到安卓app上面按照字节再进行拆分。
此外还要设置一个计时器,计时器的作用是:让蓝牙发送和蓝牙客户端接收数据能够同步进行,当手机连接到蓝牙以后,计时器启动,手机客户端接收,不然的话有可能会导致数据错位。
在这里插入图片描述
这里计时器的计时间隔我也设置成为1秒。

以上是组件设计,以下是逻辑设计

连接蓝牙的方法
在这里插入图片描述
在这里插入图片描述
当蓝牙选择完成时计时器开始启用
在这里插入图片描述
输入列表变量默认为空文本
在这里插入图片描述
当到计时器间隔点时,先清空变量,然后接收数据
在这里插入图片描述
这个函数表示:如果蓝牙客户端(手机)获取到了数据,那么就将蓝牙接收到的数据以文本的形式进行分割,然后就将分割完成后的第1项设置成为温度的文本,第2项设置成为湿度的文本。经过测试后,成功了。
整体截图
在这里插入图片描述
以下是手机app的测试截图
在这里插入图片描述
当然,以上测试还在使用串口供电,arduino nano也可以使用2节18650电池供电,单节电池是3.7V,要大于5V就得两节。所以还要重新设计电路。
以下是
高仿小米温湿度传感器样式制作的安卓app截图
在这里插入图片描述
如果您觉得本文对您有用,希望您点赞,收藏并且把它分享出去,不明白的可以在评论区留言,我会一一解答,感谢您的支持!!

<think>嗯,用户现在问的是“设备管理器的驱动状态是什么”。首先,我需要确定用户对这个概念的理解程度。他们可能在使用串口监视器时遇到了问题,之前问过错误代码1的解决方法,现在可能想更深入了解驱动状态相关的知识,以便自己排查问题。 用户之前的对话是关于串口监视器错误的解决方案,里面提到了检查设备管理器中的驱动状态。现在他们可能想更详细地了解驱动状态在设备管理器中的具体表现,以及如何通过这些信息来诊断硬件问题。 接下来,我应该解释设备管理器中的驱动状态有哪些类型,比如正常、警告、错误等,并说明每种状态对应的图标,比如黄色感叹号、红色叉号等。还要举例说明不同状态的可能原因,比如驱动未安装、版本不匹配、设备冲突等。 另外,用户可能需要知道如何查看这些状态,步骤要简单明了,适合不同水平的用户。比如在Windows中如何打开设备管理器,找到对应的设备,检查状态图标和属性中的详细信息。 还要考虑用户的实际应用场景,他们可能正在尝试解决硬件连接问题,尤其是与Arduino或其他开发板相关的驱动问题。因此,结合之前的串口错误,可以强调驱动状态异常会导致通信失败,并给出相应的解决建议,比如更新驱动、重新安装等。 需要确保语言通俗易懂,避免使用太多技术术语,但也要准确。同时,结构要清晰,分点列出不同状态及其含义,帮助用户快速查找和理解。最后,总结检查驱动状态的步骤,强化用户的操作流程。</think>以下是关于设备管理器驱动状态的详细说明: --- ### **一、驱动状态核心标识** 在Windows设备管理器中,驱动状态通过图标和文字描述显示硬件设备与驱动程序间的交互状态: | **图标** | **状态名称** | **技术含义** | **典型场景** | |-----------------|-------------------|--------------------------------------------|---------------------------------------| | ⬛ 无特殊标记 | 正常状态 | 驱动程序已正确加载,设备可被系统识别并工作 | 99%正常设备的工作状态 | | ⚠️ 黄色感叹号 | 代码28/Code 43 | 驱动程序未安装/版本不兼容/配置错误 | 新设备首次连接未装驱动 | | ❌ 红色叉号 | 设备禁用 | 设备被人为手动禁用 | 用户主动停用冗余设备 | | 🔄 蓝色问号 | 未知设备 | 系统无法识别设备类型 | 非常规硬件或驱动完全缺失 | | 💡 向下箭头 | 设备未激活 | 设备处于节能休眠状态 | USB设备选择性暂停功能启用 | --- ### **二、状态信息深度解析** #### **1. 属性对话框关键数据** 右键设备 → 属性 → 常规选项卡显示: - **设备状态代码**: - `0xC0000001`:驱动签名验证失败(常见于未签名的第三方驱动) - `0x80070005`:驱动程序安装权限不足 - `0x80070490`:设备所需服务被禁用 #### **2. 事件追踪功能** 在属性 → 事件选项卡可查看: - `Device configured (devinst_configured)`:最近一次成功驱动加载 - `Device not migrated (devinst_migrate_failed)`:系统升级后的驱动兼容问题 --- ### **三、状态异常处理流程** #### **1. 驱动验证工具** ```powershell # 检查驱动签名状态 pnputil /enum-drivers | findstr "Published Name" DriverVerifier /querysettings # 检测冲突驱动 ``` #### **2. 强制回滚操作** 当更新驱动导致异常时: 1. 设备属性 → 驱动程序 → 回滚驱动程序 2. 自动恢复至Windows认证的上个版本 --- ### **四、特殊状态应对方案** #### **1. 幽灵设备处理** 对已移除但残留的驱动记录: ```cmd devcon remove "@USB\VID_0403&PID_6001*" ``` #### **2. 资源冲突解决** 当设备显示`该设备无法分配足够资源(代码12)`: - BIOS中调整IRQ分配 - 禁用不必要的主板集成设备(如COM2端口) --- ### **五、最佳实践建议** 1. **驱动备份策略**: - 使用`dism /online /export-driver`导出当前系统所有驱动 2. **状态监控工具**: - 微软官方[Windows Performance Analyzer](https://docs.microsoft.com/zh-cn/windows-hardware/test/wpt/windows-performance-analyzer)可实时监控驱动加载过程 通过系统日志(`eventvwr.msc`)查看`Windows Logs → System`中的`DriverFrameworks-UserMode`事件源,可获取更精确的驱动故障时间线记录。
评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

望天吼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值