QT开发低功耗蓝牙BLE连接ECB02模块进行数据收发

时间记录:2024/1/22

一、注意点

(1)pro文件中引入bluetooth模块
(2)安卓端运行时需要同步打开定位功能才能扫描到蓝牙设备
(3)mingw套件不能在Windows上运行,需要使用MSVC套件编译才能在Windows上运行

二、使用步骤

(1)设备蓝牙操作类QBluetoothLocalDevice
    2.1.1 hostMode方法获取蓝牙打开状态
    2.1.2 powerOn方法打开蓝牙
    2.1.3 setHostMode方法关闭蓝牙
(2)蓝牙设备搜索类QBluetoothDeviceDiscoveryAgent
    2.2.1 setLowEnergyDiscoveryTimeout方法设置扫描超时时间,如果设置为0,则一直进行扫描
    2.2.2 为QBluetoothDeviceDiscoveryAgent对象的deviceDiscovered信号绑定槽,每发现一台蓝牙设备便会触发一次此信号,携带参数QBluetoothDeviceInfo,每台蓝牙设备的信息类
    2.2.3 使用start方法,开始搜索蓝牙设备,参数可以传递QBluetoothDeviceDiscoveryAgent::LowEnergyMethod表示搜索低功耗蓝牙设备
(3)低功耗蓝牙控制器类QLowEnergyController
    2.3.1 使用静态方法createCentral创建蓝牙控制器对象,参数为QBluetoothDeviceInfo对象
    2.3.2 为serviceDiscovered信号绑定槽,每发现一个服务触发一次此信号,携带参数QBluetoothUuid
    2.3.3 为connected信号绑定槽,用于判断是否已成功连接到蓝牙
    2.3.4 使用connectToDevice方法连接蓝牙
    2.3.5 使用disconnectFromDevice方法来断开连接
    2.3.6 连接成功后调用discoverServices方法获取连接蓝牙下的所有服务
(4)低功耗蓝牙服务类QLowEnergyService
    2.4.1 使用QLowEnergyController对象的createServiceObject方法创建QLowEnergyService对象
    2.4.2 为stateChanged信号绑定槽,监听服务状态
    2.4.3 为characteristicChanged信号绑定槽,收到信息时会触发此信号,信息为携带的参数newValue
    2.4.4 为descriptorWritten信号绑定槽,监听描述符是否成功写入
    2.4.5 使用discoverDetails方法获取服务详情
    2.4.6 服务状态改变以后写入描述符激活notify,否则无法收到消息,使用characteristics方法获取服务下所有的特征对象
(5)低功耗蓝牙特征值类QLowEnergyCharacteristic
    2.5.1 遍历特征值对象列表,使用isValid方法判断是否可用
    2.5.2 使用descriptor方法创建描述符对象,参数传递QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration,表示描述符类型由客户端特征值自行配置
(6)低功耗蓝牙描述符对象QLowEnergyDescriptor
    2.6.1 使用isValid方法判断描述符对象是否有效
    2.6.2 使用QLowEnergyService类的writeDescriptor方法向蓝牙写入描述符,激活notify,参数第一个为描述符对象,第二个为QByteArray::fromHex(“0100”)
(7)使用QLowEnergyService类的writeCharacteristic方法写入数据

三、参考代码

(1)头文件

#ifndef MWIDGET_H
#define MWIDGET_H

#include 
#include  //蓝牙设备搜索对象
#include  //本机蓝牙操作
#include 
#include 
#include 
#include  //蓝牙控制器对象
#include 
#include 
#include 
#include 

//static const QLatin1String serviceUUID("0000FFF0-0000-1000-8000-00805F9B34FB");
//static const QLatin1String readUUID("0000FFF1-0000-1000-8000-00805F9B34FB");
//static const QLatin1String writeUUID("0000FFF2-0000-1000-8000-00805F9B34FB");

QT_BEGIN_NAMESPACE
namespace Ui { class MWidget; }
QT_END_NAMESPACE

class MWidget : public QWidget
{
    Q_OBJECT

public:
    MWidget(QWidget *parent = nullptr);
    ~MWidget();

private:
    Ui::MWidget *ui;
    QBluetoothDeviceDiscoveryAgent *deviceDiscoveryAgent;
    QBluetoothLocalDevice *localDevice;
    QList<QBluetoothDeviceInfo> *deviceInfoList;
    QList<QBluetoothUuid> uuidList;
    QLowEnergyController *control;
    QLowEnergyService *mService;
    QLowEnergyCharacteristic mCharacter;
    QList<QLowEnergyCharacteristic> charList;

private slots:
    void mDeviceDiscovered(QBluetoothDeviceInfo deviceInfo);
    void on_openLocalDeviceBtn_clicked();
    void on_closeLocalDeviceBtn_clicked();
    void on_searchBtn_clicked();
    void on_listWidget_itemDoubleClicked(QListWidgetItem *item);
    void mServiceDiscovered(QBluetoothUuid serviceUuid);
    void mConnected();
    void on_uuidListWidget_itemDoubleClicked(QListWidgetItem *item);
    void mStateChanged(QLowEnergyService::ServiceState newState);
    void mCharacteristicChanged(QLowEnergyCharacteristic characteristic,QByteArray newValue);
    void mDescriptorWritten(QLowEnergyDescriptor descriptor,QByteArray newValue);
    void on_pushButton_clicked();
};
#endif // MWIDGET_H

(2)源文件

#include "mwidget.h"
#include "ui_mwidget.h"
#include 

MWidget::MWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MWidget)
{
    ui->setupUi(this);
    this->setLayout(ui->verticalLayout_2);

    //创建对象
    deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
    localDevice = new QBluetoothLocalDevice(this);
    deviceInfoList = new QList<QBluetoothDeviceInfo>();

    deviceDiscoveryAgent->setLowEnergyDiscoveryTimeout(5000);

    //连接槽
    connect(deviceDiscoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo))
            ,this,SLOT(mDeviceDiscovered(QBluetoothDeviceInfo)));
}

MWidget::~MWidget()
{
    delete ui;
}

//蓝牙设备发现槽
void MWidget::mDeviceDiscovered(QBluetoothDeviceInfo deviceInfo)
{
    //如果名称不为空切为低功耗蓝牙
    if(deviceInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration){
        QString label = QString("%1 %2").arg(deviceInfo.name()).arg(deviceInfo.address().toString());
        ui->listWidget->addItem(label);
        deviceInfoList->append(deviceInfo);
    }
}

//打开本地蓝牙
void MWidget::on_openLocalDeviceBtn_clicked()
{
    if(localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff){
        localDevice->powerOn();
    }
}

//关闭本地蓝牙
void MWidget::on_closeLocalDeviceBtn_clicked()
{
    localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);
}

void MWidget::on_searchBtn_clicked()
{
    ui->listWidget->clear();
    deviceInfoList->clear();
    deviceDiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
}

//双击连接设备
void MWidget::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{
    deviceDiscoveryAgent->stop();
    Q_UNUSED(item);
    uuidList.clear();
    //创建蓝牙控制器对象
    control = QLowEnergyController::createCentral(deviceInfoList->at(ui->listWidget->currentRow()));
    connect(control,SIGNAL(serviceDiscovered(QBluetoothUuid))
            ,this,SLOT(mServiceDiscovered(QBluetoothUuid)));
    connect(control,SIGNAL(connected())
            ,this,SLOT(mConnected()));
    control->connectToDevice();
}

//发现服务uuid
void MWidget::mServiceDiscovered(QBluetoothUuid serviceUuid)
{
    QString label = QString("%1").arg(serviceUuid.toString());
    ui->uuidListWidget->addItem(label);
    uuidList.append(serviceUuid);
}

//成功连接到设备
void MWidget::mConnected()
{
    ui->textBrowser->append("成功连接"+deviceInfoList->at(ui->listWidget->currentRow()).name());
    //搜索服务
    uuidList.clear();
    control->discoverServices();
}

//双击创建服务UUID,写描述符,建立通讯
void MWidget::on_uuidListWidget_itemDoubleClicked(QListWidgetItem *item)
{
    Q_UNUSED(item);
    //创建服务
    mService = control->createServiceObject(uuidList.at(ui->uuidListWidget->currentRow()),this);
    if(mService == NULL){
        ui->textBrowser->append("创建服务失败");
    }else{
        ui->textBrowser->append("服务创建成功");
        ui->comboBox->clear();
        //监听服务状态变化
        connect(mService,SIGNAL(stateChanged(QLowEnergyService::ServiceState))
                ,this,SLOT(mStateChanged(QLowEnergyService::ServiceState)));
        //服务的characteristic变化,有数据传来
        connect(mService,SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray))
                ,this,SLOT(mCharacteristicChanged(QLowEnergyCharacteristic,QByteArray)));
        //描述符成功被写
        connect(mService,SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByteArray))
                ,this,SLOT(mDescriptorWritten(QLowEnergyDescriptor,QByteArray)));
        //服务详情发现函数
        mService->discoverDetails();
    }
}

//服务状态改变
void MWidget::mStateChanged(QLowEnergyService::ServiceState newState)
{
    Q_UNUSED(newState);
    //发现服务
    if(mService->state() == QLowEnergyService::ServiceDiscovered){
        charList = mService->characteristics();
        for(int i=0;i<charList.size();i++){
            mCharacter = charList.at(i);
            if(mCharacter.isValid()){
                ui->comboBox->addItem(mCharacter.uuid().toString());
                QLowEnergyDescriptor descriptor = mCharacter.descriptor(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration);
                if(descriptor.isValid()){
                    mService->writeDescriptor(descriptor,QByteArray::fromHex("0100"));
                }
            }
        }
    }
}

//characteristic变化,数据传来
void MWidget::mCharacteristicChanged(QLowEnergyCharacteristic characteristic, QByteArray newValue)
{
    ui->textBrowser->append("接收值成功");
    Q_UNUSED(characteristic);
    QTextCodec *code = QTextCodec::codecForName("GBK");
    QString str = code->toUnicode(newValue);
    ui->textBrowser->append(str.toUtf8());
}

//描述符成功被写
void MWidget::mDescriptorWritten(QLowEnergyDescriptor descriptor, QByteArray newValue)
{
    ui->textBrowser->append(descriptor.uuid().toString()+":"+newValue);
    ui->textBrowser->append("描述符写入成功");
}

void MWidget::on_pushButton_clicked()
{
    QString text = ui->lineEdit->text();
    QTextCodec *code = QTextCodec::codecForName("GBK");
    QString str = code->toUnicode(text.toUtf8());
    mService->writeCharacteristic(charList.at(0),str.toUtf8());
}

四、与ECB02模块通信效果

(1)连接效果
QT开发低功耗蓝牙BLE连接ECB02模块进行数据收发_第1张图片
(2)写描述符,激活notify效果
QT开发低功耗蓝牙BLE连接ECB02模块进行数据收发_第2张图片

你可能感兴趣的:(QT,qt,c++,低功耗蓝牙)