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 = "";
}
}
}
热门推荐
西安种植牙价格表:不同品牌种植牙价格差异及2025年收费标准
钢笔笔尖分类:5种常见形状及其特点
中药材合同编写要求及注意事项
Arduino智能小车的制作记录与综合应用
美育案例 | 女工戏剧:以艺术之光照亮女性劳动者之路
曼联完成今夏第五签!乌加特以5000万欧元转会费加盟
香蕉果酱的自制方法(以新鲜香蕉为原材料,享受纯正健康的味蕾盛宴)
诗歌的脊梁:解读“颈联”的含义与作用
银行的金融科技投资风险管理的流程优化分析
WPS云盘原账号清理指南:从解绑到注销的完整步骤
购买力平价理论:解析国际经济中的货币价值衡量
眉山温泉度假村哪家环境优美且性价比高?
【中草药科普】每天认识一味中草药-蛤蟆草
过量怕中毒,不补怕缺乏,AD滴剂该怎么补?
剖腹产后如何预防黏连
玉米面和白面混合做法,这些方法值得看!
历史揭秘:唐太宗与武则天的真实关系——并非如传闻般宠爱
PS怎么用JS脚本
八珍丸和十全大补丸的区别有哪些
黄芪泡酒的功效与作用
刘备与孙尚香:历史中的夫妻关系及其子嗣之谜
保险合同主险和附加险什么区别
欧宝车敞篷的开启方法是什么?敞篷车的使用注意事项有哪些?
了解遗体器官捐献:流程与注意事项
新生儿视力发育与自我检测方法
观“湘”门丨“桥”见幸福 见证湘潭城发集团国企责任与担当
晋文公——历尽千辛万苦成为春秋五霸之一的重耳
再上质量黑榜!回力1批次运动鞋耐折性能不合格
链式思维与思维树:AI如何提升推理能力
引起膝前痛的胫骨结节骨软骨炎的诊治