Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QLowEnergyService::characteristicChanged is not emitted



  • I am using Bluetooth API of QT 5.13.0 on Windows 10 to connect and get data from my BLE device. But QLowEnergyService::characteristicChanged is not emitted.

    Below is my steps:
    step 1: Use QBluetoothDeviceDiscoveryAgent to discovery devices.
    step 2: Use QLowEnergyController to connect to my device and get specific service of this device that is discovered by ID (My service is serviceA has ID is serviceID)
    step 3: Use QLowEnergyService to connect to serviceA of my device
    serviceA has 2 characteristics: characteristic1(Write) & characteristic2(Notify).
    I have to write value1 to characteristic1 and enable notification of characteristic2, after that I can get data value from characteristic2 through characteristicChanged event of serviceA.

    With the same source code, It works well on Mac OS but on Windows 10 QLowEnergyService::characteristicChanged is not emitted. Is there difference of QT Bluetooth API from Win to Mac? Is this a bug of QT Bluetooth API on Windows?
    Please have a look my source and show me if you know how to fix it. Thanks!

    Below is my code to connect to service and get data from device:

    void Device::connectToService(QLowEnergyService &service)
    {
           if (!service)
                return;
        if (service->state() == QLowEnergyService::DiscoveryRequired) {
            connect(service, &QLowEnergyService::stateChanged, this, &Device::serviceDetailsDiscovered);
            service->discoverDetails();
            return;
       }
    }
    
    void Device::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState)
    {
        QLowEnergyService *service = qobject_cast<QLowEnergyService *>(QObject::sender());
        if (!service){
            qWarning() << "BTLEQtInputDevice::onServiceDetailsDiscovered service is null";
            return;
        }
    
        if (newState != QLowEnergyService::ServiceDiscovered) {
            return;
        }
        QList<QLowEnergyCharacteristic> chars = service->characteristics();
        foreach (const QLowEnergyCharacteristic &currChar, chars) {
            auto currUUID = currChar.uuid();// cInfo->getUuid();
            if (currUUID == characteristic1) {
                service->writeCharacteristic(currChar, value1);
                continue;
            }
            if (currUUID == characteristic2){
                const QLowEnergyDescriptor descriptor = currChar.descriptor(QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
                if (!descriptor.isValid()) {
                    qInfo() << "Descriptor is invalid!";
                }
                service->writeDescriptor(descriptor, QByteArray::fromHex("0100"));
    //Device::onCharacteristicChanged is invoked on Mac but doesn't run on Window10
                connect(service, &QLowEnergyService::characteristicChanged, this, &Device::onCharacteristicChanged);
                continue;
            }
        }
    }
    


  • I see the following message:
    qt.bluetooth.winrt: QWinRTLowEnergyServiceHandlerNew::obtainCharList
    qt.bluetooth.winrt: Could not await descriptor read result

    What does that mean? When does it occur?



  • @NhungPham

    I had the same problem on Windows.

    As a workaround I used QLowEnergyService::readCharacteristic(QLowEnergyChar&) to just read the characteristic and signal QLowEnergyService::characteristicRead() to perform the operation that QLowEnergyService::characteristicChanged() signal would do.


Log in to reply