今天要跟大家分享的是两个蓝牙模块之间的通信,再结合摇杆模块和小车就可以做一个遥控小车啦!
在此之前,大家需要准备好两个蓝牙模块、两个摇杆模块、两个Arduino UNO开发板、一辆带电机驱动的小车、下载线、杜邦线等各种零件!然后跟着小编一起玩起来!
要实现两个蓝牙模块之间的通信就要先搞明白蓝牙模块的工作模式,HC-05是一款主从一体蓝牙模块,既有从机模式,也有主机模式,而且两者之间可以自行设置。
主机模式:蓝牙模块在主机模式下可以对周围的蓝牙设备进行搜索,并且可以选择需要连接的从机设备进行连接,连接成功后就可以发送数据和接收数据了。
从机模式:蓝牙模块在从机模式下不能主动搜索其他蓝牙设备,但是可以被主机模式下的蓝牙模块搜索到,而且与主机模式的蓝牙模块建立连接后也可以发送数据和接收数据。HC-05蓝牙模块默认工作在从机模式下。
设置蓝牙模块的主从机模式需要使用AT指令,所以我们先按照上一篇文章《浅谈Arduino进入蓝牙模块的AT指令模式》的方法给Arduino板子上传AT指令的程序,然后把其中一个蓝牙模块设置成主机模式,连接模式设置为任意蓝牙地址连接模式,并且设置好配对密码、波特率、蓝牙模块的名字。然后再把另外一个蓝牙模块设置成从机模式,连接模式、配对密码和波特率要和主机模式的蓝牙模块一样,否则会导致不能正常接收数据,蓝牙模块的名字可以不一样。通过Arduino进入AT指令的程序如下:
#include
SoftwareSerial softSerial = SoftwareSerial(10, 11);
String s="";
void setup() {
Serial.begin(9600); //串口监视器的波特率
softSerial.begin(38400); //蓝牙模块的波特率
}
void loop() {
if (Serial.available() > 0) {//判断串口监视器是否有指令发送
softSerial.write(Serial.read());//从串口监视器读取指令并发送给蓝牙模块
}
while (softSerial.available() > 0) {//判断蓝牙模块是否有指令发送过来
s = softSerial.readString();//读取蓝牙模块返回的信息
Serial.println(s);//把信息输出到串口监视器
}
}
这是小编设置的两个蓝牙模块:
注意:进入AT指令的方法是先按住蓝牙模块的小按钮再上电;设置蓝牙模块的名字时要把EN引脚接到3.3V引脚上。
设置完两个蓝牙模块的主从机模式以后,可以把两个模块分别接到两个Arduino板上,上电几秒后,两个蓝牙模块的指示灯会从快速闪烁变成慢速闪烁,这就表示两个蓝牙模块能够自动建立连接了。
接下来我们利用主机模式的蓝牙模块、Arudino板和摇杆模块制作一个遥控器,摇杆模块比较简单,我们直接用Arduino的A0~A5端口读取摇杆模块的VRX和VRY引脚的模拟信号即可,SW引脚是摇杆模块的按键,小编没有用到就直接空着了。
这几个模块的接线方式如下:
蓝牙模块 Arduino UNO
VCC ----------------- +5V
GND ---------------- GND
TXD ----------------- 11
RXD ----------------- 10
右侧摇杆 Arduino UNO
GND ----------------- GND
+5V ----------------- +5V
VRX ----------------- A0
VRY ----------------- A1
左侧摇杆 Arduino UNO
GND ----------------- GND
+5V ----------------- +5V
VRX ----------------- A2
VRY ----------------- A3
注意:这里比较难的是电源正极(+5V)引脚的分配,ArduinoUNO板上只有一个明确标识+5V的引脚,大家可以在遥控器上加一个小面包板,把+5V引脚扩展到面包板上,再从面包板上分配给摇杆和蓝牙模块即可。但是小编喜欢不走寻常路,因为UNO板上还隐藏着两个+5V和两个GND引脚,就是标着ICSP的接口和复位按钮旁边的接口,大家有兴趣可以查一下UNO板的电路图或者直接用万用表测试。
由于从Arduino的A0 ~ A5端口读取的模拟信号的数据范围在0 ~ 1023之间,而通过串口发送给蓝牙模块的数据和从串口缓存区读取的数据都是字节数据,另外通过蓝牙模块发送数据的时候还要对数据做一些简单的“加密”,这样受控端可以更加准确的读取数据,所以小编在程序中把0 ~ 1023的数据映射到了0 ~ 250之间,这样在给数据“加密”时,可以利用251 ~ 255这几个数字作为数据的开头和结尾发送出去。
#include
SoftwareSerial softSerial = SoftwareSerial(10, 11);
int rightX = 0, rightY = 0;
int leftX = 0, leftY = 0;
void setup() {
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
softSerial.begin(9600);
delay(100);
}
void loop() {
//读取摇杆数据
rightX = analogRead(A0);
rightY = analogRead(A1);
leftX = analogRead(A2);
leftY = analogRead(A3);
//将数据映射到指定数据范围,方便蓝牙传输
rightX = map(rightX, 0, 1023, 0, 250);
rightY = map(rightY, 0, 1023, 250, 0);
leftX = map(leftX, 0, 1023, 0, 250);
leftY = map(leftY, 0, 1023, 250, 0);
//蓝牙发送信息
softSerial.write(0xFC);//发送:开始标志数据
softSerial.write(leftY);//发送:左侧摇杆Y轴数据
softSerial.write(rightX);//发送:右侧摇杆X轴数据
softSerial.write(0xFE);//发送:结束标志数据
delay(100);//延时,避免蓝牙持续发送数据而堵塞串口
}
小车部分作为受控端,可以直接把从机模式的蓝牙模块连接到小车上,在连接蓝牙模块时要注意避免使用和控制小车速度的PWM端口冲突的端口,这句话是不是有点绕?
小编举个例子,以前在调试小车的时候发现,当使用3、5、6这几个PWM端口控制电机速度时,9、10、11这几个PWM端口会受到影响,尤其是使用这几个端口控制舵机或者红外接收器时,影响最明显,所以小编就把蓝牙模块的引脚接到了A0和A1端口。
蓝牙模块 Arduino UNO
VCC -------------- +5V
GND -------------- GND
TXD -------------- A0
RXD -------------- A1
建议:同学们在制作小车时可以先调试好小车的驱动程序,让小车能前后移动,在此基础上增加蓝牙接收程序,通过串口监视器观察蓝牙接收的数据是否正确,然后通过计算把数据转换成小车的速度,最后统一调试。
设计蓝牙接收数据的程序时,要先从串口的缓冲区读取第一个数据,当这个数据是发送来的数据的开头标志时再继续读取后面的数据;读取完所有的数据后,当判断开头标志和结束标志都正确时再处理摇杆数据。
为了便于控制小车,小编在程序中先把摇杆数据映射到了-250~250之间,然后利用加减法来消除摇杆模块中间位置的偏差,保证摇杆模块在中间位置时的数据为0。
另外,小编根据自己的习惯设定两个摇杆的工作方式,左侧摇杆的纵轴VRY设定为控制小车前进和后退,右侧摇杆的横轴VRX控制小车左右转向,两者结合可以控制小车一边前进/后退一边左转/右转,但是这样设定时还要在程序中对计算得到的速度值进行限定,不能超出-250~250的范围。
注意:摇杆的使用可以根据自己的想法和习惯自行设定,例如,可以直接把左侧摇杆的纵轴VRY的数据作为小车左侧电机的速度,右侧摇杆的纵轴VRY的数据作为小车右侧电机的速度。
小车端的部分程序如下:
void loop() {
//蓝牙接收信息
while (softSerial.available() > 0) {
buf[0] = softSerial.read();
if (buf[0] == 0xFC)//接收到正确的开始标志时再读取后面的数据
{
for (int i = 1; i < 4; i++)
buf[i] = softSerial.read();
}
}
//如果开始标志和结束标志都正确则表示可用使用其中的数据
if (buf[0] == 0xFC && buf[3] == 0xFE)
{
//将数据映射到指定范围内,便于控制小车的速度
leftY = map(buf[1], 0, 250, -250, 250);
rightX = map(buf[2], 0, 250, -250, 250);
//由于摇杆的中间位置有偏差,所以通过此方法将其调整为0
leftY = leftY + 8;
rightX = rightX + 4;
}
//将摇杆数据转换为小车的速度
//这里使用左侧摇杆控制小车前进和后退,右侧摇杆控制小车转向,两者配合更方便操控小车
leftSpeed = leftY + rightX;
rightSpeed = leftY - rightX;
//由于左右摇杆数值相加或相减时会超出电机的PWM值,所以利用判断语句将其控制在-200~200之间
//注意:Arduino中的PWM值为0~255,这里的最大值只到250,不影响控制小车的速度
if (leftSpeed < -250)
leftSpeed = -250;
if (leftSpeed > 250)
leftSpeed = 250;
if (rightSpeed < -250)
rightSpeed = -250;
if (rightSpeed > 250)
rightSpeed = 250;
setMotorSpeed(ENL, leftSpeed*0.6);
setMotorSpeed(ENR, rightSpeed*0.6);
delay(100);//延时,避免蓝牙持续发送数据而堵塞串口
}
蓝牙遥控小车视频:
蓝牙遥控小车2.0
篇幅有限,小编在这里只写了部分代码,完整的程序已经上传到网盘了,想要程序的同学,请先关注公众号哦,然后在对话框中回复“蓝牙遥控小车2.0”,即可获得下载链接,好东西不容错过。