Qt programming example: BLE communication software based on Android

Qt programming example: BLE communication software based on Android

[[374870]]

Achieving goals

  • Write your own Qt-based Android software to enable data communication between the mobile phone and the TB-02-kit module;
  • The data sent by the Android software is forwarded to the serial port assistant through the TB-02-kit module;
  • The data sent by the serial port assistant can be displayed in the Android software, thereby realizing two-way data communication of BLE.

Required tools and environment

  • TB-02-kit module
  • Qt Creator 4.10.1
  • Qt 5.13.1
  • XCOM V2.0 Serial Port Assistant
  • Android Phone
  • My computer is Windows 10 64bit [version 10.0.19041.329]

Source code of this article

Because this is the first time to share Qt code, in order to facilitate everyone's learning, a lot of comments have been added to the code, and everyone can learn more efficiently by referring to the code.

Reply to the keyword "Android-BLE" in the backend to obtain the software and Qt project source code involved in this article.

Specific implementation

1. To use the Qt Bluetooth module, you need to add a declaration to the project's .pro file.

2. Scan Devices

Perform a scan for Bluetooth devices in the constructor, that is, as soon as the software starts.

  1. Widget::Widget(QWidget *parent)
  2. : QWidget(parent)
  3. , ui(new Ui::Widget)
  4. {
  5. ui->setupUi(this);
  6.  
  7. //Create a search service: https://doc.qt.io/qt-5/qbluetoothdevicediscoveryagent.html
  8. discoveryAgent =new QBluetoothDeviceDiscoveryAgent(this);
  9. //Set the BLE search time
  10. discoveryAgent->setLowEnergyDiscoveryTimeout(20000);
  11. connect (discoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this,SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo)));//After finding the device, add it to the list and display it
  12. connect (discoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
  13. connect (discoveryAgent, SIGNAL(canceled()), this, SLOT(scanCanceled()));
  14. connect (this, SIGNAL(returnAddress(QBluetoothDeviceInfo)), this, SLOT(createCtl(QBluetoothDeviceInfo)));
  15.  
  16. //Start searching for devices
  17. discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
  18. }

3. Add the scan results to QListWidget

  1. //Slot function corresponding to deviceDiscovered signals
  2. void Widget::addBlueToothDevicesToList(const QBluetoothDeviceInfo &info)
  3. {
  4. if (info.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) //Get device information and determine whether the device is a BLE device
  5. {
  6. //Format device address and device name
  7. QString label = QString( "%1 %2" ).arg(info.address().toString()).arg(info.name ( ));
  8. // Check if the device already exists to avoid duplicate addition
  9. QList<QListWidgetItem *> items = ui->ctrBleList->findItems(label, Qt::MatchExactly);
  10.  
  11. //If it does not exist, add it to the device list
  12. if (items.empty())
  13. {
  14. QListWidgetItem *item = new QListWidgetItem(label);
  15. ui->ctrBleList->addItem(item);
  16. devicesList.append(info);
  17. }
  18. }
  19. }

4. Connect Bluetooth and stop scanning

  1. void Widget::on_btnConnectBle_clicked()
  2. {
  3. //Confirm that a Bluetooth device is selected
  4. if(!ui->ctrBleList->currentItem()->text().isEmpty())
  5. {
  6. //Get the selected address
  7. QString bltAddress = ui->ctrBleList->currentItem()->text(). left (17);
  8.  
  9. for ( int i = 0; i<devicesList. count (); i++)
  10. {
  11. //Address comparison
  12. if(devicesList. at (i).address().toString(). left (17) == bltAddress)
  13. {
  14. QBluetoothDeviceInfo choosenDevice = devicesList. at (i);
  15. //Send custom signals==>Execute slots:createCtl
  16. emit returnAddress(choosenDevice);
  17. //Stop the search service
  18. discoveryAgent->stop();
  19. break;
  20. }
  21. }
  22. }
  23. }

5. Get features

  1. void Widget::searchCharacteristic()
  2. {
  3. if(m_bleServer)
  4. {
  5. QList<QLowEnergyCharacteristic> list=m_bleServer->characteristics();
  6. qDebug()<< "[xiaohage]list.count()=" << list.count ();
  7. //Traverse characteristics
  8. for ( int i=0;i<list. count ();i++)
  9. {
  10. QLowEnergyCharacteristic c= list.at (i);
  11. /*Returns true if the QLowEnergyCharacteristic object is valid, otherwise returns false */
  12. if(c.isValid())
  13. {
  14. // Return the properties of the feature.
  15. // These attributes define the access permissions of the characteristic.
  16. if(c.properties() & QLowEnergyCharacteristic::WriteNoResponse || c.properties() & QLowEnergyCharacteristic::Write)
  17. {
  18. ui->ctrSystemLogInfo->insertPlainText( "\nHas write permission!" );
  19. m_writeCharacteristic = c; //Save write permission characteristics
  20. if(c.properties() & QLowEnergyCharacteristic::WriteNoResponse)
  21. {
  22. m_writeMode = QLowEnergyService::WriteWithoutResponse;
  23. }
  24. else  
  25. {
  26. m_writeMode = QLowEnergyService::WriteWithResponse;
  27. }
  28. }
  29.  
  30. if(c.properties() & QLowEnergyCharacteristic:: Read )
  31. {
  32. m_readCharacteristic = c; //Save read permission characteristics
  33. }
  34.  
  35. // A descriptor defines how a characteristic is configured by a specific client.
  36. m_notificationDesc = c.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
  37. //value is true
  38. if(m_notificationDesc.isValid())
  39. {
  40. //Write descriptor
  41. m_bleServer->writeDescriptor(m_notificationDesc, QByteArray::fromHex( "0100" ));
  42. ui->ctrSystemLogInfo->insertPlainText( "\nWrite descriptor!" );
  43. }
  44. }
  45. }
  46. }
  47. }

6. Sending Data

writeCharacteristic() method to send data to the BLE device.

Click the "Send" button in the interface to send the "Hello World" string.

  1. void Widget::SendMsg(QString text)
  2. {
  3. QByteArray array=text.toLocal8Bit();
  4.  
  5. m_bleServer->writeCharacteristic(m_writeCharacteristic,array, m_writeMode);
  6. }
  7.  
  8. void Widget::on_btnSendData_clicked()
  9. {
  10. SendMsg( "Hello World" );
  11. }

7. Write data

Receive messages received by Bluetooth through the Bluetooth QLowEnergyService::characteristicRead callback interface.

  1. void Widget::BleServiceCharacteristicRead(const QLowEnergyCharacteristic &c,const QByteArray &value)
  2. {
  3. Q_UNUSED(c)
  4.  
  5. ui->ctrSystemLogInfo->insertPlainText( "\nWhen a characteristic read request successfully returns its value: " );
  6. ui->ctrSystemLogInfo->insertPlainText(QString(value));
  7. }

8. Disconnect

  1. Widget::~Widget()
  2. {
  3. if(!(m_BLEController->state() == QLowEnergyController::UnconnectedState))
  4. m_BLEController->disconnectFromDevice(); //Disconnect from the device
  5.  
  6. delete ui;
  7. }

Interface layout

Results

If "Cannot connect to remote device." appears, you can click the "Connect" button to reconnect.

Serial port assistant and application output

To do

This example is just to demonstrate the communication process between an Android phone and the TB-02-kit module. There are some areas that need to be improved in the program. For example, a "scan" button should be added instead of directly performing Bluetooth scanning during software startup. In this case, Bluetooth power-on needs to be completed before the software is started.

The robustness of the program also needs to be improved. For example, occasionally the module may not be connected properly, and you will need to click the "Connect" button again. You can improve these tasks by yourselves.

With this knowledge, the next step is to combine Android phones and TB-02-kit modules to achieve remote control of STM32 devices.

Qt Tips

1. Qt Creator program output window filters debugging information

2. Add events to Button

Select "Go to slot..." in the right-click menu of the Button control, then select the signal in the pop-up list: "clicked()", and then click the OK button to enter its event function.

References

Qt official documentation: https://doc.qt.io/qt-5/classes.html

This article is reprinted from the WeChat public account "Embedded from 0 to 1", which can be followed through the following QR code. To reprint this article, please contact the Embedded from 0 to 1 public account.

<<:  This year's 12306 is very different! New features you must know when going home for the Spring Festival

>>:  Talk about the birth and use of AMS

Recommend

Another way to bypass the non-public API restrictions on Android P and above

Last year, Android P introduced restrictions on n...

Case summary: How can an offline store attract 2,000+ people in two hours?

Seeing this title, I believe many people are a li...

New discovery | Intestinal flora affects obesity!

Obesity is a global public health issue. Some stu...

How to master new media marketing?

In the new media era, where “everyone has their o...

Three steps to help you organize your WeChat operation ideas

If your thinking is not clear, it will be difficu...

Cool horizontal elastic menu

Source code introduction: MySpringMenu is a cool ...

SEM | Click is a technology, conversion is an art, why do we say that?

Over the past few decades, the rapid and innovati...