基于Arduino的蓝牙通信

本文介绍了如何在Arduino小车上实现蓝牙遥控,包括使用BT05蓝牙模块、AT指令、数据结构设计(布尔值与字符值)以及软串口调试。作者详细阐述了硬件配置、AT指令应用和两种不同的数据设计方法的比较。
摘要由CSDN通过智能技术生成

基于Arduino的蓝牙通信

前言: 本文主要以Arduino小车中的蓝牙遥控作为案例来讲解蓝牙通信。了解相关编程和数据设计。
功能和结构上:一个舵机控制小车前排车轮转向(模拟阿克曼转向结构),另外两个舵机控制车前部两轴云台,云台上放置ESP32 CAM用来拍摄。超声波传感器用来自动避障、三路红外用来巡线。


本例中用到的硬件:
主控UNO或Nano,
扩展板1块(板载有源蜂鸣器和蓝牙接口),
TT马达4个,
舵机3个,
超声波传感器1个,
三路红外传感器1个,
ESP32 CAM1个,
电源等


1.了解蓝牙模块

1.1.介绍

BT05 低功耗4.0蓝牙

  • 超低待机功耗 90uA~400uA
  • 超远连接距离100英尺/60米
  • 超快反应速度 0.4秒
  • 兼容iOS等多平台
  • 收发无字节限制,最高可达3K Bytes/秒

AT 指令只能在模块未连接状态下才能生效,一旦蓝牙模块与设备连接上,蓝牙模块即进入数据透传模式

AT指令集指南

1.2.引脚连接方式

  • 准备TTL转USB模块和蓝牙模块:(用Arduino板CH340再通过软串口同样可以在串口调试器上调试,不需要转接器)
    在这里插入图片描述
  • 连接线路
    在这里插入图片描述

2.串口调试助手(拓展,用于了解蓝牙AT命令)

2.1.打开即用串口助手

串口调试助手sscom下载

2.2.基础介绍

  • 1.确认端口号正确,而且没有被占用(这很重要,否则打开串口失败,例如Arduino IDE选中了该COM号之后在这里选同一个就会报警告);
  • 2.勾选“加回车换行”,这样在输入指令时就不需要加回车换行;
  • 3.波特率设置与蓝牙默认的保持一致(一般默认9600);
    在这里插入图片描述
    更多获取蓝牙信息的操作请看上文AT指令集指南

3.蓝牙调试APP作为小车遥控器

3.1.安装APP(安卓)

下载安装

3.2.APP使用介绍

来自大佬的教程

4.蓝牙通信数据设计

从功能上考虑遥控时需要通信的数据结构,一种是布尔值,一种是字符值。什么情况下用布尔值,例如控制小车左转弯,当你按下按钮发送信息左转,松手就不左转,只有动作和不动作两种情况,所以用布尔值。当你遥控小车想要不同速度行驶,这时发送速度信息就是速度值,是一个过程变化的量,用一个字节-128~127作为通信。同理,舵机控制转向左右角度值也是过程变化的量,同样各占用一个字节

4.1.蓝牙助手端数据设计

在这里插入图片描述
云台和单点控制组成一字节,剩下运动模式继续排在下一字节。移动方向摇杆和速度滑杆使用单独一字节。
APP内的数据结构设置:
在这里插入图片描述
这里面的逻辑值设置先后排序与下一节中代码设计有对应关系,不能乱调换位置。关于数据传输、数据帧等更多相关详细内容欢迎查看之前博文串行通信

4.2.主控板端代码数据设计

数据位为5个字节,加上包头、校验和包尾共8个字节的蓝牙数据包。

byte RX_package[8] = {0};
typedef struct      //5字节分布:
{
  byte ControlMode; //遥控八位:bit0~7:原地左转0x01、原地右转0x02、云台左转0x04、云台右转0x08、云台向上0x10、云台向下0x20、方向盘回正0x40、蜂鸣器打开0x80;
  byte MoveMode;    //运动模式四位:bit0~3:自由控制模式0x01、避障模式0x02、循迹模式0x04、跟随模式0x08
  byte x_axis = 0;  //摇杆X轴
  byte y_axis = 0;  //摇杆Y轴
  byte speed = 0;   //速度控制(App端控件范围默认-128~127,要想速度从0开始,就要加上128)
}rx_buffer;

为了更好的调试蓝牙数据,采用了软串口,避免频繁拔掉rx/tx。同时避免串口阻塞,增加Serialcount清阻。下面的小样例测试代码用Nano板测试的,蓝牙的TX连接Nano的D4,RX连接D3引脚,可以获取到调试APP发来的信息。

#include<SoftwareSerial.h>
/*
*SoftwareSerial(rxPin, txPin, inverse_logic)
*rxPin:接收串行数据的引脚。
*txPin:传输串行数据的引脚。
*inverse_logic:用于反转输入位的含义(默认为正常逻辑)。如果设置,
                SoftwareSerial 将 RX 引脚上的低电平(引脚上通常为 0v)
                视为 1 位(空闲状态),将高电平(引脚上通常为 5V)视为 0 位
                。它还会影响写入 TX 引脚的方式。默认值为 false。
*/  
int myvalue =0;
int Serialcount = 0;
SoftwareSerial softSerial(4, 3);
byte RX_package[8] = {0};
typedef struct      //5字节分布:
{
  byte ControlMode; 
  byte MoveMode;    
  byte x_axis = 0;  //摇杆X轴
  byte y_axis = 0;  //摇杆Y轴
  byte speed = 0;   //速度控制
}rx_buffer;

rx_buffer RX_buffer;

void setup() {
  Serial.begin(9600);
  softSerial.begin(9600);
  // softSerial.listen();
  // Serial.println(softSerial.isListening());
}

void loop() {
  if(softSerial.available()>0){
    delay(1);
    if(softSerial.readBytes(RX_package,8)){
      if(RX_package[0] == 0xA5 && RX_package[7] == 0x5A){
        Serialcount =0;
        RX_buffer.ControlMode = RX_package[1];
        RX_buffer.MoveMode = RX_package[2];
        RX_buffer.x_axis = RX_package[3];
        RX_buffer.y_axis = RX_package[4];
        RX_buffer.speed = map(RX_package[5], -128, 127, 0, 255);//-128~127
      }else{
          Serialcount++;
          // Serial.println("getit");
          return;
      }
        Serial.print("[1]ControlMode:");
        Serial.print(RX_package[1]);
        Serial.print("[2]MoveMode:");
        Serial.print(RX_package[2]);
        Serial.print("[3]X:");
        //无符号byte类型在print打印时自动转成有符号类型,
        //如果不转为int8_t看到的数值就不是负数,而是更大的数
        Serial.print((int8_t)RX_buffer.x_axis);
        Serial.print("[4]Y:");
        Serial.print((int8_t)RX_buffer.y_axis);
        Serial.print("[5]speed:");
        Serial.println(RX_buffer.speed);
    }
  }else
    {
        delay(1);
        Serialcount++;
        if(Serialcount > 500)
        {
            Serialcount = 0;
            RX_buffer.ControlMode = 0; 
            RX_buffer.MoveMode = 0;
            RX_buffer.x_axis = 0;
            RX_buffer.y_axis = 0;
        }
    }
}

在调试过程中遇到小问题:在Arduino IDE中,Serial.print() 函数将整数类型自动解释为有符号整数,因此当你传递负数给 Serial.print() 函数时,它会将其解释为有符号整数进行打印,而不会打印负号。导致数值不正确,折腾了好一会儿,用一个(int8_t)搞定了。

打开串口监视器得到的信息与预期一致:

在这里插入图片描述

4.3.不一定的数据设计

直接一个按钮对应一个字节,按一下发一个字符。每一个指令都有对应一个字符,接收到一个字符证明就有一个按钮按下。


if (Serial1.available() > 0) {  //判断接收到的数据是否大于0
    char ser_val = Serial1.read();
    Serial.print("ser_val=");
    Serial.println(ser_val);
    switch (ser_val) {
      case 'S': F_MOD = 0; break;  //车轮停止转动
      case 'F': F_MOD = 1; Serial.print("FFFFF");break;  //前进
      case 'B': F_MOD = 2; break;  //后退
      case 'Q': F_MOD = 3; break;  //方向盘回正后 原地左转
      case 'E': F_MOD = 4; break;  //方向盘回正后 原地右转

      case 'H': servo_mod = 0; break;  //云台、方向盘停止转动

      case 'Z': servo_mod = 1; break;  //方向盘左转
      case 'X': servo_mod = 2; break;  //方向盘回正
      case 'C': servo_mod = 3; break;  //方向盘右转

      case 'O': servo_mod = 4; break;  //云台回正
      case 'I': servo_mod = 5; break;  //云台左转
      case 'P': servo_mod = 6; break;  //云台右转
      case 'A': servo_mod = 7; break;  //云台向上
      case 'D': servo_mod = 8; break;  //云台向下

      case 'J': Buzzer = true; break;   //蜂鸣器打开
      case 'K': Buzzer = false; break;  //蜂鸣器关闭

      case '4': Car_MOD = 0; break;    //自由控制模式
      case '5': Car_MOD = 1; break;    //避障模式
      case '6': Car_MOD = 2; Steer_middle(); break; //默认先回正方向,切寻迹模式
      case '7': Car_MOD = 3; break;  //跟随模式
      default: break;
    }
  }

总结:
后一种通信设计功能上同样可以实现,与前一种方式相比需要增加一些停止的指令,在按钮松开时要发送停止指令。同时设置的按钮指令也会更多,对于蓝牙调试APP中有限的按钮设置来说不太现实的。将布尔值的开关量用字符值来代替在通信效率上也差了一些。对于同一字节来讲每一条指令为互斥关系,按了前进就不能同时旋转舵机,而前一种数据设计一个字节包含多个操作,在实际应用上更灵活,整体代码关系更简单。

搞完后才感慨这次又了解了不少东西,蓝牙AT命令、软串口和借助CH340在串口调试助手上调试数据、数据类型的设计转换等等。明天元宵开耍!开心!

  • 10
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Arduino蓝牙小车项目通常是一个有趣的DIY电子项目,它将Arduino微控制器与蓝牙模块结合起来,使小车可以通过手机或其他蓝牙设备进行遥控。以下是一个简要的介绍: 1. **Arduino核心**:Arduino Uno或类似板子作为控制中心,提供数字和模拟输入/输出,处理传感器数据和发送蓝牙指令。 2. **蓝牙模块**:如 HC-05 或 HC-06,这是一种低功耗、低成本的蓝牙通信模块,用于连接Arduino蓝牙设备。 3. **无线通信**:通过编写蓝牙库(如SoftwareSerial、BluetoothSerial等),Arduino蓝牙设备建立连接,接收从手机APP发送的移动命令(比如前进、后退、转向等)。 4. **机械结构**:小车通常由电机、车轮、电源和支架组成。电机用来驱动车轮,电源为整个系统供电。 5. **编码器或传感器**(可选):为了增强小车的精确度,可能会添加编码器或距离传感器,用于反馈速度和位置信息。 **步骤**: - 连接硬件:安装Arduino板、电机、蓝牙模块和电源。 - 编写代码:使用Arduino IDE编写程序,设置蓝牙通信,定义电机控制函数,并处理来自蓝牙设备的指令。 - 蓝牙配对:确保蓝牙模块与手机APP正确配对,发送预设的控制命令。 **相关问题**: 1. Arduino Uno在蓝牙小车中的具体作用是什么? 2. 如何选择适合的蓝牙模块来提高通讯稳定性? 3. 蓝牙小车项目中,如果需要远程控制,如何优化电池续航时间?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值