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 = "";
}
}
}
热门推荐
盘点朝鲜和韩国半个世纪的恩怨情仇!
如何评估律师打官司的收费标准
青枣搭配普洱茶的食用指南
夜幕下的警钟:作息紊乱的危害
科学用油 让健康与美味同行
微信扫码授权登录的介绍
“老头乐”高速逆行致2人死亡,乱窜的“老头乐”安全从何而来?
成绩出来啦!六级和考研成绩如何换算?
合同条款编号规范:确保合同条款清晰易懂
卫生间总有味道怎么办?五大反味来源及解决方案
商业航天+低空经济:1+1>2的全球超级新基建
什么是系统自动交易?系统自动交易的优势有哪些?
如何通过DevOps自动化运维平台提升企业效率?
一年"酱酒热",几年价跌还?
国家免费师范生和地方免费师范生的区别有哪些
情理法:中国传统法律文化的精髓
属鸡人2025年每月运程
四季食单:春夏秋冬的美食选择
薪酬调查:行业薪酬差异,洞悉职场待遇真相
民法典婚前协议的内容有哪些
新能源汽车动力电池关键技术综述
招聘博士需28岁以下?“年轻化”不该“卷”年龄
硅胶泥耳塞:让浅睡眠者告别噪音困扰的小神器
2025年度个人所得税退税办理指南与注意事项
安康这些春天的美味,你吃过几种?
AI冲击下的职业变迁:哪些传统岗位正面临消失风险?
地方政府偿债能力指标详解:债务率、偿债率、逾期债务率和借新还旧偿债率
维生素D2和D3的区别:素食者的补充指南
2025 工作签证最新政策:如何前往日本工作?
如何判断化妆品是否过期?