Problem reading BLE Characteristic value

Hi,

I'm trying to read the value from a Characteristic with getValue(), but it is not working.

I provide here a minimum working example of the problem, where I write the value to the characteristic, and then try to read it. connectTime is the time when the central connects:

void BLESetupClass::loop() {   

    // Check if someone subscribed to the salt characteristic
    if (millis() - connectTime > 100 && millis() - connectTime < 1000) {
        connectTime -= 1000;
        
        
        uint8_t currentSalt[4] = {0x00, 0x00, 0x04, 0x08};             
        // Write the new salt to the characteristic so we have something to read
        currentSalt[0] = 0x10;
        saltCharacteristic.setValue(currentSalt, 4);
        // Set to a different value so we can see if it changes
        currentSalt[0] = 0x20;
        ssize_t retVal = saltCharacteristic.getValue(currentSalt, 4);
        // Set the value, we will see if 0x10 was read, it works, if 0x20 was read, it doesn't work
        saltCharacteristic.setValue(currentSalt, 4);
        Log.info("Salt Notified: %02X%02X%02X%02X", currentSalt[0], currentSalt[1], currentSalt[2], currentSalt[3]);
        // Lets also check if it returned the expected 4 bytes
        Log.info("Salt Retval: %d", retVal);
        

    }
    
}

The output I'm getting is this:

0000004640 [app] INFO: Connected to 58:C1:D7:A7:50:C5
0000004640 [wiring.ble] TRACE: Connected
0000004641 [app] INFO: Salt Notified: 20000408
0000004641 [app] INFO: Salt Retval: 0

Where you can see that the return value is 0 (nothing was read) and the notified value is the 0x20 (on the first byte) that is the original value of the currentSalt variable. Everything indicates that nothing was read and I have no clue why.

With nrfConnect, I can see that the value is indeed being written correctly, so it's strange that it can't be read.

Does anyone know what is going on?

Thanks!
Pedro

What's the configuration of the characteristic on the other end?

In general, BLE characteristics are one-way. In order to both write and read a characteristic, you typically create two different characteristics. See the BLE UART example.

1 Like

The Characteristic is configured as NOTIFY, and this is a peripheral device.

My question is; what does the getValue function do? In the docs it says that you can use it to read the value of a Characteristic. But it's not working as you can see from the code that I posted.

Is it working only on some specific cases? am I doing something wrong? If this function doesn't work for NOTIFY Characteristics for example, it would be really nice that the documentation was a bit more clear about that.

Since I'm not able to get the expected behaviour from the getValue function, what I'm doing is that I'm storing the value for the Characteristic externally in a variable so I can call setValue with the same value to send a notification for a central that missed the previous notification because it wasn't connected. This is unnecessary if I could get the docuemented behaviour from getValue and I don't know if this is something I should do for all Characteristics that I want to be able to read, or if I'm just doing something wrong.

From the peripheral getValue does a read to the central. It will not get the last notify. You really do need to use your workaround.

1 Like

OK, yes, that explains the behaviour I'm seeing thanks!

I would suggest to clarify this in the documentation, IMO it's not obvious.