SLOT is not executed after successfully contected to BLE-Device



  • Hello,

    I am writing a simple desktop application to find and connect to a bluetooth low energy device.
    With the code you see below I could discover and connect to a blueetooth low energy device. After the succesfull connection I would like to print all the services of my device. Therefore I wrote a Slot connectionSuccessfull. However it seems that this function is not executed at all, but the connect Function returns "true", when I print the return type.
    It only worked once when I started the code in debug mode. But then it did not work in debug mode either.
    Bzw: I know that the connection is successful because a LED turn on at my ble device.

    const QBluetoothUuid adafruitServiceUuid = (QUuid("6e400001-b5a3-f393-e0a9-e50e24dcca9e"));
    
    void Scanner::startDeviceDiscovery(){
    
        discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
        discoveryAgent->setLowEnergyDiscoveryTimeout(5000);
        discoveryAgent->start();
    
        connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &Scanner::deviceDiscovered);
        connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &Scanner::doConnect);
    
    }
    
    
    void Scanner::deviceDiscovered(const QBluetoothDeviceInfo &device)
    {
        qDebug() << "Found new device:" << device.name();
    }
    
    void Scanner::doConnect(){
        cout << "\nPlease enter the number of your device: ";
        int listNumber;
        cin >> listNumber;
    
        deviceList = discoveryAgent->discoveredDevices();
        adafruit = &deviceList[listNumber];
        qDebug() << "The element that you chose is: " + adafruit->name();
    
    
        controller = QLowEnergyController::createCentral(*adafruit);
        controller->connectToDevice();
        connect(controller, &QLowEnergyController::connected, this, &Scanner::connectionSuccessful);
    
    }
    
    
    void Scanner::connectionSuccessful(){
    
        qDebug()<<"succesfully connected";
        controller->discoverServices();
        QLowEnergyService *service = controller->createServiceObject(adafruitServiceUuid);
        const QList<QLowEnergyCharacteristic> characteristics = service->characteristics();
        for (const QLowEnergyCharacteristic &ch : characteristics) {
            qDebug() << ch.name();
        }
    
    }
    
    


  • @SpaceToon said in SLOT is not executed after successfully contected to BLE-Device:

    controller->connectToDevice();
    connect(controller, &QLowEnergyController::connected, this, &Scanner::connectionSuccessful);
    

    I don't really understand what it is you see or don't see. (Presumably you know whether it does indeed read an element number from stdin.) However, assuming controller->connectToDevice(); does the device connection, then you must not set your connected signal-->slot handler after the line where it connects, that's too late! You must always connect signals/slots on an object before any call which could raise a signal. Swap the order of these two lines, does your slot get called?


  • Lifetime Qt Champion

    @SpaceToon said in SLOT is not executed after successfully contected to BLE-Device:

    int listNumber;
    cin >> listNumber;
    

    What do you expect these lines to do in an UI program?

    Regards



  • @aha_1980 said in SLOT is not executed after successfully contected to BLE-Device:

    @SpaceToon said in SLOT is not executed after successfully contected to BLE-Device:

    int listNumber;
    cin >> listNumber;
    

    What do you expect these lines to do in an UI program?

    Regards

    Hello aha,

    this is just a console application. The devices are printed from a list to the console, and the user can enter a number (the list element of the device he/she wants to connect to), then this paritcular device is saved in the adafruit variable

    adafruit = &deviceList[listNumber];
    

    It's just a temporary solution to see how Bluetooth Low Energy works in Qt. After I understand all this I will create a real application with GUI. As I mentioned, the connection is established successfully, however the slot connectionSuccessful() is not executed.


  • Lifetime Qt Champion

    Hi @SpaceToon,

    then make sure this program runs in a terminal, not in Creators Application Output, which has no input capabilities.

    If you still encounter problems, you will need to share more code, otherwise we cannot tell you where the problem is.

    Regards



  • @SpaceToon said in SLOT is not executed after successfully contected to BLE-Device:

    controller->connectToDevice();
    connect(controller, &QLowEnergyController::connected, this, &Scanner::connectionSuccessful);
    

    I don't really understand what it is you see or don't see. (Presumably you know whether it does indeed read an element number from stdin.) However, assuming controller->connectToDevice(); does the device connection, then you must not set your connected signal-->slot handler after the line where it connects, that's too late! You must always connect signals/slots on an object before any call which could raise a signal. Swap the order of these two lines, does your slot get called?


  • Moderators

    @SpaceToon said in SLOT is not executed after successfully contected to BLE-Device:

    ontroller->discoverServices();

    additionally to what @aha_1980 and @JonB said, the discoverServices call is asynchronous and you'll have to listen to the QLowEnergyController::serviceDiscovered signal before you can print them.

    This can't work:

    void Scanner::connectionSuccessful(){
    
        qDebug()<<"succesfully connected";
        controller->discoverServices();
        QLowEnergyService *service = controller->createServiceObject(adafruitServiceUuid);
        const QList<QLowEnergyCharacteristic> characteristics = service->characteristics();
        for (const QLowEnergyCharacteristic &ch : characteristics) {
            qDebug() << ch.name();
        }
    
    }
    

    That said, you do know, that Qt offers a ready to compile BTLE Scanner example, that prints out (Gui form) all services & characteristics of BTLE devices ?

    https://doc.qt.io/qt-5/qtbluetooth-lowenergyscanner-example.html



  • @J-Hilk Thank you, JonB and you were right. For me it actually makes more sense that e.g. at first you connect to the device and then you say "okay, if the signal "connected" is emitted then call the function x.y.". So after changing it, it works now. However, after getting all services and calling "service->discoverDetails" and then "service->characteristics" the characteristics List is empty.

    After connection is successfull:

    void Scanner::startServiceDiscovery(){
        connect(controller, &QLowEnergyController::discoveryFinished, this, &Scanner::discoveryFinished);
        controller->discoverServices();
    }
    
    
    void Scanner::discoveryFinished(){
        qDebug() << "\nService Discovery finished. Following Services found:\n";
        QList<QBluetoothUuid> serviceList = controller->services();
    
        for(QBluetoothUuid &sl : serviceList){
            qDebug() <<  controller->createServiceObject(sl)->serviceName() << "Uuid: " << sl;
        }
    
        uartService = controller->createServiceObject(adafruitServiceUuid);
    
        qDebug() <<"\nChose the following service: " << (*uartService).serviceName();
        
        connect(uartService, &QLowEnergyService::stateChanged, this, &Scanner::printChars);
        qDebug() << uartService->state(); //here the state is QLowEnergyService::DiscoveryRequired
        uartService->discoverDetails(); 
    }
    
    
    void Scanner::printChars(){
    
        qDebug() << uartService->state(); // here the state is now QLowEnergyService::DiscoveringServices
        
    
        const QList<QLowEnergyCharacteristic> chars = uartService->characteristics();
        qDebug()<< chars.size(); //however the list size is 0
        for (const QLowEnergyCharacteristic &ch : chars) {
            qDebug() << &ch;
        }
    }
    
    

    btw: I know that there is an example for BLE Scanner. But for a project, I want to create an own desktop application which connnects to a peripheral and live plots the data which are received from the sensor with qcustomplot. So I need a QWidget Application because QCustomPlot is a widget...