Unable to run BLE GATT service on Nordic Thingy 52

Posted on
  • I can't get Thingy to provide a GATT service. After reading everything I could find online, I still have no idea what I could be doing wrong.

    Advertising work fine, I can see the 0x180D service in the advertisement (I'm using NRFconnect on iOS to check, but have the same effect with other tools as well).

    But when I connect only the standard UART RX and TX services are visible. Nothing else.

    The code below is taken from another stream and appeared to work on a Ruuvitag. (I've tried various versions, but without any change in effect).


    NRF.setServices({
      0x180D: { // heart_rate
        0x2A6E: { // heart_rate_measurement
          notify: true,
          readable: true,
          value : [0]
        }
      }
    }, { advertise: [0x180D], uart: false });
    
    
    var cnt = 0;
    
    setWatch(function() {
      if(cnt++ % 2 === 0)
        LED1.set();
      else
        LED1.reset();
      NRF.updateServices({
        0x180D : {
          0x2A6E : {
            value : [cnt],
            notify: true
          }
        }
      });
    }, BTN, { repeat:true, edge:"rising", debounce: 50 });
    

    The LED toggles just fine, so obviously the function gets called.

    And, yes, I do disconnect the Web Bluetooth IDE from Thingy before I check the services.

    Any help would be much appreciated!
    Thanks,

    Bernd

  • I'm using NRFconnect on iOS to check

    I'm afraid it's just a 'features' of iOS. The phone expects that the services advertised by the Thingy haven't changed and it doesn't bother scanning again - and because it's an Apple device, it knows best and doesn't allow NRF connect to ask it to re-scan.

    IMO NRF connect on iOS should come with a massive disclaimer about that as it seems to be a common source of pain.

    I bet if you tried on an Android phone it'd show the services just fine.

    I think if you turned Bluetooth off and back on - and definitely if you restarted the phone - it would show the services too.

  • Oh, great. Thanks for the quick response. Switching Bluetooth on and off actually solved the problem!

    I found a note in the meantime that the Bluetooth SIG requires a service 0x1801: { // generic attribute service with charactersitic 0x2A05: { // service changed characteristic to be present (and I assume with value true) if the services on a device can change.

    I tried to set this, as part of my code using

    NRF.setServices({
      0x1801: { // generic attribute service
        0x2A05: { // service changed characteristic
          notify: true,
          readable: true,
          value : [true]
        }
      }
    });
    

    but this didn't produce any effect. I suppose at that point it's already too late? Would it be possible to put that into the default profile?

  • As I understand it, that characteristic is for when the iPhone is actually connected to Espruino.

    The issue is that you can only dynamically add services to the nRF52. To remove/change a service Espruino has to restart the whole Bluetooth stack behind the scenes, which can't be done with an active connection... And if there's no connection then the iPhone isn't watching that service for a notification so it doesn't know anything has changed.

    At the end of the day I think the only option is really to just toggle Bluetooth on your iPhone. After all, this is only something that's likely to happen one or twice during development. Usually you keep the same characteristics around on a device all the time.

    If you're doing loads of development where it becomes a real pain, you could always buy a cheap Android phone ;)

  • thanks, Gordon.
    I actually have a few old Androids lying around. Maybe I'll try that.

    On a related matter: I need to transfer larger amounts of data via the BLE connection (offline data logging). From studying the web resources, the normal approach (see here) appears to sequentially write to a characteristic, exploiting the events / exceptions

    BLE_ERROR_NO_TX_BUFFERS and
    BLE_EVT_TX_COMPLETE

    These don't seem to be exposed in the NRF library. What do you recommend? (I think I could exploit the UART interface, but I would like to be able to implement the same protocol on non-Espruino devices later so that I don't have to change the central side).

    Thanks!

  • Well, I believe you can write to a characteristic and use try...catch to see if you get an error, but there's no TX_COMPLETE event.

    I'd say for maximum speed, use the UART interface as that does handle those events correctly. Even so I've actually had to reduce the amount of transmits that can be done on each connection interval as it's not reliable on some platforms.

    There's nothing proprietary about the UART (far from it, it's a spec that Nordic themselves defined) so nothing stops you implementing it on a non-Espruino device later.

  • That’s good to hear. In that case it’s probably better to use the UART. Thanks!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Unable to run BLE GATT service on Nordic Thingy 52

Posted by Avatar for Bernd @Bernd

Actions