Arduino HC05 蓝牙模块 实现手机与单片机下发通讯(遥控)

发布于:2024-12-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

本文中使用的是软件模拟串口,附有完整例程.
 

目录

本文中使用的是软件模拟串口,附有完整例程.​​​​​​​

0.相关软件

0.1下载链接:

1.HC05与USB转TTL

2.进入AT命令模式

2.1连线

2.2发送指令

3.简略版demo

3.1 HC05与arduino连线图

3.2实验现象

发射端(主机)(手机的蓝牙调试助手)

接收端(从机)

4.软件模拟串口 HEX格式接收 帧头 帧尾 校验代码

4.1实验现象

主机

从机

4.2代码

5.软串口 字符串格式 无校验 (处理函数中有阻塞)

5.1实验现象

主机

从机

5.2代码

 6.软串口 字符串格式 无校验 无阻塞

6.1实验现象

主机

从机

6.2代码


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 = "";
    }
  }
}