1、蓝牙模块在嵌入式设备上是通过串口连接,这样我们跟蓝牙进行交互是通过串口进行交互的。
2、蓝牙一般是两板,一般是主机和从机,每块板跟嵌入式核心板都是通过串口进行通信的。
3、蓝牙与蓝牙之间的通信方式这个我们不用管,我们只需要分别配置两块板,让主机能够扫描到从机。
4、蓝牙板跟嵌入式核心板它们之间的通信协议是AT指令集。
5、我们首先需要了解AT指令集,分别设置主机和从机。
6、然后通过AT指令获取从机的MAC地址,然后在主机上指定扫描从机的MAC地址。
7、扫描成功后会自动进行配对,配对后会自动进入透传模式。
8、什么是透传模式,蓝牙分为两种模式,分别是透传模式和AT模式,透传模式就是蓝牙与蓝牙之间需要进行通信时设置的。AT模式是设置蓝牙的一些功能的。
9、进入透传模式后,主机发送数据给从机,从机也可以发送数据给主机。发送数据完毕后,退出透传模式到AT模式,然后通过AT指令进行其它需要的操作。
主机协议解析代码 核心解析部分:
.h
#ifndef BLUETOOTHHANDLER_H
#define BLUETOOTHHANDLER_H
#include <QObject>
/* AT command Set*/
#define AT_BLEMODE_M "AT+BLEMODE=1\r\n" //设置蓝牙为主机
#define AT_RESTORE "AT+RESTORE\r\n" //恢复出厂设置指令
#define AT_BLENAME "AT+BLENAME=ai-think-s\r\n" //设置蓝牙模块名称
#define AT_BLEMAC "AT+BLEMAC=" //设置蓝牙模块MAC地址
#define AT_TRANSENTER "AT+TRANSENTER\r\n" //进入透传模式
#define AT_QUITTRANSENTER "+++" //退出透传模式
#define AT_BLEAUTH "AT+BLEAUTH=123456\r\n" //设置蓝牙模块配对码
#define AT_BLEADVEN "AT+BLEADVEN=1\r\n" //开启蓝牙广播(仅允许在蓝牙从机状态执行设置)
#define AT_BLEADVDATA "AT+BLEADVDATA=123456\r\n" //设置蓝牙广播数据
#define AT_BLEDISCONNECT "AT+BLEDISCON\r\n" //断开蓝牙连接
#define AT_BLEAUTOCON "AT+BLEAUTOCON=" //自动扫描连接
/* AT command query */
#define AT "AT\r\n" //测试指令,串口是否通着
#define AT_BLERFPWR_QUERY "AT+BLERFPWR?\r\n" //查询蓝牙发射功率
#define AT_BLESTATE_QUERY "AT+BLESTATE?\r\n" //查询蓝牙连接状态
#define AT_BLEUNLOCK "$USVBLEUNLOCK#" //开锁
#define AT_BLELOCK "$USVBLELOCK#" //上锁
#define AT_BLEUNLOCKRES "$USVBLEUNLOCKSUCCESS#" //开锁返回值
#define AT_BLELOCKRES "$USVBLELOCKSUCESS#" //上锁返回值
class BluetoothHandler : public QObject
{
Q_OBJECT
public:
explicit BluetoothHandler();
void connectBlueTooth();
void checkData(QByteArray& by, bool& hasReadHead);
void delay(int msec, QByteArray res);
signals:
void sig_Ok();
signals:
void signSend(const unsigned char* ch,int len,int retry = 3);
private:
QByteArray m_data;
QByteArray m_recvRes;
bool m_connectStatus = false;
};
#endif // BLUETOOTHHANDLER_H
.cpp
#include "bluetoothhandler.h"
#include <QEventLoop>
#include <QTimer>
#include <QDebug>
BluetoothHandler::BluetoothHandler()
{
}
void BluetoothHandler::delay(int msec,QByteArray res)
{
m_recvRes = res;
QEventLoop loop;
QTimer::singleShot(msec,&loop,SLOT(quit()));
connect(this,&BluetoothHandler::sig_Ok,&loop,&QEventLoop::quit);
loop.exec();
}
void BluetoothHandler::connectBlueTooth()
{
//退出透传模式
emit signSend((unsigned char*)AT_QUITTRANSENTER,strlen(AT_QUITTRANSENTER));
delay(1000,"OK");
m_data.clear();
//恢复出厂设置
emit signSend((unsigned char*)AT_RESTORE,strlen(AT_RESTORE));
delay(5000,"ready");
if (m_data.contains("++AT+RESTORE"))
{
m_data.clear();
//指令跟缓存中的数据拼接了,重发恢复出厂设置
emit signSend((unsigned char*)AT_RESTORE,strlen(AT_RESTORE));
delay(5000,"ready");
if (!m_data.contains("ready"))
{
connectBlueTooth();
return;
}
}
else
{
if (!m_data.contains("ready"))
{
connectBlueTooth();
return;
}
}
m_data.clear();
//设置主机模式
emit signSend((unsigned char*)AT_BLEMODE_M, strlen(AT_BLEMODE_M));
delay(5000,"ready");
if (!m_data.contains("ready"))
{
m_data.clear();
connectBlueTooth();
return;
}
m_data.clear();
//获取MAC地址
static QByteArray sss;
sss.clear();
sss.append(AT_BLEAUTOCON);
sss.append("94c960392537");
sss.append(",FALSE,0\r\n");
//自动扫描
const unsigned char* atcmd = (const unsigned char*)sss.data();
emit signSend(atcmd, sss.size());
delay(10000,"OK");
if (!m_data.contains("OK"))
{
connectBlueTooth();
m_data.clear();
return;
}
m_data.clear();
}
void BluetoothHandler::checkData(QByteArray &by, bool &hasReadHead)
{
qDebug()<<by;
if (by.contains(m_recvRes))
emit sig_Ok();
if (by.contains("EVENT:BLE_CONNECTED"))
{
qDebug()<<"bluetooth connect sucess";
m_connectStatus = true;
}
if (by.contains("EVENT:BLE_DISCONNECT"))
{
qDebug()<<"bluetooth disconnect sucess";
m_connectStatus = false;
}
m_data = by;
by.clear();
}