特此声明,本文所有内容是在参考以下链接的基础上整理并开发的,所有代码均验证无误。如果你想使用或者发表,请您声明出处。
一,实验目的。
本文使用两个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的RXDchar val; //存储接收的变量void setup() {Serial.begin(9600); //与电脑的串口连接,串口监视器波特率设置为9600Serial.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)
下文是我直接粘贴的台湾人的介绍,他的连接在本文末尾处贴上,有兴趣的同学可以去看一下
然后我们用同样的方法获得主站的地址::6:271123
在主站的AT模式下的串口监视器中输入指令:AT+BIND=,6,271130(主站绑上从站)
在从站的AT模式下的串口监视器中输入指令:AT+BIND=,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 pinconst 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);//StoppinMode(buttonPin1, INPUT);//GopinMode(buttonPin2, INPUT);//BackpinMode(buttonPin3, INPUT);//LeftpinMode(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);//给蓝牙串口输入0if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态val = BT.read();Serial.print(val);}} else if(buttonState1 == LOW){BT.print(1);//给蓝牙串口输入1if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态val = BT.read();Serial.print(val);}}else if(buttonState2 == LOW){BT.print(2);//给蓝牙串口输入2if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态val = BT.read();Serial.print(val);}} else if(buttonState3 == LOW){BT.print(3);//给蓝牙串口输入3if (BT.available()) {//如果读到从站的返回值,在串口监视器窗口输出小车运动状态val = BT.read();Serial.print(val);}}else if(buttonState4 == LOW){BT.print(4);//给蓝牙串口输入4if (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教程(本实验中没有用到,但是很有用,推荐给大家):
/qq_41381461/article/details/90047414
2. HC-05蓝牙AT模式配置步骤与代码意义:
/weixin_42994525/article/details/82622405
3. 电位器控制伺服电机的硬件链接与教学视频(外网英文版):
/tutorials/arduino/how-to-configure-pair-two-hc-05-bluetooth-module-master-slave-commands/
4. 比较详细的蓝牙AT模式配置教程:
.tw/?p=750
5. HC-05硬件初始设置与常见问题解析:(区分了不同种类的HC-05的使用方法)
/p/a1781b3d3e44?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
如果觉得《Arduino实现两个HC-05蓝牙模块控制蓝牙小车》对你有帮助,请点赞、收藏,并留下你的观点哦!