Unable to subscribe to notifications from Arduino GATT server

I have an app running on a Fenix 6x that subscribes to BLE notify characteristics (using code like `characteristic.getDescriptor(Ble.cccdUuid()).requestWrite([0x1,0x0]b);`). Whenever I try this while connected to the Arduino hardware, one of two things happens:

1. `getDescriptor(Ble.cccdUuid())` returns null, even though it’s registered in the profile and the Arduino characteristic definitely has it.

2. `onDescriptorWrite` is called with status `STATUS_WRITE_FAIL`

and obviously notifications are never received.

Notifications work perfectly between the connect IQ app and an nRF Connect GATT server, and also between the Arduino and an nRF Connect client. It’s just the combination of connect IQ app and Arduino that doesn’t seem to work.

I’m using SDK 3.2.2. All BLE operations are in a queue. I’d really appreciate any help here, we’d much prefer to use notifications as the BLE reads are so slow.

  • Here's the basics of how I turn on notify.  There's a queue involved, and what I typically do is turn on notify and do a read at the same time, as with some characteristics, notifications may only be every few seconds.  Are you doing something similar when you may be trying to turn on notify while a read is still in progress? (maybe a bug in your queuing?)

    And you're not doing this until after onConnectedStateChanged with a state of CONNECTION_STATE_CONNECTED? 

    var char = (service!=null) ? service.getCharacteristic(profileManager.HR_CHAR) : null;
    
    if(char!=null) {
      var cccd = char.getDescriptor(Ble.cccdUuid());
      cccd.requestWrite([0x01,0x00]b);
    } else {
      System.println("char is null");
    }

    And your profile looks something like:

        private var hrProfileDef = {
            :uuid => HR_SERVICE,
            :characteristics => [{
                :uuid => HR_CHAR,
                :descriptors => [Ble.cccdUuid()]
            }]
        };

  • Yes, I’m turning on notify after I receive `CONNECTION_STATE_CONNECTED`. I’m not doing any reads of the notify characteristics currently. If I disable turning on notify I can issue regular characteristic read & write requests no problem. Logging shows no concurrent requests from the queue.

    Notify works fine with the nRF Connect server, but not with an Arduino. I saw someone else complaining about this problem in a different thread, I’m hoping it’s a known issue and/or there’s a workaround.

  • can you do any debugging on the Arduino end?

    I use notify in most of my apps and for multiple characteristics, from different senors and things like raspberry pi devices with no issue, as long as the characteristic supports notify.

    Are you doing anything like checking RSSI to make sure you're seeing a strong enough signal?  I've seen issues where the RSSI is too low and things can get flaky (I usually check for a minimum RSSI in the scan result before trying to pair.)

  • Not really - I’m not the Arduino dev, but I sat down with him and all we can see is the initial connection and that's it - no subscription is ever registered.

    Have you managed to use notify with an Arduino before, or know of anyone who has?

    I’m not checking RSSI (range is about 10cm) - I’ll do it next time I have access to the hardware - but it doesn’t seem to be flakiness given connect/read/write always succeeds and enabling notify always fails.

  • I've never used an Arduino, but I know others here have done apps with it.

    Are you sure your BLE in your app is correct?  Unlike something like nRFConnect, everything must be hard coded, as nothing is learned over the connection.  Above I posted one I use with a BLE HRM where I use notify.

    10 cm shouldn't be an RSSI issue, but if it was a few meters, maybe.

  • Correct as in all the UUIDs are right? I’ve double-checked them, and I can read/write the characteristics okay. I definitely have the CCCD UUID descriptor on all the characteristics. I’ll go get my own hardware tomorrow and see if I can reproduce with a fresh project.

  • Okay, the Nano 33 BLE has finally arrived and I’ve managed to reproduce with a minimal project. All it does is connect then attempt to write to the CCCD. The descriptor (returned by `characteristic.getDescriptor(Ble.cccdUuid())`) is always null. If I try to iterate through the descriptors for that characteristic I get no results. The CCCD UUID is definitely registered as a descriptor in the profile. Notifications work fine between the Nano and nRF connect.

    To clarify, this is a problem with an ArduinoBLE GATT server running on onboard-BLE devices like the Nano BLE, I can get at the client config descriptor using an old AVR arduino with the HM10 serial BLE module.

    I’m fairly confident there’s nothing here that I’m doing wrong & there’s some sort of incompatibility at the BLE stack level. I’d appreciate any guidance on how take this further.

  • I'm really not sure what to tell you, as I've had no problems with notify with different CIQ apps and different sensors.

    When I started using BLE, I used the sample app in the SDK along with a thingy52, wrote my one interface it it, etc, just to make sure I understood how to do things, wrote apps for the pi, and others for things like a BLE HRM.

    Maybe if you got a hold of a thingy, and use it to modify your app to get something like the temperature value, you'll find something (temperature on a thingy is only available with a notify.)

  • Hmm, I don’t know how a thingy would help - I can get notify working between the fenix & other devices, the issue is just with the Nano/ArduinoBLE. My best guess is it’s a format or parsing issue at one or both ends - I got as far as logging Bluetooth packets to see if I could spot differences, but honestly I’m well out of my depth there.

    My testing shows the same issue with custom descriptors, not just the CCCD, although interestingly *sometimes* if there are two descriptors on the characteristic one or the other will be accessible, however writes to it will always fail with STATUS_WRITE_FAIL.

    Unfortunately we’re just going to have to push on without notifications on this project. It’s super annoying as my client says this is the hardware Garmin recommended they use.

  • How much data is being sent with a notify?  The same amount as with a read or more?

    There's a limit on the CIQ side about how much data can receive and it's fairly small. (<30 bytes)