I. Introduction to the environment
QT version: 5.12.6
Compilation environment: Win10 64-bit
Target system: Android
* * complete engineering source download address (including the APK) : * * download.csdn.net/download/xi…
Want to learn QT Android environment set up here (win10 version) : blog.csdn.net/xiaolong112…
(ubuntu version) : blog.csdn.net/xiaolong112…
Want to learn QT entry to the proficient in programming here: blog.csdn.net/xiaolong112…
Two, function introduction
This software is a BLE Bluetooth serial port debugging assistant, which supports routine debugging of sending and receiving. BLE is bluetooth with low power consumption and is widely used in smart home and Internet of things. BLE Low power Bluetooth generally cannot be directly connected with a mobile phone. By default, mobile phone Bluetooth works in traditional Bluetooth mode and cannot be directly connected to BLE low power Bluetooth signal. You need to use a dedicated APP to configure the mobile phone Bluetooth mode for communication.
In order to facilitate engineers to debug BLE Bluetooth in the process of product development, the software outputs all the information in the process of Bluetooth connection to the screen, which is convenient for debugging errors.
Three, the core source code
#include "mainwindow.h"
#include "ui_mainwindow.h"
/* * Set the QT interface style */
void MainWindow::SetStyle(const QString &qssFile) {
QFile file(qssFile);
if (file.open(QFile::ReadOnly)) {
QString qss = QLatin1String(file.readAll());
qApp->setStyleSheet(qss);
QString PaletteColor = qss.mid(20.7);
qApp->setPalette(QPalette(QColor(PaletteColor)));
file.close(a); }else
{
qApp->setStyleSheet(""); }}//# Bluetooth serial port service
//SerialPortServiceClass_UUID = '{00001101-0000-1000-8000-00805F9B34FB}'
//Service UUID 0xFEE0 Primary Service
//static const QLatin1String serviceUuid("0000FEE0-0000-1000-8000-00805F9B34FB");
// The contents of this string are the serial mode Uuid
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->SetStyle(":/qss/blue.css"); // Set the style sheet
this->setWindowTitle("BLE Bluetooth Debugging Assistant"); // Set the title
this->setWindowIcon(QIcon(":/wbyq.ico")); // Set the icon
/*1. Instantiate bluetooth related objects */
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(a); localDevice =new QBluetoothLocalDevice(a);/*2. Associate bluetooth device-related signals */
/*2.1 Associated device discovery slot function. When scanning detects nearby Bluetooth devices, deviceDiscovered signal is emitted */
connect(discoveryAgent,
SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
this.SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo))
);
/*3. Check the bluetooth status, which is used to set the initial state of the button */
/*3.1 Check whether Bluetooth is enabled */
if(localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff)
{
// If bluetooth is off
ui->pushButton_OpenBluetooth->setEnabled(true); // Open the button
ui->pushButton_CloseBluetooth->setEnabled(false); // Close the button
}
else // If Bluetooth is enabled
{
ui->pushButton_OpenBluetooth->setEnabled(false);// Open the button
ui->pushButton_CloseBluetooth->setEnabled(true);// Close the button
ui->pushButton_BluetoothScan->setEnabled(true); // Set scan button available
}
/*3.2 Set the label to display the name of the local Bluetooth */
QString name_info("Native Bluetooth :");
name_info+=localDevice->name(a); ui->label_BluetoothName->setText(name_info);
ui->pushButton_StopScan->setEnabled(false); // The button to stop bluetooth scanning is not available
ui->plainTextEdit_BluetoothInfiShow->setEnabled(false); // The Settings are not editable
m_control=NULL; / / initial value
m_service=NULL; / / initial value
SendModeSelect=0;
SendMaxMode=0;
}
MainWindow::~MainWindow()
{
delete ui;
delete discoveryAgent;
delete localDevice;
}
void MainWindow::on_pushButton_OpenBluetooth_clicked(a)
{
/* Request to turn on bluetooth device */
localDevice->powerOn(a); ui->pushButton_OpenBluetooth->setEnabled(false);// Open the button
ui->pushButton_CloseBluetooth->setEnabled(true);// Close the button
ui->pushButton_BluetoothScan->setEnabled(true); // Set scan button available
}
void MainWindow::on_pushButton_CloseBluetooth_clicked(a)
{
/* Turn off bluetooth devices */
localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);
ui->pushButton_OpenBluetooth->setEnabled(true);// Open the button
ui->pushButton_CloseBluetooth->setEnabled(false);// Close the button
ui->pushButton_BluetoothScan->setEnabled(false); // Set scan button unavailable
}
void MainWindow::on_pushButton_BluetoothScan_clicked(a)
{
/* Start scanning for nearby Bluetooth devices */
discoveryAgent->start(a); ui->comboBox_BluetoothDevice->clear(a);// Clear the entry
ui->pushButton_BluetoothScan->setEnabled(false); // Set scan button unavailable
ui->pushButton_StopScan->setEnabled(true); // Set the stop scan button available
}
void MainWindow::on_pushButton_StopScan_clicked(a)
{
/* Stop scanning for nearby Bluetooth devices */
discoveryAgent->stop(a); ui->pushButton_StopScan->setEnabled(false); // Set the stop scan button to be unavailable
ui->pushButton_BluetoothScan->setEnabled(true); // Set scan button available
}
/* The current slot function is called */ when scanning for surrounding devices
void MainWindow::addBlueToothDevicesToList(const QBluetoothDeviceInfo &info)
{
// QString label = QString("%1 %2").arg(info.name()).arg(info.address().toString());
QString label = QString("% 1% 2").arg(info.address().toString()).arg(info.name());
ui->comboBox_BluetoothDevice->addItem(label); // Add string to comboBox
}
In Bluetooth, each service and service attribute is uniquely verified by a "global unique identifier" (Uuid). As its name implies, each such identifier is guaranteed to be unique in space and time. The UUID class can manifest as a short (16 or 32 bit) and long (128 bit) UUID. He provides constructors to create classes using strings and 16-bit or 32-bit values, a method to compare two UUids (if both are 128-bit), and a method to convert a UUID to a String. UUID instances are immutable, and only services identified by UUID can be discovered. On Linux you can generate a UUID value with the command uuidgen -t. On Windows, run the uuidgen command. The UUID looks like this: 2D266186-01FB-47C2-8D9F-10b8EC891363. When using the generated UUID to create a UUID object, you can remove the hyphen. * /
// Send data
void MainWindow::on_pushButton_SendData_clicked(a)
{
QString text=ui->lineEdit_SendData->text(a); QByteArray array=text.toLocal8Bit(a);/* Writes newValue as the value of the feature. If the operation succeeds, a characteristicWritten () signal will be emitted. Low-power devices: write up to 20 bytes */ at a time
m_service->writeCharacteristic(m_writeCharacteristic[SendModeSelect],array, m_writeMode);
}
// Clear the data received
void MainWindow::on_pushButton_Clear_clicked(a)
{
ui->plainTextEdit_BluetoothInfiShow->setPlainText("");
}
// Connect to Bluetooth
void MainWindow::on_pushButton_ConnectDev_clicked(a)
{
QString text = ui->comboBox_BluetoothDevice->currentText(a);int index = text.indexOf(' ');
if(index == - 1) return;
QBluetoothAddress address(text.left(index));
QString connect_device="Start connecting bluetooth device :\n";
connect_device+=ui->comboBox_BluetoothDevice->currentText(a); QMessageBox::information(this.tr("Connection hint"),connect_device);
/* Low power Bluetooth device */
if(m_control! =NULL)
{
m_control->disconnectFromDevice(a);// Disconnect the remote device
delete m_control;
m_control = NULL;
}
ui->comboBox_UUID->clear(a);// Clears the UUID service list box
QList<QBluetoothDeviceInfo> info_list=discoveryAgent->discoveredDevices(a);// Get the information about all devices scanned
for(int i=0; i<info_list.count(a); i++) {if(info_list.at(i).address().toString()==text.left(index))
{
remoteDevice=info_list.at(i);
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Connecting device :");
ui->plainTextEdit_BluetoothInfiShow->insertPlainText(remoteDevice.name());
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("\n");
ui->plainTextEdit_BluetoothInfiShow->insertPlainText(remoteDevice.address().toString());
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("\n");
break; }}// Create a central role device
m_control = new QLowEnergyController(remoteDevice, this);
//m_control=QLowEnergyController::createCentral(remoteDevice,this);
if(m_control==0)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Failed to create central role device! \n");
}
else
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Central role device created successfully! \n");
}
// This signal is sent each time a new service is discovered
connect(m_control, SIGNAL(serviceDiscovered(QBluetoothUuid)),this.SLOT(BlueServiceDiscovered(QBluetoothUuid)));
// This signal is emitted when the discovery of a running service is complete.
connect(m_control, SIGNAL(discoveryFinished()),this.SLOT(BlueServiceScanDone()));
// This signal is emitted when the controller is successfully connected to a remote Low Energy device.
connect(m_control, SIGNAL(connected()),this.SLOT(BlueDeviceConnected()));
// This signal is emitted when the controller is disconnected from a remote low-power device.
connect(m_control, SIGNAL(disconnected()),this.SLOT(BlueDeviceDisconnected()));
// This signal is emitted when an error occurs.
connect(m_control, static_cast<void(QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error),
[=](QLowEnergyController::Error error){
if(error==QLowEnergyController::NoError)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("No error \n");
}
else if(error==QLowEnergyController::UnknownError)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("An unknown error occurred. \n");
}
else if(error==QLowEnergyController::UnknownRemoteDeviceError)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("The remote Bluetooth Low Energy device passed to such a constructor could not be found. \n");
}
else if(error==QLowEnergyController::NetworkError)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Failed to read or write to remote device \n");
}
else if(error==QLowEnergyController::InvalidBluetoothAdapterError)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("The local Bluetooth device passed to this constructor could not be found, or there is no local Bluetooth device \n");
}
else if(error==QLowEnergyController::InvalidBluetoothAdapterError)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Failed to connect to the remote device. \n");
}
else
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("***** unknown error! ******\n");
});
// Connect to a remote Bluetooth low power device.
m_control->connectToDevice(a); }// This slot function is called every time a new service is discovered
void MainWindow::BlueServiceDiscovered(const QBluetoothUuid &gatt)
{
ui->comboBox_UUID->addItem(gatt.toString()); // Add string to comboBox
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("\n");
ui->plainTextEdit_BluetoothInfiShow->insertPlainText(gatt.toString());
}
// Help tips
void MainWindow::on_pushButton_help_clicked(a)
{
QMessageBox::information(this.tr("Help tips"),"This software for BLE4.0 Bluetooth debugging \n"
"Hc-05 Series 2.0 Bluetooth \ N not supported"
"If you open the software interface for the first time,
"Don't fit the screen close the application can be reopened \n"
"Software author :DS Little Dragon brother \ N"
"BUG feedback: 1126626497 @qq.com");
}
// Specifies the UUID service by default
static const QLatin1String serviceUuid("{0000FEE0-0000-1000-8000-00805F9B34FB}");
// This signal is emitted when the discovery of a running service is complete.
void MainWindow::BlueServiceScanDone(a)
{
// UI ->plainTextEdit_BluetoothInfiShow->insertPlainText(" running service discovery complete \n");
// QMessageBox::information(this,tr(" help ")," service discovery completed \n"
// "Please select service \n from the list above"
// "Connect to BLE low power Bluetooth device \n");
/* Check whether */ has been connected before
if(m_service! =NULL)
{
delete m_service;
m_service=NULL;
}
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("\n Selected service :");
ui->plainTextEdit_BluetoothInfiShow->insertPlainText(serviceUuid);
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("\n");
/* Establish services between devices */
m_service=m_control->createServiceObject(QBluetoothUuid(serviceUuid),this);
if(m_service==NULL)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Service establishment failed! \n");
return;
}
else
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Service established successfully! \n");
}
/* This signal is emitted when the service status changes. NewState can also be passed through state (). * /
connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
this.SLOT(BleServiceServiceStateChanged(QLowEnergyService::ServiceState)));
/* This signal is emitted on the peripheral when the property value is changed by an event. The newValue parameter contains the updated value feature */
connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)),
this.SLOT(BleServiceCharacteristicChanged(QLowEnergyCharacteristic,QByteArray)));
/* This signal is emitted when a characteristic read request successfully returns its value. * /
connect(m_service, SIGNAL(characteristicRead(QLowEnergyCharacteristic,QByteArray)),
this.SLOT(BleServiceCharacteristicRead(QLowEnergyCharacteristic,QByteArray)));
/* This signal is emitted when the property value is successfully changed to newValue. * /
connect(m_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)),
this.SLOT(BleServiceCharacteristicWrite(QLowEnergyCharacteristic,QByteArray)));
/* Error signal */
connect(m_service, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error),
[=](QLowEnergyService::ServiceError newErrorr)
{
if(QLowEnergyService::NoError == newErrorr)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("There was no error. \n");
}
if(QLowEnergyService::OperationError==newErrorr)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Error: Trying to operate when service is not ready! \n");
}
if(QLowEnergyService::CharacteristicReadError==newErrorr)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Failed to read characteristic values! \n");
}
if(QLowEnergyService::CharacteristicWriteError==newErrorr)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Failed to write new value for feature! \n");
}
if(QLowEnergyService::DescriptorReadError==newErrorr)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Attempt to read descriptor value failed! \n");
}
if(QLowEnergyService::DescriptorWriteError==newErrorr)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Failed to write new value to descriptor! \n");
}
if(QLowEnergyService::UnknownError==newErrorr)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Unknown error while interacting with service! \n"); }});if(m_service->state() == QLowEnergyService::DiscoveryRequired)
{
m_service->discoverDetails(a);// Start the service discovery scan
}
else
searchCharacteristic(a); }// Search features
void MainWindow::searchCharacteristic(a)
{
if(m_service)
{
QList<QLowEnergyCharacteristic> list=m_service->characteristics(a);qDebug() < <"list.count()="<<list.count(a);// Characteristics
SendMaxMode=list.count(a);// Set the upper limit of mode selection
for(int i=0; i<list.count(a); i++) { QLowEnergyCharacteristic c=list.at(i);
/* Returns true if the QLowEnergyCharacteristic object is valid, false*/ otherwise
if(c.isValid())
{
// Returns the attribute of the attribute.
// These attributes define the access permissions for attributes.
if(c.properties() & QLowEnergyCharacteristic::WriteNoResponse || c.properties() & QLowEnergyCharacteristic::Write)
// if(c.properties() & QLowEnergyCharacteristic::Write)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Have write permission! \n");
m_writeCharacteristic[i] = c; // Save the write permission feature
if(c.properties() & QLowEnergyCharacteristic::WriteNoResponse)
Remote peripherals should not send write acknowledgements if this mode write feature is used.
// The success of the operation cannot be determined, and the payload must not exceed 20 bytes.
// A feature must be set to the QLowEnergyCharacteristic :: WriteNoResponse attribute to support this write mode.
// It has the advantage of faster write operations, as it may occur between other device interactions.
m_writeMode = QLowEnergyService::WriteWithoutResponse;
else
m_writeMode = QLowEnergyService::WriteWithResponse;
// If this mode write feature is used, the peripheral should send write acknowledgement.
// If the operation succeeds, a confirmation is issued via the characteristicWritten () signal.
// Otherwise, issue a CharacteristicWriteError.
// A feature must be set to the QLowEnergyCharacteristic :: Write attribute to support this Write mode.
}
if(c.properties() & QLowEnergyCharacteristic::Read)
{
m_readCharacteristic = c; // Save the read permission feature
}
// Descriptors define how features are configured by a particular client.
m_notificationDesc = c.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
/ / value is true
if(m_notificationDesc.isValid())
{
// Write the descriptor
m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
// m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("FEE1"));
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Write the descriptor! \n");
}
}
}
}
}
// This signal is emitted when the controller is successfully connected to a remote Low Energy device.
void MainWindow::BlueDeviceConnected(a)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Device connected successfully! \n");
// Start discovery Services
m_control->discoverServices(a);// QList
uuid_list=m_control->services(); // Get the successfully searched service
// for(int i=0; i
/ / {
// ui->comboBox_UUID->addItem(uuid_list.at(i).toString()); // Add string to comboBox
/ /}
// if(uuid_list.count()<=0)
/ / {
// UI ->plainTextEdit_BluetoothInfiShow->insertPlainText(" no UUID service found! \n");
/ /}
}
// This signal is emitted when the controller is disconnected from a remote low-power device.
void MainWindow::BlueDeviceDisconnected(a)
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("Successfully disconnected! \n");
}
// The currently selected service
void MainWindow::on_comboBox_UUID_currentIndexChanged(const QString &arg1)
{}// This signal is emitted when the service status changes
void MainWindow::BleServiceServiceStateChanged(QLowEnergyService::ServiceState s)
{
// UI ->plainTextEdit_BluetoothInfiShow->insertPlainText(" This signal is emitted when the state of the service changes! \n");
if(s == QLowEnergyService::ServiceDiscovered) // All details are synchronized
{
ui->plainTextEdit_BluetoothInfiShow->insertPlainText("All the details have been discovered! \n");
searchCharacteristic();
}
}
// Data is read
void MainWindow::BleServiceCharacteristicChanged(const QLowEnergyCharacteristic &c,
const QByteArray &value)
{
// UI ->plainTextEdit_BluetoothInfiShow->insertPlainText(" this signal is emitted when a property value is changed by an event on a peripheral! \n");
ui->plainTextEdit_BluetoothInfiShow->insertPlainText(QString(value));
// Move the scroll bar to the bottom
QScrollBar *scrollbar = ui->plainTextEdit_BluetoothInfiShow->verticalScrollBar(a);if(scrollbar)
{
scrollbar->setSliderPosition(scrollbar->maximum()); }}void MainWindow::BleServiceCharacteristicRead(const QLowEnergyCharacteristic &c,
const QByteArray &value)
{
// UI ->plainTextEdit_BluetoothInfiShow->insertPlainText(" when a feature read request returns its value successfully \n");
//ui->plainTextEdit_BluetoothInfiShow->insertPlainText(QString(value));
}
void MainWindow::BleServiceCharacteristicWrite(const QLowEnergyCharacteristic &c,
const QByteArray &value)
{
// UI ->plainTextEdit_BluetoothInfiShow->insertPlainText(" when the property value is successfully changed to newValue! \n");
ui->plainTextEdit_BluetoothInfiShow->insertPlainText(QString(value));
}
// Send mode
void MainWindow::on_pushButton_SendMode_clicked(a)
{
bool ok;
int data = QInputDialog::getInt(this.tr("Get input mode"),tr("Selection mode :"), 0.0,SendMaxMode,1, &ok);
if(ok) { SendModeSelect=data; }}Copy the code