特此声明,本文所有内容是在参考以下链接的基础上整理并开发的,所有代码均验证无误。如果你想使用或者发表,请您声明出处。
一,实验目的。
本文使用两个Arduino UNO板子,两个HC-05,分别作为主站和从站,实现主站按钮控制从站小车运动。
二,蓝牙HC-05的主从站初始AT配置方法:
1,蓝牙模块介绍:
常见的蓝牙模块按型号可分为HC-05和HC-06两种,HC-05既可以作为主站使用,又可以作为从站使用。而HC-06只能作为从站使用。
主机:用来搜索从设备,不能被其他设备搜索。(有白点或者对勾标记的那个)
从机:用来被搜索的设备,不能主动搜索其他设备。主从连上以后就相当于一根串口线使用,这个时候就不分主从,也就是透传模式。
这俩长相都差不多,仔细看会发现HC-05模块有一个对勾或者白点,如下图所示:
然后HC-05主从一体的蓝牙模块又分为两种,一种是有KEY脚的,一种是有EN脚的。这俩的使用区别是:
在AT模式设定的时候,有KEY的需要,在上电前将KEY脚与3.3V脚连接,INT脚不接;
有EN的需要,在上电前按住按钮不放,再上电,且除了VCC,GND,RX,TX之外的引脚都不接。
在本实验中我计划使用一个有KEY脚的HC-05作为主站(下文简称为主站),另一个有EN脚的作为从站(下文简称为从站)。
2.主站AT模式配置
首先是硬件链接,请看下图所示的示意图:
无论你用带KEY脚的作为主站还是用EN脚的作为主站,在AT配置中都没关系,电路连接方式可以参考我画的。
值得说明的是:1. 尽管Arduino引脚的电压接近3.3伏,但还是出于安全考虑,我们将Arduino的11引脚(Arduino的发送端)接上2K的保护电阻,在无信号传输的时候端口是低电平状态。(实际上你不接这个保护电阻也没啥,我的就没烧,哈哈,说话还是要负责任,建议大家还是接上好)。
2. 网上有人说可以直接将HC-05的RX接Arduino的TX,将HC-05的TX接Arduino的RX,这样说确实没错,但是当你的电脑与Arduino下载或者使用串口监视器的时候,那样做就不合适,因为Arduino的TX端口被电脑和蓝牙同时占用,互相之间有扰动,尤其是波特率设置不同的时候。所以,本实验将蓝牙的TXD/RXD脚接在新的Arduino脚,避免冲突。
在硬件如上图接好后,将Arduino与电脑连接,打开Arduino IDE, 匹配好COM口。
看到蓝牙上的指示灯2秒一闪就说明进入了AT模式
将以下代码下载到Arduino中:
//HC-05分为有EN和有key两种:
//有EN的需要,在上电前按住按钮不放,再上电,且除了VCC,GND,RX,TX之外的引脚都不接
//有KEY的需要,在上电前将KEY脚与3.3V脚连接,INT脚不接
#include <SoftwareSerial.h>
//使用软件串口,能讲数字口模拟成串口
SoftwareSerial BT(10, 11);
// Pin10为RX,接HC05的TXD
// Pin11为TX,接HC05的RXD
char val; //存储接收的变量
void setup() {
Serial.begin(9600); //与电脑的串口连接,串口监视器波特率设置为9600
Serial.println("BT is ready!");
BT.begin(38400); //设置蓝牙波特率为默认值
}
void loop() {
//如果串口接收到数据,就输出到蓝牙串口
if (Serial.available()) {
val = Serial.read();
BT.print(val);
}
//如果接收到蓝牙模块的数据,输出到屏幕
if (BT.available()) {
val = BT.read();
Serial.print(val);
}
}
//当发现串口监视器显示BT is ready!后,输入AT点击键盘回车一次,当看到OK的时候就说明可以进行AT模式设置了。
网上有的人说,到这步有点看不见OK,常见的问题有两个,一个是RXD/TXD接反了,两一个是波特率设置错误,要知道蓝牙模块的默认波特率是38400,电脑与Arduino匹配的常用波特率为9600.别搞混。
然后打开串口监视器,你就看见如下图所示的内容:
现在我们需要在串口监视器中输入以下内容进行主站AT配置:(每次指令必须手动按键盘回车一次)
输入顺序从上到下:
AT 进入AT模式设置
AT+ORGL 恢复出厂设置
AT+NAME=HX01 设置蓝牙的名字为 'HX01'(你改成别的也行)
AT+ROLE=1 # 作为主站使用
AT+CMODE=1 # 设置该蓝牙为允许任意设备检测模式(=0是仅允许当前设备接入,多设备控制就=1,单设备就=0)
AT+PSWD=1234 # 设置密码为 1234
主站就配置完成了,暂时先将它搁置一边。当看到都OK的时候就可以断电了。
3. 从站AT模式配置
现在我们那另一个Arduino UNO板子连接一个有EN脚的HC-05模块,用他们作为从站。有EN的需要,在上电前按住按钮不放,再上电,且除了VCC,GND,RX,TX之外的引脚都不接。Pin10作为Arduino的RX端,接HC05的TXD。Pin11为TX,接HC05的RXD。(出于安全考虑HC-05的接收端RX还是像上图电路连接图那样串接一个保护电阻)
看到蓝牙上的指示灯2秒一闪就说明进入了AT模式
软件代码还是上文那个代码,原封不动的将它下载到从站Arduino中。打开串口监视器,看到BT is ready! 后输入AT回车,看到如下图所示:
然后输入以下指令对从站进行AT配置:(输入顺序从上到下)
AT+ORGL 恢复出厂设置(有EN脚的进行配置时当输入恢复出厂设置时,它会恢复快闪,需要重新断电上电才能进行下一步)
AT+NAME=HX01 设置蓝牙名字为 'HX01'(主从站名字必须一致)
AT+ROLE=0 作为从站使用
AT+CMODE=1 设置为任何设备可检测到
AT+PSWD=1234 设置匹配密码为 1234(主从站密码必须一致)
从站就配置完成了,暂时先将它搁置一边。当看到都OK的时候就可以断电了。
我想会有人质疑为啥不输入AT+ADDR?获得地址,别急呀,放到下文再说,怕新手学不懂。
另外我不是卖东西的,就夸一句,德飞莱牌的LY-BL001,HC-05蓝牙模块太好使了,比ZS-040稳定多了。淘宝上买二还送一个转TTL模块。啧啧
4. 主站从站配置连接
我们继续,在从站的AT模式下,串口监视器输入指令“AT+ADDR?”点击回车,查询从站的地址为下图所示
我们需要记住它。
如果你用蓝牙APP扫描它,实际上它的地址是这样表示的(20:19:06:27:11:30)
下文是我直接粘贴的台湾人的介绍,他的连接在本文末尾处贴上,有兴趣的同学可以去看一下
然后我们用同样的方法获得主站的地址:2019:6:271123
在主站的AT模式下的串口监视器中输入指令:AT+BIND=2019,6,271130(主站绑上从站)
在从站的AT模式下的串口监视器中输入指令:AT+BIND=2019,6,271123(从站绑上主站)
等双方窗口都设置完成,就完成了最终的AT配置。以上设置会永久保存在蓝牙芯片中,直到下次恢复出厂设置,重新写入。
三,蓝牙一对一传输测试
现在我们测试一下,无线传输。我们让主站窗口手打发送0和1给从站,然后让从站检测到0和1信号后,控制LED灯亮灭。
在这之前要把有KEY引脚的那个蓝牙模块的KEY引脚悬空(啥也不接)
给主站输入如下代码:
//这是蓝牙主站代码
#include <SoftwareSerial.h> // 引用函数库
SoftwareSerial BT(10, 11); // 接收,传送
char val; // 储存串口发送值
void setup() {
Serial.begin(9600); // 与电脑连接的波特率
Serial.println("BT is ready!");
// 蓝牙模式设置的波特率
BT.begin(38400);
}
void loop() {
// 若读到串口监视器的值,则给蓝牙
if (Serial.available()) {
val = Serial.read();
BT.print(val);
}
// 若收到蓝牙值,则给串口监视器
if (BT.available()) {
val = BT.read();
Serial.print(val);
}
}
给从站Arduino下载如下代码:
//这是从站代码,LED灯正极串联一个1K电阻,负极接Arduino的P13脚
#include <SoftwareSerial.h> // 引用BT函数库
SoftwareSerial BT(10, 11); // 接收脚,传送脚
char val; // 存储接收的值
const byte LED_PIN = 13; // 定义LED引脚
void setup() {
// 设定蓝牙模块初始波特率
BT.begin(38400);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// 若收到值,则送到串口监视窗
if (BT.available()) {
val = BT.read();
if (val == '1') {
digitalWrite(LED_PIN, LOW);
// 回应命令发送端,开灯
BT.println("LED ON");
} else if (val == '0') {
digitalWrite(LED_PIN, HIGH);
// 回应命令发送端,关灯
BT.println("LED OFF");
}
}
}
然后回到主站的串口监视器窗口下,手打输入0或者1,你就会发现从站LED灯在你的控制下亮灭,同时主站串口监视器显示:
嗯,到目前为止,成功了。
四,主站按钮无线控制从站蓝牙小车
我用的是Arduino自带的电机驱动板(Arduino Motor Shield),它的引脚与传统的L298N配置不太一样,它是用单个引脚控制电机的前进和后退(高电平前进,低电平后退)。它的引脚配置说明请见代码。
这是蓝牙主站代码:
//这是蓝牙主站代码
#include <SoftwareSerial.h> // 引用函数库
SoftwareSerial BT(10, 11); // 接收,传送
char val; // 储存串口发送值
const int buttonPin0 = 2; // the number of the pushbutton pin
const int buttonPin1 = 3;
const int buttonPin2 = 4;
const int buttonPin3 = 5;
const int buttonPin4 = 6;
int buttonState0 = 0; //初始化按键状态
int buttonState1= 0;
int buttonState2= 0;
int buttonState3= 0;
int buttonState4= 0;
void setup() {
Serial.begin(9600); // 与电脑连接的波特率
Serial.println("BT is ready!");
// 蓝牙模式设置的波特率
BT.begin(38400);
//设置主站按键
pinMode(buttonPin0, INPUT);//Stop
pinMode(buttonPin1, INPUT);//Go
pinMode(buttonPin2, INPUT);//Back
pinMode(buttonPin3, INPUT);//Left
pinMode(buttonPin4, INPUT);//Right
}
void loop() {
buttonState0 = digitalRead(buttonPin0);
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
buttonState4 = digitalRead(buttonPin4);
Monitor();
}
void Button(){
if (buttonState0 == LOW) {
BT.print(0);//给蓝牙串口输入0
if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态
val = BT.read();
Serial.print(val);
}
}
else if(buttonState1 == LOW){
BT.print(1);//给蓝牙串口输入1
if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态
val = BT.read();
Serial.print(val);
}
}
else if(buttonState2 == LOW){
BT.print(2);//给蓝牙串口输入2
if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态
val = BT.read();
Serial.print(val);
}
}
else if(buttonState3 == LOW){
BT.print(3);//给蓝牙串口输入3
if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态
val = BT.read();
Serial.print(val);
}
}
else if(buttonState4 == LOW){
BT.print(4);//给蓝牙串口输入4
if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态
val = BT.read();
Serial.print(val);
}
}
}
void Monitor(){
// 若读到串口监视器的值,则给蓝牙
if (Serial.available()) {
val = Serial.read();
BT.print(val);
}
// 若收到蓝牙值,则给串口监视器
if (BT.available()) {
val = BT.read();
Serial.print(val);
}
}
下面是从站代码
//这是从站机器人
#include <SoftwareSerial.h> // 引用BT函数库
SoftwareSerial BT(5, 6); // 接收脚,传送脚
char val; // 蓝牙传输存储接收的值
int dira=13; //左电机直行高电平后退低
int dirb=12; //右电机直行高电平后退低
int pwmb=11; //右电机PWM速度控制
int bra=9; //左电机制动使能(高停低动)
int brb=8; //右电机制动使能(高停低动)
int pwma=3; //左电机PWM速度控制
void setup() {
BT.begin(38400); // 设定蓝牙模块初始波特率
Serial.begin(9600);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
pinMode(3,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(11,OUTPUT);
}
void loop() {
// 若收到值,则送到串口监视窗
if (BT.available()) {
val = BT.read();
if (val == '1') {
Go();// 1代表前进
BT.println("Go");//回应主站当前状态
}
else if (val == '0') {
Stop();//0代表停车
BT.println("Stop");//回应主站当前状态
}
else if (val == '2') {
Back();//2代表后退
BT.println("Back");//回应主站当前状态
}
else if (val == '3') {
Left();//3代表左转
delay(300);
Stop();
BT.println("Left");//回应主站当前状态
}
else if (val == '4') {
Right();//4代表右转
delay(300);
Stop();
BT.println("Right");//回应主站当前状态
}
}
}
void Go()
{
digitalWrite(12,HIGH); //双电机前进
digitalWrite(13,HIGH);
digitalWrite(8,LOW); //双电机制动关
digitalWrite(9,LOW);
digitalWrite(3,200);//设置PWM A占空比
digitalWrite(11,200);//设置PWM B占空比
}
void Back()
{
digitalWrite(12,LOW);//双电机后退
digitalWrite(13,LOW);
digitalWrite(8,LOW); //双电机制动关
digitalWrite(9,LOW);
digitalWrite(3,200);//设置PWM A占空比
digitalWrite(11,255);//设置PWM B占空比
}
void Stop()
{
digitalWrite(8,HIGH); //双电机制动开
digitalWrite(9,HIGH);
}
void Left()
{
digitalWrite(12,HIGH);//右前
digitalWrite(13,LOW);//左退
digitalWrite(8,LOW); //双电机制动关
digitalWrite(9,LOW);
digitalWrite(3,200);//设置PWM A占空比
digitalWrite(11,255);//设置PWM B占空比
}
void Right()
{
digitalWrite(12,LOW);//右退
digitalWrite(13,HIGH);//左前
digitalWrite(8,LOW); //双电机制动关
digitalWrite(9,LOW);
digitalWrite(3,200);//设置PWM A占空比
digitalWrite(11,255);//设置PWM B占空比
}
主站代码没有写按键消抖功能,所以当按键按下的时候,它会给从站发射很多次信号,在这点上,大家可以通过加检测延时或者其他消抖代码进行补偿改进。主站代码也可以使用上文用过的串口进行发送,控制小车。
就完事了。
大家可以去试一下,下面连接的第三个,电位器主站控制从站伺服电机。
五,链接参考。
1. 自己编写手机蓝牙APP教程(本实验中没有用到,但是很有用,推荐给大家):
https://blog.csdn.net/qq_41381461/article/details/90047414
2. HC-05蓝牙AT模式配置步骤与代码意义:
https://blog.csdn.net/weixin_42994525/article/details/82622405
3. 电位器控制伺服电机的硬件链接与教学视频(外网英文版):
4. 比较详细的蓝牙AT模式配置教程:
5. HC-05硬件初始设置与常见问题解析:(区分了不同种类的HC-05的使用方法)