BLE introduction
BLE Bluetooth is a Bluetooth module above Bluetooth 2.0, and classic Bluetooth is Bluetooth below Bluetooth 2.0. Bluetooth is divided into client and server. Classic Bluetooth can communicate between client and server through socket programming (similar to network socket), but BLE Bluetooth cannot communicate in this way. There are services and eigenvalues under BLE Bluetooth. The so-called BLE Bluetooth communication is actually a read-write operation of eigenvalues. Microsoft's API under Windows, C++API for BLE Bluetooth is relatively few, and C # API will be relatively more. The demo I implemented this Bluetooth is a development using Qt.
It should be noted that Qt Used in development QBlueTooth Library in Windows Only supported under win10 The above systems, and need Qt Version 5.15 Above, the compiler must be used MSVC Compile, otherwise it cannot be supported Windows Platform.
Qt5BLE Bluetooth development
The environment of this paper is Qt5 fifteen point two
To use Bluetooth Library in Qt, you need to Add a sentence to the pro file
QT += bluetooth
BLE Bluetooth development process
First of all, let's talk about my understanding of BLE Bluetooth. BLE Bluetooth has a name and address. There is a service under the Bluetooth device. The service has a specific uuid, which can be understood as the identification code of the service. There are features under the service. BLE Bluetooth service can have 0-3 features, namely read, write and eigenvalue notification. If the service has a read feature, you can read messages from the service. If the service has a write feature, you can send messages to the service. If the service has a feature of feature value change notification, a message notification will be sent when the feature value of the service changes.
- Bluetooth permission problem (this problem does not exist under Windows platform and can be ignored. This problem needs to be considered under Android platform, whether Qt or Java)
- Search surrounding Bluetooth
- Connect Bluetooth
- Get service
- Get the features under the service. There are 0-3 features under each service, which correspond to reading, writing and whether to notify when the features change
- Communicating with BLE devices (actually reading and writing a service)
Bluetooth Class involved in Qt and Bluetooth header files and classes involved in APIQt
#include <QBluetoothLocalDevice> #include <QBluetoothUuid> #include <QBluetoothDeviceDiscoveryAgent> #include <QLowEnergyService> #include <QLowEnergyController> stay windows Platform and ios Under platform QBluetoothLocalDevice Class cannot be used Because the platform will not disclose any information that may be available locally Bluetooth Data or information provided on the device API QBluetoothDeviceDiscoveryAgent -- Bluetooth search class( BLE (both Bluetooth and classic Bluetooth use this for searching) LowEnergyController -- BLE Bluetooth device access class QLowEnergyService -- BLE Bluetooth service class
Concrete implementation
1. Realize the search of nearby BLE Bluetooth
QBluetoothDeviceDiscoveryAgent *Discovery = new QBluetoothDeviceDiscoveryAgent; Discovery->setLowEnergyDiscoveryTimeout(30000);//Set the search time to 30000us //When the Bluetooth search is completed, [Signal]finished() will be sent connect(Discovery, SIGNAL(finished()), this, SLOT(findFinish())); //When a Bluetooth device is found, it will send [signal] devicediscovered (qbluetooth DeviceInfo) connect(Discovery, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), this, SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo))); //start starts the search. If the search is BLE, Bluetooth needs to write parameters //QBluetoothDeviceDiscoveryAgent::LowEnergyMethod Discovery->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
2. Connect BLE Bluetooth
//void QLowEnergyController::creatCentral(const QBluetoothDeviceInfo &remotedevice,QObject *parent) //Parameters: remotedevice -- information of remote device parent -- parent class //Return value: None //Function: initialize the controller for remote Bluetooth access mController = QLowEnergyController::createCentral(currentDevice,this); connect(mController, &QLowEnergyController::serviceDiscovered,this, &MainWindow::serviceDiscovered);//Scan the target BLE service, and get it and trigger it once connect(mController, &QLowEnergyController::discoveryFinished,this, &MainWindow::serviceScanDone); //This signal is triggered after the scan is completed connect(mController, static_cast<void (QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error), this, [this](QLowEnergyController::Error error) { Q_UNUSED(error); QMessageBox::information(this,tr("Info"),tr("Cannot connect to remote device.")); });//link error connect(mController, &QLowEnergyController::connected, this, [this]() { QMessageBox::information(this,tr("Info"),tr("Controller connected. Search services...")); mController->discoverServices(); });//Connection successful connect(mController, &QLowEnergyController::disconnected, this, [this]() { QMessageBox::information(this,tr("Info"),tr("LowEnergy controller disconnected")); });//Disconnect mController->connectToDevice();//Establish a connection. If there is no error in the connection, the service of the connected device will be automatically searched
3. Access to services
//mController->connectToDevice(); If there is no error after the connection is established, the service scan of the remote device will be carried out automatically //This slot function is triggered when the service is found //Service found void MainWindow::serviceDiscovered(const QBluetoothUuid & serviceUuid) { QLowEnergyService *service = mController->createServiceObject(serviceUuid); //Synchronization service if (!service) { QMessageBox::information(NULL,"error","Cannot create service for uuid"); return; } connect(service, &QLowEnergyService::stateChanged, this,&MainWindow::serviceStateChanged); //Service status value changed connect(service, &QLowEnergyService::characteristicChanged, this,&MainWindow::BleServiceCharacteristicChanged); //Eigenvalue changes connect(service, &QLowEnergyService::characteristicRead, this,&MainWindow::BleServiceCharacteristicRead); //Read information successfully connect(service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)),this, SLOT(BleServiceCharacteristicWrite(QLowEnergyCharacteristic,QByteArray))); //Write message succeeded if(service->state() == QLowEnergyService::DiscoveryRequired) service->discoverDetails(); //Scan eigenvalue serviceList.append(service); } //This slot function is triggered when the service status value changes //When the Bluetooth service is scanned, the status value will change to QLowEnergyService::ServiceDiscovered void MainWindow::serviceStateChanged(QLowEnergyService::ServiceState s) { if(s == QLowEnergyService::ServiceDiscovered) { //QMessageBox::information(NULL,"tips",QObject::tr("Service synchronization")); //TODO.... } }
4. Scan service characteristic value
void MainWindow::searchCharacteristic() { if(currentService) { memset(m_Characteristic,0,sizeof(m_Characteristic)); QList<QLowEnergyCharacteristic> list = currentService->characteristics(); //Characteristics get detailed characteristics foreach(QLowEnergyCharacteristic c,list) { /*Returns true if the QLowEnergyCharacteristic object is valid, otherwise false*/ if(c.isValid()) { //Returns the properties of the feature. //These attributes define the access rights of the feature. //Save properties (notify when reading, writing and changing) if(c.properties() & QLowEnergyCharacteristic::WriteNoResponse || c.properties() & QLowEnergyCharacteristic::Write)//write // if(c.properties() & QLowEnergyCharacteristic::Write) { ui->checkBox_write->setChecked(true); m_Characteristic[0] = c; } else ui->checkBox_write->setChecked(false); if(c.properties() & QLowEnergyCharacteristic::Read)//read { ui->checkBox_read->setChecked(true); m_Characteristic[1] = c; } else ui->checkBox_read->setChecked(true); if(c.properties() & QLowEnergyCharacteristic::Notify)//Is it notified when the characteristics change { ui->checkBox_notify->setChecked(true); m_Characteristic[2] = c; } else ui->checkBox_notify->setChecked(false); } } } }
5. Read and write operation of ble Bluetooth
//void QLowEnergyService::writeCharacteristic(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue, QLowEnergyService::WriteMode mode = WriteWithResponse) //Parameters: Characteristic -- a characteristic value of the current service newValue -- write data WriteMode mode -- write mode //Return value: None //Function: send information to BLE currentService->writeCharacteristic(m_Characteristic[0], QByteArray(text.toUtf8())); //This slot function is triggered successfully after sending a message void MainWindow::BleServiceCharacteristicWrite(const QLowEnergyCharacteristic &c, const QByteArray &value) { QString str(c.uuid().toString()); QString str2("instructions %1 send to success!"); QString str3 = str + QString(":") + str2.arg(QString(value)); QMessageBox::information(NULL,"tips",str3); } //void QLowEnergyService::readCharacteristic(const QLowEnergyCharacteristic &characteristic) //Parameter: Characteristic -- a characteristic value of the current service //Return value: None //Function: read information from BLE currentService->readCharacteristic(m_Characteristic[1]); //This slot function is triggered when a message is read void MainWindow::BleServiceCharacteristicRead(const QLowEnergyCharacteristic &c, const QByteArray &value) { QTextCodec *codec = QTextCodec::codecForName("GBK");//Specifies how QString is encoded QString showMsg = c.uuid().toString() + codec->toUnicode(value);//Output information in Unicode encoding format QString valuetoHexString = value.toHex();//Hexadecimal output information qDebug()<<value; qDebug()<<valuetoHexString; ui->listWidget_recv->addItem(showMsg); ui->listWidget_recv->setCurrentRow(ui->listWidget_recv->count()-1); }