HC05 蓝牙模块 Arduino 实现手机与单片机下发通讯(遥控)
创作时间:
作者:
@小白创作中心
HC05 蓝牙模块 Arduino 实现手机与单片机下发通讯(遥控)
引用
CSDN
1.
https://blog.csdn.net/qq_66771136/article/details/144607973
本文将详细介绍如何使用HC05蓝牙模块与Arduino实现手机与单片机之间的通信。文章内容包括HC05模块的基本配置、Arduino与HC05的连接方式,以及多种数据传输方式的示例代码。
0.相关软件
0.1下载链接:
链接: https://pan.baidu.com/s/1cFXqshrRk7hNMwSu7eCPbQ?pwd=ahao 提取码: ahao
1.HC05与USB转TTL
2.进入AT命令模式
2.1连线
HC-05 USB转TTL
STATE NC(不连)
RXD 9
TXD 8
GND GND
VCC +5V
EN NC
连接好线路后,按住HC05的按键,然后给模块重新上电,HC05指示灯慢闪(2秒闪一次)代表进入AT模式
2.2发送指令
在串口调试助手上发送指令,HC05的指令模式的波特率默认是38400.
勾选回车换行后依次发送(期间每个指令都会回传OK)
AT+NAME=HC-05 修改蓝牙模块名称为HC-05
AT+ROLE=0 蓝牙模式为从模式
AT+CMODE=1 蓝牙连接模式为任意地址连接模式,也就是说 该模块可以被任意蓝牙设备连接
AT+PSWD=1234 蓝牙配对密码为1234
AT+UART=9600,0,0 蓝牙通信串口波特率为9600,停止位1位, 无校验位
完成指令配置.
之后就是arduino与HC05的连接.
3.简略版demo
3.1 HC05与arduino连线图
//arduino的GND接蓝牙或串口工具的GND,共地
//arduino的9接蓝牙或串口工具的RX
//arduino的8接蓝牙或串口工具的TX
//arduino的5V接蓝牙的5V
//根据自己的实际改为对应的串口,我这里接的是8和9
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8,9);
int led = 13;
void setup()
{
Serial.begin(9600);
pinMode(led,OUTPUT);//定义小灯为输出模式
BTSerial.begin(9600);
}
void loop()
{
if (BTSerial.available())
{
char var;
var = BTSerial.read(); //从串口接收数据
if (var == '1') {
digitalWrite(led, HIGH);
Serial.println("LED is on!");
}
if (var == '0') {
digitalWrite(led, LOW);
Serial.println("LED is off");
}
}
}
3.2实验现象
发射端(主机)(手机的蓝牙调试助手)
接收端(从机)
4.软件模拟串口 HEX格式接收 帧头 帧尾 校验代码
4.1实验现象
主机
从机
4.2代码
//arduino的GND接蓝牙或串口工具的GND,共地
//arduino的9接蓝牙或串口工具的RX
//arduino的8接蓝牙或串口工具的TX
//arduino的5V接蓝牙的5V
//根据自己的实际改为对应的串口,我这里接的是8和9
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8,9);
#define FRAME_LENGTH 7
char str[100];
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("CongHC-05 is opened:");
BTSerial.begin(9600);
while (BTSerial.read() >= 0); //清空BT串口缓冲区
}
void loop() {
// put your main code here, to run repeatedly:
receive();
}
void receive()
{
//当串口缓冲区大于等于6时
while (BTSerial.available() >= FRAME_LENGTH) {
unsigned char ubuffer[FRAME_LENGTH];
//从串口缓冲读取1个字节但不删除
unsigned char frame_header = BTSerial.peek();
//当获取的数据是包头(0x55)时
if (frame_header == 0x55)
{
//从串口缓冲区读取7字节
BTSerial.readBytes(ubuffer, FRAME_LENGTH);
if (ubuffer[4] == 0xff && ubuffer[5] == 0xff && ubuffer[6] == 0xff) {
if(ubuffer[1] == 0x01)
{
//下发的是LED信息
sprintf(str,"led %d %s\r\n", ubuffer[2], ubuffer[3] ? "打开" : "关闭");
Serial.print(str);
}else if(ubuffer[1] == 0x02)
{
//下发的是风扇
sprintf(str, "风扇 %d %s\r\n", ubuffer[2], ubuffer[3] ? "打开" : "关闭");
Serial.print(str);
}else if(ubuffer[1] == 0x03)
{
//下发的是继电器的信息
sprintf(str, "继电器 %d %s\r\n", ubuffer[2], ubuffer[3] ? "打开" : "关闭");
Serial.print(str);
}
}
} else {
BTSerial.read(); //从串口缓冲读取1个字节并删除
}
}
}
//例子1:上位机代码 55 01 01 00 ff ff ff 含义:1号led关闭
//例子2:上位机代码 55 01 04 01 ff ff ff 含义:4号led打开
//例子3:上位机代码 55 02 01 01 ff ff ff 含义:1号风扇打开
//例子4:上位机代码 55 03 04 00 ff ff ff 含义:4号继电器关闭
5.软串口 字符串格式 无校验 (处理函数中有阻塞)
5.1实验现象
主机
从机
5.2代码
//arduino的GND接蓝牙或串口工具的GND,共地
//arduino的9接蓝牙或串口工具的RX
//arduino的8接蓝牙或串口工具的TX
//arduino的5V接蓝牙的5V
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8,9);
void setup() {
Serial.begin(9600); // 设置串口波特率
BTSerial.begin(9600);
while (BTSerial.read() >= 0); //清空BT串口缓冲区
}
void loop() {
receive();
}
void receive()
{
if (BTSerial.available() > 0) { // 判断是否有数据可用
String inStr = ""; // 初始化字符串
inStr.reserve(128); // 预分配内存空间,避免多次动态分配(根据实际需要调整大小)
// 读取串口数据,直到没有更多数据
while (BTSerial.available() > 0) {
inStr += (char)BTSerial.read(); // 拼接读取的字符
delay(5); // 小延时,避免阻塞,允许其他任务运行
}
// 移除输入数据中的换行符和回车符
inStr.trim(); // trim() 会移除字符串两端的空格、换行符和回车符
// 输出清理后的字符串
//Serial.println(inStr); // 输出读取的字符串
// 检查inStr中是否包含"txt"
if (inStr.indexOf("ledon") >= 0) { // indexOf返回匹配子字符串的起始位置,若找不到则返回-1
Serial.println("led打开"); // 如果包含"ledon",输出"ok"
}
if (inStr.indexOf("ledoff") >= 0) { // indexOf返回匹配子字符串的起始位置,若找不到则返回-1
Serial.println("led关闭"); // 如果包含"ledon",输出"ok"
}
if (inStr.indexOf("jion") >= 0) { // indexOf返回匹配子字符串的起始位置,若找不到则返回-1
Serial.println("继电器打开"); // 如果包含"ledon",输出"ok"
}
}
}
6.软串口 字符串格式 无校验 无阻塞
6.1实验现象
主机
从机
6.2代码
//arduino的GND接蓝牙或串口工具的GND,共地
//arduino的9接蓝牙或串口工具的RX
//arduino的8接蓝牙或串口工具的TX
//arduino的5V接蓝牙的5V
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8,9);
void setup() {
Serial.begin(9600); // 设置串口波特率
BTSerial.begin(9600);
while (BTSerial.read() >= 0); //清空BT串口缓冲区
}
void loop() {
receive();
}
void receive()
{
static String inStr = ""; // 使用静态变量保持输入字符串
static unsigned long lastReadTime = 0; // 记录上次读取的时间
// 每次循环检查串口是否有数据可用
if (BTSerial.available() > 0) { // 判断是否有数据可用
unsigned long currentMillis = millis(); // 获取当前时间
// 判断是否距离上次读取时间超过一定间隔(避免过快读取)
if (currentMillis - lastReadTime > 10) { // 每10ms读取一次数据
inStr += (char)BTSerial.read(); // 拼接读取的字符
lastReadTime = currentMillis; // 更新上次读取时间
}
// 如果读取到完整的一行数据(假设换行符为结束标志)
if (inStr.indexOf('\n') >= 0) {
// 移除输入数据中的换行符和回车符
inStr.trim(); // trim() 会移除字符串两端的空格、换行符和回车符
// 输出清理后的字符串
//Serial.println(inStr); // 输出读取的字符串
// 检查inStr中是否包含"txt"
if (inStr.indexOf("txt") >= 0) { // indexOf返回匹配子字符串的起始位置,若找不到则返回-1
Serial.println("ok"); // 如果包含"txt",输出"ok"
}
if (inStr.indexOf("ledon") >= 0) { // indexOf返回匹配子字符串的起始位置,若找不到则返回-1
Serial.println("led已经打开"); // 如果包含"txt",输出"ok"
}
if (inStr.indexOf("ledoff") >= 0) { // indexOf返回匹配子字符串的起始位置,若找不到则返回-1
Serial.println("led已经关闭"); // 如果包含"txt",输出"ok"
}
// 重置字符串,准备下一次输入
inStr = "";
}
}
}
热门推荐
鸡的象征意义和精神
TN-C系统与TN-S系统详解:供配电系统的两种主要类型
“00后”涌入佛山工厂,要高薪,也要体面
餐边柜选购全攻略:从选材到布局,一文掌握核心要点
5种餐边柜设计拯救小餐厅!收纳扩容×颜值翻倍攻略
青岛郊区自驾游烧烤攻略
咖啡的种类及制作原理
南京市妇幼保健院丁家庄院区正式启用 就医感受焕然“医”新
如何用特效和视觉效果为电影增加独特魅力
电锯:类型、品牌、使用方法与安全指南
北京买房退税的办理流程,北京买房退税的办理流程及时间
八字命理学习指南:从入门到精通的五个步骤
彭光谦:伟人母亲文素勤系民族英雄文天祥后裔
感冒是什么病毒
结膜炎和角膜炎的区别是什么?
美元走势仍是影响人民币汇率的主要因素
南京南站内换乘怎么换
神舟十九号成功发射,美国人如今可曾懊悔:当初不该放钱学森回国?
CPL门可以打发泡胶固定吗?专业分析与建议
12张跳芭蕾的小女生涂色图片免费下载!附详细绘画教程
“海上精灵”频现三亚,背后的生态“答案”是……
高效LED照明解决方案提升道路行车安全
路灯智能控制器到底能为道路照明做些什么?
降压药应该啥时候吃?早晨、中午还是晚上?
更年期不用干预?这是个误会 | 世界更年期关怀日
一文读懂:宝宝口腔溃疡、手足口病、鹅口疮如何区分?
企业拖欠劳动者工资的利息怎么计算
中式婚礼喜娘的任务 中式婚礼喜娘是干嘛的
集成光伏的含义、工作原理和应用领域
巫师3终极攻略:阿尔德刺骨技能深度解析,伤害爆表与战术效果全!