1.要使用qt蓝牙模块, 项目的 .pro要声明使用
2.有了lambda函数后,不用再一个个声明和创建具名槽函数的感觉挺好,就是代码成一坨了
3.虽然说是低功耗蓝牙,但还是要记得用完后断开和外设店连接,之前忘记断开,一晚上一个纽扣电池的点就被耗光了
4.GATT Profile 简介
- 搜寻附近全部的蓝牙设备
- 根据搜寻出的蓝牙设备信息,筛选出要连接的蓝牙设备进行连接
- 建立连接后,去获取该蓝牙设备等services列表,根据约定好的服务uuid筛选出自己需要的服务
- 发现对应的服务后,根据约定好的服务下characteristic特性id,创建特征对象,并监听特征对象内容的变化
- 向客户端特征配置对象写入特征生效消息,开始接收外围蓝牙设备。
bluedevice.h:
1 #ifndef BLUEDEVICE_H
2 #define BLUEDEVICE_H
3 #include <QObject>
4 #include<QBluetoothDeviceDiscoveryAgent>
5 #include<QBluetoothDeviceInfo>
6 #include<QBluetoothUuid>
7 #include<QBluetoothServiceInfo>
8 #include<QLowEnergyController>
9 #include<QLowEnergyService>
10 #include<QLowEnergyDescriptor>
11 class BlueDevice: public QObject{
12 Q_OBJECT
13 public:
14
15 BlueDevice();
16 QString getAddress(QBluetoothDeviceInfo device) const;
17 private:
18 QList<QBluetoothDeviceInfo> device_list; //存放搜索到到蓝牙设备列表
19 QBluetoothDeviceDiscoveryAgent *m_deviceDiscoveryAgent; //设备搜索对象
20 QLowEnergyController *m_controler; //单个蓝牙设备控制器
21 QLowEnergyService *m_service; //服务对象实例
22 };
23
24 #endif // BLUEDEVICE_H
bluedevice.cpp:
1 #include "bluedevice.h"
2 #include <QDebug>
3 #include<QTimer>
4
5 BlueDevice::BlueDevice() {
6 qDebug() << "enter bludedevice constructor....";
7
8 m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
9 m_deviceDiscoveryAgent->setLowEnergyDiscoveryTimeout(5000);
10
11 //每次发现新设备时触发
12 connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this ,[this]() {
13 qDebug() << "find a new bluebooth device";
14 });
15
16 //蓝牙设备搜索完成后,筛选出目标设备进行连接,并进行相关信号与槽函数的绑定
17 connect(m_deviceDiscoveryAgent,&QBluetoothDeviceDiscoveryAgent::finished, this, [this]() {
18 device_list = this->m_deviceDiscoveryAgent->discoveredDevices();
19
20 //遍历显示设备详情
21 QList<QBluetoothDeviceInfo>::iterator it;
22 for(it=device_list.begin(); it != device_list.end(); it++) {
23
24 // 外围蓝牙设备对象
25 QBluetoothDeviceInfo tmp_device = *it;
26 QString device_name = tmp_device.name();
27 //qDebug() <<"device name:::" << device_name;
28 //qDebug() << "device address:::" << this->getAddress(tmp_device);
29
30 //打印搜索出来的全部低功耗蓝牙
31 if (tmp_device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
32 qDebug() << " low Energy device ....";
33 qDebug() <<"22222device name:::" << device_name;
34 }
35
36 //正则匹配目标设备,
37 QString pattern_str = "^Eric.*"; //qt中正则匹配任意个字符,需要使用.*而不是*
38 QRegExp rx(pattern_str);
39 if(!rx.exactMatch(device_name)) {
40 continue;
41 }
42 qDebug() <<"device name:::" << device_name;
43 qDebug() << "device address:::" << this->getAddress(tmp_device);
44
45 // 创建蓝牙设备控制器对象
46 m_controler = new QLowEnergyController(tmp_device, this);
47
48 // 监听目标设备连接成功消息,连接成功后,搜索目标设备等服务列表
49 connect(m_controler, &QLowEnergyController::connected, this, [this](){
50 qDebug() << "m_controler connected ......";
51 //必须要在连接建立后 执行开始寻找service的函数
52 //之前调试,就是因为没有在设备连接后主动请求获取服务列表信息,后续监听便没有触发
53 m_controler->discoverServices();
54 });
55
56 // 监听发现服务消息,如果服务的uuid 为约定好的要使用服务类型,则进行后续处理
57 connect(m_controler,&QLowEnergyController::serviceDiscovered, this, [this](QBluetoothUuid serviceUuid) {
58 if(serviceUuid == QBluetoothUuid( quint16(0xffd0))) { //我们用的服务类型是0xffd0对应的uuid
59
60 //发现匹配的服务后,使用控制器对象创建服务对象
61 m_service = m_controler->createServiceObject(serviceUuid,this);
62 if(m_service) {
63
64 // 服务对象创建成功后,坚挺服务状态变化,如果状态变成已发现,则进行后续服务下特征对象获取
65 connect(m_service,&QLowEnergyService::stateChanged, this, [this]() {
66 qDebug() << "service state change" << m_service->state() << ",||||||";
67
68 //发现服务, 建立characteristic对象实例
69 if(m_service->state() == QLowEnergyService::ServiceDiscovered) {
70 QLowEnergyCharacteristic hrChar = m_service->characteristic(QBluetoothUuid(quint16(0xfff6)));
71 if(!hrChar.isValid()) {
72 qDebug() << "characteristic fff6 error:::";
73 }
74 // 设置特征对象可用
75 //enable the chracteristic notification by write 0x01 to client characteristic configuration
76 QLowEnergyDescriptor m_notificationDesc = hrChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
77 if (m_notificationDesc.isValid()) {
78 if(hrChar.properties() & QLowEnergyCharacteristic::Notify) {
79 qDebug() << "";
80 }
81 m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
82 }
83 }
84 });
85
86 // 通过监听特征对象的变化,不断获得鞋垫压力数据。
87 connect(m_service,&QLowEnergyService::characteristicChanged, this,
88 [this](QLowEnergyCharacteristic c,QByteArray value) {
89 qDebug() << "characteristicChanged state change::" <<c.uuid()<< ",||||||";
90 qDebug() << "value length::" << value.length();
91 qDebug() << "value length::" << value;
92
93 QByteArray sub_1 = value.mid(0,2);
94 QByteArray sub_2 = value.mid(2,2);
95 QByteArray sub_3 = value.mid(4,2);
96
97 bool ok;
98 // num 1,2,3 分别对应三个压力感应点的压力值
99 int num_1 = QString(sub_1.toHex()).toInt(&ok,16);
100 qDebug() << "num_1:::" << num_1;
101 int num_2 = QString(sub_2.toHex()).toInt(&ok,16);
102 qDebug() << "num_1:::" << num_2;
103 int num_3 = QString(sub_3.toHex()).toInt(&ok,16);
104 qDebug() << "num_1:::" << num_3;
105
106 }
107 );
108
109 // 触发服务详情发现函数 ,不要忘记调用
110 m_service->discoverDetails();
111 }
112 }
113 });
114
115 connect(m_controler,&QLowEnergyController::discoveryFinished, this, [this]() {
116 qDebug() << "finish service discovery";
117 });
118
119 //连接外围设备
120 m_controler->connectToDevice();
121
122 //QTimer *timer = new QTimer(this);
123 //connect(timer, &QTimer::timeout, this, [this](){ qDebug() <<"state:::" << this->m_controler->state();});
124 //timer->start(1000);
125 }
126 });
127
128 // 开始外围设备搜索
129 m_deviceDiscoveryAgent->start();
130
131 }
132
133 // mac和其他系统上address获取有少许差异,参见官方文档
134 QString BlueDevice::getAddress(QBluetoothDeviceInfo device) const
135 {
136 #ifdef Q_OS_MAC
137 // On OS X and iOS we do not have addresses,
138 // only unique UUIDs generated by Core Bluetooth.
139 return device.deviceUuid().toString();
140 #else
141 return device.address().toString();
142 #endif
143 }
144
145 //void BlueDevice::getNewService(QBluetoothServiceInfo info) {
146 // qDebug() << "ppppp uuuuuuuuuu";
147 //}