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

2020, top ten marketing keywords!

Affected by the overall environment this year, al...

APP promotion: 4 core steps to acquire users!

Like any startup, we are experimenting to find th...

Aiti Tribe Stories (27): The Growth Diary of a Neighboring Operations Engineer

[51CTO.com original article] The protagonist of t...

Does a catering brand need to build private domain traffic?

I haven’t talked about private domain for a long ...

The dispute between "hard tofu" and "soft tofu" is because of this addition!

Audit expert: Wang Guoyi Postdoctoral fellow in N...

In Microsoft's eyes, XBOX is actually such a role...

There is no doubt that in the battle for the next...

For promotion on Xiaohongshu, just read this article.

This article will try to answer your questions: 1...

Dongfeng A9 real shot at Guangzhou Auto Show: copying Passat to the end

It seems that ever since BMW sued domestic car co...

SEM operation: All the SEM creative strategies you want are here!

This article starts with the creative foundation,...

The three-level logic of brand slogans

As a marketing communication tool, brand slogan p...

Xiaomi MIUI 6: Lei Jun's dilemma and ambition

Xiaomi released its MIUI 6 in the form of a lolli...