Arduino蓝牙模块相互通信
Made by Mike_Zhang
在使用Arduino做项目时, 各个元件都需要使用跳线与MCU或者其他元件连接, 一旦元件数量变多, 跳线数量也会变得很多很杂, 这不利于后期的整理和调整, 也会对信号的传输造成影响, 同时外观也不好看. 因此想用蓝牙代替传统的跳线, 并且能让蓝牙模块配合单片机实现互相通信.
材料
MCU: Arduino UNO R3 2
蓝牙模块: HC-08D 2
USB-TTL转接板 : HC-USB-T V2.0 *2
HC-USB-P串口助手 (下载链接)
蓝牙模块初始化
为了使两块蓝牙模块能够互相连接, 首先需要用USB-TTL转接板 和 HC-USB-P串口助手把两块HC-08D初始化并且设置其中一个为主机.
- 给两块HC-08D上电
- 把其中一块HC-08D与USB-TTL转接板相互连接, 然后把USB-TTL转接板接上电脑
- 打开HC-USB-P串口助手, 选择模块类型HC-08, 点击测试指令, 回复“OK”即为测试成功
- 点击“设置模块主机”, 然后在指令文本框中输入AT, 点击数据发送, 收到回复“OK”即为测试成功, 如图:
- 设置完成后, 两块蓝牙模块上的指示灯常亮说明连接已经成功, 之后断电后上电两块板会自动连接, 可以把两块板连接USB-TTL转接板, 并通过HC-USB-P串口助手互相给另一块板发送以及接收数据, 以测试连接的稳定性.
蓝牙模块与MCU连接方式
连接方式参考上图
VCC —- 5V
GND —- GND
TXD —- D5
RXD —- D3
主机与从机与MCU连接方式相同, 虽然称为主机和从机, 但是两者都具有传输和接收数据的功能, 名称不同只为了区分两者.
Arduino UNO 测试程序
初始化与连接完成后, 可以开始Arduino的编程, 以达到用MCU传输以及接收数据.
程序主体部分, 主机与从机是相同的, 数据处理部分就取决于自己的需求.
需要用到 SoftwareSerial.h 这一头文件, 使用read()方法接收数据, write()方法传输数据, 更多关于此头文件的内容, 请查看Arduino官网对此的描述.
参考程序如下:1
2
3
4
5
6
7
8
9
10
11
12
13#include<SoftwareSerial.h>
SoftwareSerial BT(5,3); // RX:5, TX:3 实例化一个名为BT的SoftwareSerial对象
int btRead;
void setup() {
Serial.begin(9600);
BT.begin(9600); // 初始化BT的频率, 一般为9600, 不建议修改
}
void loop() {
BT.write(100); // BT发送数据100到另一个蓝牙模块
btRead = BT.read(); // BT接收数据
Serial.println(btRead); // 串口打印数据
delay(100);
}
以上示例程序能够让两个MCU互相发送与接收数据, 随后在两个Arduino的串口监视器都能够看到接收的数据100. 可以让两块MCU发送不一样的数据, 以测试数据传输以及接收的成功.
在测试中可能会发现接收到的数据为-1, 这说明在某一时刻接收出错, 因此我们可以用available()方法或者检查read()的数据是否为-1来检查接收的成功性, 示例如下:
1 |
|
或者1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include<SoftwareSerial.h>
SoftwareSerial BT(5,3); // RX:5, TX:3 实例化一个名为BT的SoftwareSerial对象
int btRead;
void setup() {
Serial.begin(9600);
BT.begin(9600); // 初始化BT的频率, 一般为9600, 不建议修改
}
void loop() {
BT.write(100); // BT发送数据100到另一个蓝牙模块
btRead = BT.read(); // BT接收数据
if (btRead != -1){ // 检查接收成功性
Serial.println(btRead);// 串口打印数据
}
delay(100);
}
数据传输算法
需要注意的是, read()方法只能每次传输以及接收一个数据, 并且传输以及接收的是character类型的数据, 数据大小介于0到255, 共256个数据. 若要传输较大的数据, 可以采用同比缩小和放大的方法. 例如, 若要传输一值为12345的数据, 可以在发送端整除100, 变为123后在传输; 并且在接收端乘以100, 最后接收到的数据即为12300. 当然, 这样的过程产生了数据的误差.
此外, 在实际操作中, 我在传输端有多个旋转电阻模块, 用来控制接收端连接的多个舵机, 每一个舵机都是单独被旋转电阻模块控制的. 这种情况下, 用蓝牙模块就需要注意数据的分组以及顺序的匹配性, 不能使接收到的数据与传输的数据错位.
考虑到此蓝牙模块一次只能传输一个数据, 并且在测试中发现, 传输数据的顺序与接收数据的顺序是一致的, 不会发生偏移. 那只需要在发送端使旋转电阻模块的数据以一个特定的顺序发送, 并且在接收端以相同的顺序接收, 那就可以实现一一对应. 之后唯一需要做的就是使第一个值对齐, 防止数据的整体偏移.
因此, 我在每一组传输数据第一位前加上“000”的校验符, 使得接收端每次接收到“000”后, 开始处理校验符之后的数据, 以此使数据对齐. 一旦接收端没有接收到完整的“000”, 则重新接收下一组数据.
参考程序: (传输端有5个传感器控制接收端连接的5个舵机)
代码下载链接:
https://github.com/zhangwengyu999/Arduino_Bluetooth_Transceiving
发送端程序:
1 |
|
接收端程序:
1 |
|
写在最后
这是第一次研究Arduino的蓝牙模块, 学到很多所以记录一下, 会继续更新.
最后,希望大家一起交流,分享,指出问题,谢谢!
引用:
Arduino-SoftwareSerial Library
原创文章,转载请标明出处
Made by Mike_Zhang