Qt for Android 使用BLE串口蓝牙发送数据

您所在的位置:网站首页 手机蓝牙发送数据 Qt for Android 使用BLE串口蓝牙发送数据

Qt for Android 使用BLE串口蓝牙发送数据

2023-07-25 06:06| 来源: 网络整理| 查看: 265

最近搞毕设,买了个串口BLE蓝牙想配合Qt for Android做一个自制的遥控器,参考了很多qt蓝牙的文章,最后弄成apk发现连接不了我的蓝牙,折腾了好久发现Qt官方的蓝牙套接字只适用于SPP传输的蓝牙,而BLE蓝牙则有专门实现代码,说实话比蓝牙套接字复杂了好几百倍,而且官方的示例工程是一些有特殊功能的蓝牙,不太能移植到单单发送数据的串口蓝牙。由于我对蓝牙研究也不是很深,参考了很多大佬的博客,发现了一个比较好,功能相近的项目,下面是链接

Qt for Androidble蓝牙串口助手

但是进去后界面排版有点不好看,也没有源码可以提供,并且我只是要一个发送数据的功能,所以经过改造,实现了可以发送数据的功能了,下面贴下关键步骤的代码

下面是构造函数执行的操作,首先是建立一个搜索设备的服务类,设置好各种信号槽连接,然后开始搜索设备。

//搜索设备 m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); m_deviceDiscoveryAgent->setLowEnergyDiscoveryTimeout(20000); //设置超时时间 connect(m_deviceDiscoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), this, SLOT(addDevice(QBluetoothDeviceInfo)));//搜索到设备操作 connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));//搜索结束 connect(this, SIGNAL(returnAddress(QBluetoothDeviceInfo)), this, SLOT(createCtl(QBluetoothDeviceInfo))); //开始连接目标设备 connect(ui->bluemsg,SIGNAL(cursorPositionChanged()),this,SLOT(autoScroll())); //信息一直在最下面显示 m_deviceDiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); //开始进行搜索 ui->blue_search->setEnabled(false);

当搜索到设备后会进入下列槽函数,这里对目标设备进行了过滤,去除了非BLE的设备,然后添加进ListWidget的列表中

void MainWindow::addDevice(const QBluetoothDeviceInfo &info) { if (info.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {//判断是否是BLE设备 QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name());//按顺序显示地址和设备名称 QList items = ui->bluelist->findItems(label, Qt::MatchExactly);//检查设备是否已存在,避免重复添加 if (items.empty()) {//不存在则添加至设备列表 QListWidgetItem *item = new QListWidgetItem(label); ui->bluelist->addItem(item); m_devices.append(info); } } }

当双击列表中的设备后,就会将设备信息传到另一个函数中(建立中心设备的函数),准备开始连接

void MainWindow::on_blue_connect_clicked(bool checked) { if(ui->bluelist->currentItem()->text().isEmpty()){}//确认选取有效 else { QString bltAddress = ui->bluelist->currentItem()->text().left(17);//获取选择的地址 for (int i = 0; istop();//停止搜索服务 break; } } } }

获取到设备信息后,建立BLE中心设备系统类,并先配置好有关下面操作的信号槽:

搜索外围设备服务通过UUID建立对应服务配置相应的服务出错提示成功提示

然后开始对对应的外围设备进行连接申请

void MainWindow::createCtl(QBluetoothDeviceInfo info) { m_control = QLowEnergyController::createCentral(info, this); connect(m_control, &QLowEnergyController::serviceDiscovered, this,&MainWindow::serviceDiscovered); //发现了目标设备后触发的操作 connect(m_control, &QLowEnergyController::discoveryFinished, this, &MainWindow::serviceScanDone); //配置服务 connect(m_control, static_cast(&QLowEnergyController::error), this, [this](QLowEnergyController::Error error) { Q_UNUSED(error); ui->bluemsg->append("Cannot connect to remote device."); //错误连接 }); connect(m_control, &QLowEnergyController::connected, this, [this]() { ui->bluemsg->append("Controller connected. Search services...\n"); //成功连接触发的槽函数 m_control->discoverServices(); isconnected=true; }); connect(m_control, &QLowEnergyController::disconnected, this, [this]() { ui->bluemsg->append("LowEnergy controller disconnected"); //错误连接 }); //connect ui->bluemsg->append("start to connect\n"); m_control->connectToDevice(); //开始连接目标设备 }

第一步:开始搜索外围设备的UUID。第一次如果不知道外围设备有什么UUID就像下面这样写,然后下一次将其中一个UUID复制下来用就行了。

void MainWindow::serviceDiscovered(const QBluetoothUuid &gatt) { ui->bluemsg->insertPlainText(QString("%1").arg(gatt.toString())); m_foundHeartRateService = true; }

第二步:通过UUID建立服务,并配置读写特性就绪、状态变化、特性变化的信号槽。如果UUID没有问题,就会进入searchCharacteristic函数进行筛选特性。

void MainWindow::serviceScanDone() { //setInfo("Service scan done."); ui->bluemsg->append("Service scan done."); m_service = m_control->createServiceObject(QBluetoothUuid(serviceUuid), this);//这里的serviceUuid就是自己找的,可以通过上面方法找 if(m_service) { ui->bluemsg->append("服务建立成功\n"); m_service->discoverDetails(); } else { ui->bluemsg->append("Service not found"); return; } connect(m_service, &QLowEnergyService::stateChanged, this, &MainWindow::serviceStateChanged); connect(m_service, &QLowEnergyService::characteristicChanged, this, &MainWindow::BleServiceCharacteristicChanged); connect(m_service, &QLowEnergyService::characteristicRead, this, &MainWindow::BleServiceCharacteristicRead); connect(m_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)), this, SLOT(BleServiceCharacteristicWrite(QLowEnergyCharacteristic,QByteArray))); if(m_service->state()==QLowEnergyService::DiscoveryRequired) { m_service->discoverDetails(); } else { searchCharacteristic(); } }

这里可以判断服务的获取状态来验证服务是否成功建立,进入不了那么大概率是UUID配置错了。

void MainWindow::serviceStateChanged(QLowEnergyService::ServiceState s) { if(s == QLowEnergyService::ServiceDiscovered) { ui->bluemsg->append("服务已同步\n"); searchCharacteristic(); } }

下面是筛选特性,读特性没什么讲究,只要UUID是正确的就可以。但是写特性要注意,BLE中分为回响写特性和无回响写特性,回响写特性就是写一次必须要等到外围设备发回来一次才能写,如果你的写模式两种都要,那么可以用个容器保存,不然过滤掉回响写特性就可以了。

void MainWindow::searchCharacteristic() { if(m_service) { QList list=m_service->characteristics(); qDebug()bluemsg->insertPlainText("写描述符!\n"); } } } } }

下面分别是发送数据的函数和发送成功的函数,通过向写特性写入数据即可发送数据,发送成功后就会进入对应的槽函数。

void MainWindow::SendMsg(QString text) { QByteArray array=text.toLocal8Bit(); m_service->writeCharacteristic(m_writeCharacteristic[SendModeSelect],array, m_writeMode); } void MainWindow::BleServiceCharacteristicWrite(const QLowEnergyCharacteristic &c, const QByteArray &value) { ui->bluemsg->append(QString("指令%1发送成功").arg(QString(value))); }

当有数据发送过来的时候,我们就可以通过读特性的槽函数来获取数据。

在我另外的一个蓝牙小车遥控器也用相关代码实现了,可以在那个博客获取到源码。

下面是成功连接的图片 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3