概述 Qt中是有蓝牙模块的,直接用此模块开发就行。但是注意使用的是低功耗蓝牙的类,连接方式和经典蓝牙会有区别
大致的连接步骤是:
界面设计
- 搜索附近的蓝牙设备
- 连接指定的蓝牙设备
- 获取服务
- 指定服务进行连接(因为每一种下的特征对象的权限是不一样的,有的只有读取权限,没有写权限,有的则相反,必要时可以直接打印一下查看)
- 获取服务下可用的特征对象
- 监听特征对象的消息变化和向特征对象发送消息
文章图片
文章图片
文章图片
代码设计
主界面的.cpp和.h
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QBluetoothLocalDevice"MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//连接设备按钮点击事件
this->btConnect = new BluetoothConnect();
connect(ui->btnConnectDevice,&QPushButton::clicked,[=](){
//this->hide();
btConnect->show();
});
//监听连接设备窗口发送的连接服务信号
connect(btConnect,&BluetoothConnect::toConectCharacteristic,this,&MainWindow::ConnectCharacteristic);
//数据发送按钮点击事件
connect(ui->btnSend,&QPushButton::clicked,[=](){
//发送数据
btConnect->m_service->writeCharacteristic(btConnect->m_characteristic,ui->leSendData->text().toUtf8(),QLowEnergyService::WriteMode::WriteWithoutResponse);
});
//关闭数据接收按钮点击事件
connect(ui->btnClose,&QPushButton::clicked,[=](){
if(this->isClose)
{
ui->btnClose->setText("开启");
this->isClose = false;
}
else
{
ui->btnClose->setText("关闭");
this->isClose = true;
}
});
//清除数据接受区内容按钮点击事件
connect(ui->btnClear,&QPushButton::clicked,[=](){
ui->tbRevData->clear();
});
}void MainWindow::ConnectCharacteristic(QLowEnergyService * m_service)
{
// 通过监听特征对象的变化
//写的和读取到的都会进入到这个位置
connect(m_service,&QLowEnergyService::characteristicChanged,[=](QLowEnergyCharacteristic c,QByteArray value) {
//qDebug() << "characteristicChanged state change::";
//qDebug() << "value length::" << value.length();
//qDebug() << "value length::" << value;
if(this->isClose)
{
ui->tbRevData->append(value);
}
});
//没有写响应属性的Characteristic不会进入这个连接
//connect(m_service,&QLowEnergyService::characteristicWritten,[=](QLowEnergyCharacteristic c,QByteArray value) {
qDebug() << "characteristicChanged state change::";
qDebug() << "value length::" << value.length();
qDebug() << "value length::" << value;
//});
//service错误监听
connect(m_service,&QLowEnergyService::errorOccurred,[=](QLowEnergyService::ServiceError newErrorr){
if(QLowEnergyService::NoError == newErrorr)
{
qDebug() <<"没有发生错误。";
}
if(QLowEnergyService::OperationError==newErrorr)
{
qDebug() <<"错误: 当服务没有准备好时尝试进行操作!";
}
if(QLowEnergyService::CharacteristicReadError==newErrorr)
{
qDebug() <<"尝试读取特征值失败!";
}
if(QLowEnergyService::CharacteristicWriteError==newErrorr)
{
qDebug() <<"尝试为特性写入新值失败!";
}
if(QLowEnergyService::DescriptorReadError==newErrorr)
{
qDebug() <<"尝试读取描述符值失败!";
}
if(QLowEnergyService::DescriptorWriteError==newErrorr)
{
qDebug() <<" 尝试向描述符写入新值失败!";
}
if(QLowEnergyService::UnknownError==newErrorr)
{
qDebug() <<"与服务交互时发生未知错误!";
}});
}MainWindow::~MainWindow()
{
delete ui;
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include
#include "bluetoothconnect.h"QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{
Q_OBJECTpublic:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
BluetoothConnect *btConnect;
bool isClose = true;
void ConnectCharacteristic(QLowEnergyService * m_service);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
连接界面的.cpp和.h
#include "bluetoothconnect.h"
#include "ui_bluetoothconnect.h"BluetoothConnect::BluetoothConnect(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::BluetoothConnect)
{
ui->setupUi(this);
//设置设备列表的标题
QListWidgetItem *item = new QListWidgetItem();
//创建自定义的窗口 然后放入到listwidget中
BtDevCell *bdc = new BtDevCell();
//设置item的高
item->setSizeHint(QSize(ui->lwShow->width(),bdc->height()));
//设置label的显示
bdc->btName->setText("名称");
bdc->btAddr->setText("地址");
bdc->btRssi->setText("信号强度");
//把item加入到listwidget
ui->lwShow->addItem(item);
//设置item的窗口为自定义的窗口
ui->lwShow->setItemWidget(item,bdc);
//设置服务列表的标题
QListWidgetItem *items = new QListWidgetItem();
//创建自定义的窗口 然后放入到listwidget中
BtDevCell *bdcs = new BtDevCell();
//把item加入到listwidget
items->setSizeHint(QSize(ui->lwService->width(),bdcs->height()));
//设置label的显示
bdcs->btName->setText("空");
bdcs->btAddr->setText("服务Uuid");
bdcs->btRssi->setText("空");
//设置item的窗口为自定义的窗口
ui->lwService->addItem(items);
//设置item的窗口为自定义的窗口
ui->lwService->setItemWidget(items,bdcs);
//创建通信的socket 普通蓝牙使用
//QBluetoothSocket *btSocket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol,this);
//创建设备发现对象
QBluetoothDeviceDiscoveryAgent *discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
//点击搜索设备后开始搜索设备
connect(ui->btnSerachDevice,&QPushButton::clicked,[=](){
qDebug() << "开始搜索设备";
//如果已经搜索过一次了,那么设计列表可能就大于1,那么就清空设备列表
//但是标题也会被清除,所以重新构建
if(ui->lwShow->count()>1)
{
ui->lwShow->clear();
//设置设备列表的标题
QListWidgetItem *item = new QListWidgetItem();
//创建自定义的窗口 然后放入到listwidget中
BtDevCell *bdc = new BtDevCell();
//设置item的高
item->setSizeHint(QSize(ui->lwShow->width(),bdc->height()));
//设置label的显示
bdc->btName->setText("名称");
bdc->btAddr->setText("地址");
bdc->btRssi->setText("信号强度");
//把item加入到listwidget
ui->lwShow->addItem(item);
//设置item的窗口为自定义的窗口
ui->lwShow->setItemWidget(item,bdc);
}//开始搜索设备
discoveryAgent->start();
});
//搜索到设备后进入
connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::deviceDiscovered,[=](QBluetoothDeviceInfo devInfo){
qDebug() << "搜索到设备";
//名称不为空且是低功耗蓝牙
if(devInfo.name() != "" && (devInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration))
{
QListWidgetItem *item = new QListWidgetItem();
BtDevCell *bdc = new BtDevCell();
item->setSizeHint(QSize(ui->lwShow->width(),bdc->height()));
bdc->btName->setText(devInfo.name());
bdc->btAddr->setText(devInfo.address().toString());
bdc->btRssi->setText(QString::number(devInfo.rssi()));
ui->lwShow->addItem(item);
ui->lwShow->setItemWidget(item,bdc);
devInfos.append(devInfo);
}
});
//搜索设备发生错误
connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::errorOccurred,[=](QBluetoothDeviceDiscoveryAgent::Error error){
qDebug() << error;
//警告对话框
QMessageBox::warning(this,"警告","搜索蓝牙设备发生错误,请检查蓝牙是否开启!");
});
//搜索设备完成
connect(discoveryAgent,&QBluetoothDeviceDiscoveryAgent::finished,[=](){
qDebug() << "搜索完成";
});
//设备列表被点击事件
connect(ui->lwShow,&QListWidget::itemClicked,[=](QListWidgetItem *item){
//这是经典蓝牙的连接方式
//QWidget *widget = ui->lwShow->itemWidget(item);
//BtDevCell *wbdc = (BtDevCell *)widget;
//qDebug() << wbdc->btAddr->text().toUtf8().data();
//btSocket->connectToService(QBluetoothAddress(wbdc->btAddr->text().toUtf8().data()),QBluetoothUuid("00001101-0000-1000-8000-00805F9B34FB"),QIODevice::ReadWrite);
//这是低功耗蓝牙的连接方式
//qDebug() << ui->lwShow->currentRow();
//创建蓝牙控制器
QLowEnergyController *lowBtControl = QLowEnergyController::createCentral(this->devInfos.at(ui->lwShow->currentRow()-1));
//连接设备
lowBtControl->connectToDevice();
//连接成功后进入
connect(lowBtControl,&QLowEnergyController::connected,[=](){
qDebug() << "连接成功";
//搜索服务
lowBtControl->discoverServices();
});
//连接失败后进入
connect(lowBtControl,&QLowEnergyController::errorOccurred,[=](QLowEnergyController::Error newError){
qDebug() << newError;
});
//搜索到服务后进入
connect(lowBtControl,&QLowEnergyController::serviceDiscovered, [=](QBluetoothUuid serviceUuid) {
qDebug() << "发现服务";
QListWidgetItem *item = new QListWidgetItem();
BtDevCell *bdc = new BtDevCell();
item->setSizeHint(QSize(ui->lwService->width(),bdc->height()));
bdc->btName->setText("");
bdc->btAddr->setText(serviceUuid.toString());
bdc->btRssi->setText("");
ui->lwService->addItem(item);
ui->lwService->setItemWidget(item,bdc);
btUuids.append(serviceUuid);
});
//服务uuid列表被点击事件
connect(ui->lwService,&QListWidget::itemClicked,[=](){
QBluetoothUuid serviceUuid = btUuids.at(ui->lwService->currentRow()-1);
//创建服务
this->m_service = lowBtControl->createServiceObject(QBluetoothUuid(serviceUuid),this);
if(m_service==NULL)
{
qDebug() << "服务建立失败!";
}
else
{
qDebug() << "服务建立成功!";
// 服务对象创建成功后,坚挺服务状态变化,如果状态变成已发现,则进行后续服务下特征对象获取
connect(m_service,&QLowEnergyService::stateChanged, this, [this]() {
//qDebug() << "service state change" << m_service->state();
//发现服务, 建立characteristic对象实例
if(m_service->state() == QLowEnergyService::ServiceDiscovered) {//获取特征对象
QList list=m_service->characteristics();
for(int i=0;
im_characteristic = list.at(i);
//qDebug() << c.properties();
/*如果QLowEnergyCharacteristic对象有效,则返回true,否则返回false*/
if(m_characteristic.isValid())
{
//描述符定义特征如何由特定客户端配置。
QLowEnergyDescriptor m_notificationDesc = m_characteristic.descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration);
if(m_notificationDesc.isValid())
{
//写描述符
m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
//m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("FEE1"));
}
}
}
}
});
//通知主窗口可以连接service了
emit toConectCharacteristic(m_service);
// 触发服务详情发现函数 ,不要忘记调用
m_service->discoverDetails();
}
});
});
////普通蓝牙使用
//connect(btSocket,&QBluetoothSocket::connected,[=](){
//qDebug() << "连接完成";
//});
//connect(btSocket,&QBluetoothSocket::errorOccurred,[=](QBluetoothSocket::SocketError error){
//qDebug() << "连接失败:" <
#ifndef BLUETOOTHCONNECT_H
#define BLUETOOTHCONNECT_H#include
#include "QLowEnergyController"
#include "QBluetoothLocalDevice"
#include "QBluetoothDeviceDiscoveryAgent"
#include "QBluetoothSocket"
#include "QDebug"
#include "QListWidgetItem"
#include "btdevcell.h"
#include "QLabel"
#include "QMessageBox"
#include "QLowEnergyDescriptor"
#include "QLowEnergyService"
#include "QBluetoothUuid"
#include "QTimer"namespace Ui {
class BluetoothConnect;
}class BluetoothConnect : public QMainWindow
{
Q_OBJECTpublic:
explicit BluetoothConnect(QWidget *parent = nullptr);
~BluetoothConnect();
QList devInfos;
QList btUuids;
QLowEnergyService * m_service;
QLowEnergyCharacteristic m_characteristic;
void searchCharacteristic();
private:
Ui::BluetoothConnect *ui;
signals:
void toConectCharacteristic(QLowEnergyService * m_service);
};
#endif // BLUETOOTHCONNECT_H
listWidget Item界面.cpp和.h
#include "btdevcell.h"
#include "ui_btdevcell.h"BtDevCell::BtDevCell(QWidget *parent) :
QWidget(parent),
ui(new Ui::BtDevCell)
{
ui->setupUi(this);
this->btName = ui->btName;
this->btAddr = ui->btAddr;
this->btRssi = ui->btRssi;
}BtDevCell::~BtDevCell()
{
delete ui;
}
#ifndef BTDEVCELL_H
#define BTDEVCELL_H#include
#include "QLabel"namespace Ui {
class BtDevCell;
}class BtDevCell : public QWidget
{
Q_OBJECTpublic:
explicit BtDevCell(QWidget *parent = nullptr);
~BtDevCell();
QLabel *btName;
QLabel *btAddr;
QLabel *btRssi;
private:
Ui::BtDevCell *ui;
};
#endif // BTDEVCELL_H
运行演示
文章图片
文章图片
【Qt学习|Qt开发简易蓝牙调试助手(低功耗蓝牙)】
推荐阅读
- Qt学习|Qt用MQTT协议连接阿里云
- Qt学习|Qt学习笔记——绘图设备
- #|蓝桥杯国赛之PWM互补输出
- #|蓝桥杯国赛之温度传感器
- 嵌入式|STM32的USART串口通讯~使用HAL库(查询方式)
- stm32项目|基于STM32智能循迹送货小车(一)项目介绍及硬件部分
- 单元测试|Java 单元测试指北
- Node百科|06.V8 JavaScript 引擎
- CocosCreator|cocoscreator常用代码抄录