Search code examples
c++qtbluetooth-lowenergyheartrate

get heart frequency frome a BLE sensor


I try to develope a windows 10 software on Qt creator(C++) who need the heart frequency. I buy the sensor below who transfer it's data by bluetooth(BLE:bluetooth low energy):

https://www.decathlon.fr/p/ceinture-cardiofrequencemetre-course-a-pied-dual-ant-bluetooth-smart/_/R-p-128085

but when i try to read the value, i have a empty buffer.

the sensor work correcly on a android appli (on play store)

my code :

initialisation:OK

TWindowsStatistique::TWindowsStatistique(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::TWindowsStatistique)
{
      QBluetoothDeviceDiscoveryAgent *discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
      connect(discoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this, SLOT(deviceDiscovered(QBluetoothDeviceInfo)));
      discoveryAgent->start();
}

get the list of bluetooth device:OK

void TWindowsStatistique::deviceDiscovered(const QBluetoothDeviceInfo &device)
{
    if(device.name()=="Decathlon Dual HR")
    {
        m_device=device;
        if (!controller) 
        {
            controller = QLowEnergyController::createCentral(device);
            connect(controller, &QLowEnergyController::connected,this, &TWindowsStatistique::deviceConnected);
            connect(controller, QOverload<QLowEnergyController::Error>::of(&QLowEnergyController::error),this, &TWindowsStatistique::errorReceived);
            connect(controller, &QLowEnergyController::disconnected,this, &TWindowsStatistique::deviceDisconnected);
        }
        controller->connectToDevice();
    }
}

get service list:OK

void TWindowsStatistique::deviceConnected()
{
    connect(controller, &QLowEnergyController::serviceDiscovered,this, &TWindowsStatistique::addLowEnergyService);
    connect(controller, &QLowEnergyController::discoveryFinished,this, &TWindowsStatistique::serviceScanDone);
    controller->discoverServices();
}


void TWindowsStatistique::addLowEnergyService(const QBluetoothUuid &newService)
{
    QLowEnergyService *service = controller->createServiceObject(newService);
    if (!service) return;

    if(service->serviceName()=="Heart Rate")
    {
        heart_rate_service=service;
    }
}


void TWindowsStatistique::serviceScanDone()
{
    if(heart_rate_service!=NULL)
    {
        connect(heart_rate_service, &QLowEnergyService::stateChanged, this, &TWindowsStatistique::serviceDetailsDiscovered);
        heart_rate_service->discoverDetails();
    }
}

get caracteristic list :OK with heart rate data : NOK


void TWindowsStatistique::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState)
{
    const QList<QLowEnergyCharacteristic> chars = heart_rate_service->characteristics();
    for (int i=0;i<chars.size();i++)
    {
        QLowEnergyCharacteristic tmp_char=chars.at(i);
        if(tmp_char.name()=="Heart Rate Measurement")//the code go in : **OK**
        {
            qDebug() << "carac value" << chars.at(i).value().toHex();//return a empty buffer : **NOK**

            //test by using a class with notify requerement : **NOK**
            // in THeartRateCharacteristic.h: Q_PROPERTY(QString characteristicValue READ getValue NOTIFY characteristicChanged)
            heart_rate_characteristic = new THeartRateCharacteristic(tmp_char);
            
            //test by using characteristicChanged : slot isn't call : **NOK**
            connect(heart_rate_characteristic, SIGNAL(characteristicChanged()), this, SLOT(heart_rate_update()));

            //try tu use readCharacteristic : the sensor doesn't answer **NOK**
            heart_rate_service->readCharacteristic(tmp_char);

            //Test to put notification flag to 1 : **heart rate data stay empty**
            for(int j=0;j<chars.at(i).descriptors().size();j++)
            {
                if(chars.at(i).descriptors().at(j).name()=="Client Characteristic Configuration")
                {
                    QByteArray tmp=chars.at(i).descriptors().at(j).value();
                    tmp[1]=0;
                    tmp[0]=1;
                    if(chars.at(i).descriptors().at(j).value().compare(tmp)!=0)
                    {
                        connect(heart_rate_service, &QLowEnergyService::descriptorWritten,this, &TWindowsStatistique::descriptorWritten_slot);
                        connect(heart_rate_service, SIGNAL(error(QLowEnergyService::ServiceError)),this, SLOT(service_error_slot(QLowEnergyService::ServiceError)));
                        heart_rate_service->writeDescriptor(chars.at(i).descriptors().at(j),tmp);
                    }
                }
            }

        }
    }
}



void TWindowsStatistique::timer_1s_timeout()
{
    if(heart_rate_characteristic)
    {
            qDebug() << "timer: data value:" << heart_rate_characteristic->getValue();//return a empty buffer : **NOK**
    }
}

Solution

  • I tested Qt sample project "Bluetooth Low Energy Heart Rate Game" with QT5.12 (MSVC 2017) => I stay in the waiting screem. I tested Qt sample project "Bluetooth Low Energy Heart Rate Game" with QT6.02 (MSVC 2019) => It's work.

    so I will continue my sowftware in 6.2 with MSVC 2019.

    @jpo38 : thank for you help