5 years, 12 months ago.

Can't quite get BLE working

Having one interesting problems with BLE, and it's likely I just don't get it yet, but still.

I've played around with the various sBLE example programs, and the modified one in hopes it would do what I wanted, but so far not yet.

I have an I2C CO2 sensor that I'd like to read via BLE. Here's my BLE service:

CO2 Sensor Service

#ifndef __K30_SERVICE_H__
#define __K30_SERVICE_H__
 
class K30Service {
public:
    const static uint16_t K30_SERVICE_UUID              = 0xA000;
    const static uint16_t K30_VALUE_CHARACTERISTIC_UUID = 0xA001;
 
    K30Service(BLEDevice &_ble, long k30Initial) :
        ble(_ble), k30Value(K30_VALUE_CHARACTERISTIC_UUID, &k30Initial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
    {
        GattCharacteristic *charTable[] = {&k30Value};
        GattService         k30Service(K30Service::K30_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
        ble.addService(k30Service);
    }
 
    void updateK30Value(long newValue) {
        ble.updateCharacteristicValue(k30Value.getValueHandle(), (uint8_t *)&newValue, sizeof(long));
    }
 
private:
    BLEDevice                        &ble;
    ReadOnlyGattCharacteristic<long>  k30Value;
};
 
#endif /* #ifndef __K30_SERVICE_H__ */

And I initialize it:

void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE&        ble   = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        /* In case of error, forward the error handling to onBleInitError */
        onBleInitError(ble, error);
        return;
    }
    /* Ensure that it is the default instance of BLE */
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
       return;
    }
    /* Setup primary service. */
    k30ServicePtr = new K30Service(ble, currentReading);

    /* setup advertising */
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingInterval(1000); /* 1000ms */
    ble.gap().startAdvertising();   
    ble.gap().onDisconnection(disconnectionCallback);
}

And BLE does, indeed come up, and it is discoverable. The BLE scanner I use says there is one service, but when I connect to the NRF52 device, there are no services that I can see, and I can't red the value characteristic. In addition, when I disconnect from the device, the onDisconnection() callback is never called.

Finally, in my main() loop:

while (true) {
        if ( ble.gap().getState().connected) {
            pc.printf("Connected, reading ... \n");
            readSensor();
            k30ServicePtr->updateK30Value(currentReading);
        } else {
            wait(2);
        }
    }

I *never* see the "Connected, reading ..." message, and the value is never updated.

What am I missing here?

TIA, dg

Be the first to answer this question.