qt ble蓝牙central驱动

此处分享一个ble蓝牙central驱动,此处lambda表达式利用比较多

 

toolbluetooth.h

#ifndef TOOLBLUETOOTH_H
#define TOOLBLUETOOTH_H

#include <QObject>

#include<QBluetoothDeviceDiscoveryAgent>
#include<QBluetoothDeviceInfo>
#include<QBluetoothUuid>
#include<QBluetoothServiceInfo>
#include<QLowEnergyController>
#include<QLowEnergyService>
#include<QLowEnergyDescriptor>

class ToolBluetooth : public QObject
{
    Q_OBJECT
public:
    explicit ToolBluetooth(QObject *parent = nullptr);
    ~ToolBluetooth();

    void init(QString number);//初始化链接等
    void send(QByteArray msg);//发送数据

signals:
    void sigReceived(QByteArray &msg);//接受数据
    void sigDeviceState(QString &msg);//当前设备状态

private slots:
    //void test();

private:

    QString number="";//记录当前表号
    QByteArray repeatmsg;//如果数据完全一样,则抛弃这个数据
    bool sendflag = true;//发送信号按钮,这个属于特殊案例

    QList<QBluetoothDeviceInfo> device_list;  //存放搜索到到蓝牙设备列表
    QBluetoothDeviceDiscoveryAgent *m_deviceDiscoveryAgent = nullptr;  //设备搜索对象
    QLowEnergyController *m_controler = nullptr;   //单个蓝牙设备控制器
    QLowEnergyService *m_service = nullptr; //服务对象实例
    QLowEnergyCharacteristic c;

};

#endif // TOOLBLUETOOTH_H

 

toolbluetooth.cpp

#include "toolbluetooth.h"


#include <QDebug>

#include "lib/mylib.h"

//extern void StringToHex(char *str, u8 *hex, u16 strLen);

ToolBluetooth::ToolBluetooth(QObject *parent) : QObject(parent)
{



}

ToolBluetooth::~ToolBluetooth()
{
    m_deviceDiscoveryAgent->deleteLater();m_deviceDiscoveryAgent = nullptr;
    m_controler->deleteLater();m_controler = nullptr;
    m_service->deleteLater();m_service = nullptr;
}

//初始化链接
void ToolBluetooth::init(QString num)
{
    number = num;


    m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
    m_deviceDiscoveryAgent->setLowEnergyDiscoveryTimeout(5000);

    //如果某些时间断开链接了,程序必须重新加载,之前建立的链接都失效,需要清空//主要是两个
    if(m_controler != nullptr) m_controler->deleteLater();
    if(m_service != nullptr) m_service->deleteLater();

    //每次发现新设备时触发
    connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this ,[this]() { qDebug() << "find a new bluebooth device";});

    //蓝牙设备搜索完成后,筛选出目标设备进行连接,并进行相关信号与槽函数的绑定
    connect(m_deviceDiscoveryAgent,&QBluetoothDeviceDiscoveryAgent::finished, this, [this]() {
        device_list = this->m_deviceDiscoveryAgent->discoveredDevices();

        //遍历显示设备详情
        QList<QBluetoothDeviceInfo>::iterator it;
        for(it=device_list.begin(); it != device_list.end(); it++) {

            // 外围蓝牙设备对象
            QBluetoothDeviceInfo tmp_device = *it;
            QString device_name = tmp_device.name();
            qDebug() <<"device name:::" << device_name;

           //if(!device_name.contains("onor")){continue;}
           if(!device_name.contains(number==""?"zenner":number)){continue;}//防止某些人就是不传表号,给他一个头疼的数据让他头疼去吧
            qDebug() <<"find task device-----------------------" << device_name;

            m_controler = QLowEnergyController::createCentral(tmp_device);
            m_controler->connectToDevice();

            // 监听目标设备连接成功消息,连接成功后,搜索目标设备等服务列表
            connect(m_controler, &QLowEnergyController::connected, this, [this](){
                qDebug() << "m_controler connected ......";
                //必须要在连接建立后 执行开始寻找service的函数
                //之前调试,就是因为没有在设备连接后主动请求获取服务列表信息,后续监听便没有触发
                m_controler->discoverServices();
            });

            // 监听发现服务消息,如果服务的uuid 为约定好的要使用服务类型,则进行后续处理
            connect(m_controler,&QLowEnergyController::serviceDiscovered, this, [this](QBluetoothUuid serviceUuid) {
                if(serviceUuid == QBluetoothUuid( quint16(0xff00))) {  //我们用的服务类型是0xffd0对应的uuid

                    //发现匹配的服务后,使用控制器对象创建服务对象
                    m_service = m_controler->createServiceObject(serviceUuid,this);
                    if(m_service) {

                        // 服务对象创建成功后,坚挺服务状态变化,如果状态变成已发现,则进行后续服务下特征对象获取
                        connect(m_service,&QLowEnergyService::stateChanged, this, [this]() {
                            qDebug() << "service state change" << m_service->state() << ",||||||";

                            //发现服务, 建立characteristic对象实例
                            if(m_service->state() == QLowEnergyService::ServiceDiscovered) {
                                QLowEnergyCharacteristic hrChar = m_service->characteristic(QBluetoothUuid(quint16(0xff10)));
                                if(!hrChar.isValid()) {
                                    qDebug() << "characteristic fff6 error:::";
                                }
                                else
                                {
                                    qDebug() << "characteristic fff0 finished:::uuid"<<hrChar.uuid()<<", value"<<hrChar.value();
                                    //到达此处说明已经成功建立链接
                                    c = hrChar;
                                    QString temstr = "device state: connected...";
                                    emit sigDeviceState(temstr);
                                    m_service->writeCharacteristic(hrChar,QString("\ncentral connect test!!!\n").toLatin1());
                                }

                                // 设置特征对象可用
                                //enable the chracteristic notification by write 0x01 to client characteristic configuration
                                QLowEnergyDescriptor m_notificationDesc = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
                                qDebug() << "m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex:::";
                                m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));

                            }
                        });


                        // 通过监听特征对象的变化,不断获得鞋垫压力数据。
                        connect(m_service,&QLowEnergyService::stateChanged, this,
                                [this](QLowEnergyService::ServiceState newState) {
                                    qDebug() << "central QLowEnergyService::stateChanged change::::::::::::::::::::::::::::::::::::::::"<<newState;
                                    //QString temstr = QString(value);emit sigReceived(temstr);
                                });
                        // 通过监听特征对象的变化,不断获得鞋垫压力数据。
                        connect(m_service,&QLowEnergyService::characteristicRead, this,[this]() {
                                    qDebug() << "central QLowEnergyService::characteristicRead change::::::::::::::::::::::::::::::::::::::::";
                                    //QString temstr = QString(value);emit sigReceived(temstr);
                                });
                        // 通过监听特征对象的变化,不断获得鞋垫压力数据。
                        connect(m_service,&QLowEnergyService::characteristicWritten, this,[this]() {
                                    qDebug() << "central QLowEnergyService::characteristicWritten change::::::::::::::::::::::::::::::::::::::::";
                                    //QString temstr = QString(value);emit sigReceived(temstr);
                                });
                        // 通过监听特征对象的变化,不断获得鞋垫压力数据。
                        connect(m_service,&QLowEnergyService::descriptorRead, this,[this]() {
                                    qDebug() << "central QLowEnergyService::descriptorRead change::::::::::::::::::::::::::::::::::::::::";
                                    //QString temstr = QString(value);emit sigReceived(temstr);
                                });
                        connect(m_service,&QLowEnergyService::descriptorWritten, this,[this]() {
                                    qDebug() << "central QLowEnergyService::descriptorWritten change::::::::::::::::::::::::::::::::::::::::";
                                    //QString temstr = QString(value);emit sigReceived(temstr);
                                });
//                        QObject::connect(m_service,&QLowEnergyService::error, this,[=](QLowEnergyService::ServiceError error) {
//                                    qDebug() << "central QLowEnergyService::characteristicWritten change::::::::::::::::::::::::::::::::::::::::";
//                                    //QString temstr = QString(value);emit sigReceived(temstr);
//                                });


                        connect(m_service,&QLowEnergyService::characteristicChanged, this,
                                [this](QLowEnergyCharacteristic c,QByteArray value) {
                                    qDebug() << "characteristicChanged central characteristicChanged state change::" <<c.uuid()<< ",||||||";
                                    qDebug() << "characteristicChanged central value length::" << value.length();
                                    qDebug() << "characteristicChanged central value length::" << value;
                                    //QString temstr = QString(value);emit sigReceived(temstr);

                                    //if(sendflag){emit sigReceived(value);}sendflag = !sendflag;//隔一个
                                    emit sigReceived(value);
                                    //if(sendflag==true)sendflag=false;if(sendflag==false)sendflag=true;
                                }
                        );




                        // 触发服务详情发现函数 ,不要忘记调用
                        m_service->discoverDetails();
                    }
                }
            });

            connect(m_controler,&QLowEnergyController::discoveryFinished, this, [this]() {
                qDebug() << "finish service discovery";
            });

            connect(m_controler,&QLowEnergyController::disconnected,this,[this](){
                  qDebug()<<"QLowEnergyController::disconnected------------------------------------"<<endl;
                  QString temstr = QString("device state: disconnected...");emit sigDeviceState(temstr);
            });

            connect(m_controler, QOverload<QLowEnergyController::Error>::of(&QLowEnergyController::error),
                  [=](QLowEnergyController::Error newError){
                qDebug()<<"QLowEnergyController::Error--------------------"+newError<<endl;
                //QString temstr = QString("device state: disconnected...");emit sigDeviceState(temstr);
            });

            connect(m_controler, QOverload<QLowEnergyController::ControllerState>::of(&QLowEnergyController::stateChanged),
                  [=](QLowEnergyController::ControllerState state){
                qDebug()<<"QLowEnergyController::ControllerState--------------------"+QString(state)<<endl;
                //QString temstr = QString("device state: disconnected...");emit sigDeviceState(temstr);
            });
//            connect(m_controler,&QLowEnergyController::connectionUpdated,this,[this](){
//                  qDebug()<<"QLowEnergyController::disconnected------------------------------------"<<endl;
//                  QString temstr = QString("device state: disconnected...");emit sigDeviceState(temstr);
//            });





            //QTimer *timer = new QTimer(this);
            //connect(timer, &QTimer::timeout, this, [this](){ qDebug() <<"state:::" <<  this->m_controler->state();});
            //timer->start(1000);
        }
    });


    // 开始外围设备搜索pip install https://pypi.douban.com/simple/ django
    m_deviceDiscoveryAgent->start();
}



//发送数据
void ToolBluetooth::send(QByteArray msg)
{
//    QByteArray byte;
//    byte = QByteArray(msg);//这种方式遇到00自动停止解析=_=//还崩溃
//    qDebug()<<"toolbluetooth.cpp: "+QString(byte.toHex())<<endl;

//  //因为writeCharacteristic使用QByteArray传递数据//遇到00自动停止发送,因此换一个发送方式
    //把数据拆开,用ascii发送,eg:0x68拆解为6和8

//    //这种方式程序崩溃//原因之一是未申请空间
//    int len = strlen(msg);
//    char *str = new char(len*2);
//    for (int i = 0; i < len; i++)
//    {
//        int temp = msg[i] / 16;
//        if (temp <= 9)
//            str[2*i] = temp + '0';
//        else
//            str[2*i] = temp - 10 + 'a';

//        temp = msg[i] % 16;
//        if (temp <= 9)
//            str[2*i+1] = temp + '0';
//        else
//            str[2*i+1] = temp - 10 + 'a';

//    }
//    qDebug()<<"toolbluetooth.cpp: "+QString(str)<<endl;

//    QLowEnergyCharacteristic hrChar = m_service->characteristic(QBluetoothUuid(quint16(0xff10)));
//    if(!hrChar.isValid()) { qDebug() << "characteristic fff6 error:::";}else{m_service->writeCharacteristic(hrChar,msg);}

//    QLowEnergyDescriptor m_notificationDesc = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
//    m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));


//    m_service->writeCharacteristic(c,msg);
//    QLowEnergyDescriptor m_notificationDesc = c.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
//    m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));

    m_service->writeCharacteristic(c,msg,QLowEnergyService::WriteWithoutResponse);

}

 

 

注意:   QBluetoothUuid::ClientCharacteristicConfiguration  (+_+|)

 

posted @ 2020-12-02 19:14  小城熊儿  阅读(617)  评论(0编辑  收藏  举报