• Hi!

    I've had a look through the apps and examples, apologies if I missed it:

    I'm seeking an example of robustly maintaining a connection to a BLE device so we can receive characteristicvaluechanged events.

    I have this so far, but it lacks retrying everything, handling failures, and so on. I'm unfamiliar with JavaScript. If there's no off-the-shelf example of how to be robust, I'll give it a go and share back here...

    NRF.requestDevice({ filters: [{ namePrefix: 'XXXX' }] }).then(function(device) {
      console.log("Found");
      return device.gatt.connect();
    }).then(function(g) {
      console.log("Connected");
      gatt = g;
      return gatt.getPrimaryService(
        ".......");
    }).then(function(service) {
      console.log("Got Service");
      return service.getCharacteristic(
        "......");
    }).then(function (c) {
      console.log("Got Characteristic");
      characteristic = c;
      characteristic.on('characteristicvaluech­anged', function(event) {
        console.log("Got event");
        console.log(event.target.value.buffer);
        parseMessage(event.target.value.buffer);­
      });
      return characteristic.startNotifications();
    });
    
    
  • While I'm working on this, I've realised that the Bangle.js 1 I have often doesn't find the BLE device, yet my phone or laptop does find it.

      NRF.requestDevice({ timeout:4000,
                          active:true,
                          filters: [{ namePrefix: 'XXX_' }] 
    

    I added 'active' and a long 'timeout' to try have the best luck; but still very often (more times than not) I get:

    Error: No device found matching filters
    

    while my Android phone, or a JS app in Chrome on my laptop, discovers the device just fine.

    I see the nRF chip in Bangle 2 is different; might I have better luck with a Bangle 2?

  • I tried running the same code on the microbit v2, and it seems to notice the characteristicvaluechanged much faster and miss fewer of them.

    The bangle v2 isn't the same nRF chip as the microbit v2; but maybe this is also a clue to me that the bangle v1 nRF BLE isn't reliable for my purpose?

  • This is my code so far. I'm struggling to understand how to not lose context through the promises chain - the callback I register for characteristicvaluechanged has no idea which BLE device sent an update!

    function connect() {
      nrfbusy = true;
      NRF.requestDevice({ timeout:4000,
                          active:true,
                          filters: [{ namePrefix: NAME_PREFIX }] }).then(function(device) {
      console.log("Found");
      show(0b10);
      return device.gatt.connect({minInterval:7.5, 
                                  maxInterval:7.5});
      }).then(function(gatt) {
      console.log("Connected", gatt);
      show(0b100);
      return gatt.getPrimaryService(PRIMARY_SERVICE);­
    }).then(function(service) {
      show(0b1000);
      console.log("Got Service");
      return service.getCharacteristic(READ_CHARACTER­ISTIC);
    }).then(function (characteristic) {
      show(0b100000);
      console.log("Got Characteristic");
      device = 'button1'; // how can we find this from gatt, a few promises ago?
      characteristic.on('characteristicvaluech­anged', function(event) {
        parseMessage(device, event.target.value.buffer);
      });
      return characteristic.startNotifications();
    }).then(function() {
        nrfbusy = false;
    }).catch((error)=>{
        nrfbusy = false;
        console.log("Error: " + error);
        show("1   1\n"+
            " 1 1 \n"+
            "  1  \n"+
            " 1 1 \n"+
            "1   1\n");
    });
    }
    

    Additionally, when I try to connect to a second BLE device at the same time (e.g, run that connect() twice) I get ERR 0x12 (CONN_COUNT), so maybe the nrf52833 in the Microbit v2 can only connect to a single device at a time? Although https://devzone.nordicsemi.com/f/nordic-­q-a/35158/how-many-connections-nrf52840-­nrf52832-supports-as-peripheral suggests 20.

  • I've just spotted in http://forum.espruino.com/conversations/­297460/ a mention that "connection multiple peripherals at the same time is not possible atm," - is that still true in 2v13.158 ? (Edit: I think this is https://github.com/espruino/Espruino/iss­ues/1360 , so still not possible)

  • Hi! I'm just going to move this to the Bluetooth section of the forum - I think it makes more sense there...

    I've realised that the Bangle.js 1 I have often doesn't find the BLE device

    Were you connected to Blueooth to the Bangle at the time you did this? Because usually when you're connected you're in high speed mode so sending packets to the Bangle every 7.5ms - this makes it hard for it to scan for advertisements as reliably because

    connection multiple peripherals at the same time is not possible

    Yes. You can have one connection IN and one connection OUT at the same time, but that's it.

    the callback I register for characteristicvaluechanged has no idea which BLE device

    Just define a variable in the connect function, like:

    function connect() {
      nrfbusy = true;
      var mydevice;
      NRF.requestDevice({ timeout:4000,
                          active:true,
                          filters: [{ namePrefix: NAME_PREFIX }] }).then(function(device) {
      console.log("Found");
      mydevice = device;
      // ...
    

    I'm seeking an example of robustly maintaining a connection to a BLE device

    When you first get the device, register device.on('gattserverdisconnected', ...) and that should help you detect when the connection fails, and hopefully do a reconnect (wait ~1 sec first just in case)

  • Many thanks @Gordon, all very useful information, very kind of you!

    Yes I am working while connected to the Bangle in the IDE, to be able to see the console. I might compare without that - but, actually for my current requirement not being able to connect to several peripherals at once is a blocker, so I'll have to switch to C or micro/circuit python I think!

  • Actually, a few people were asking for this so I thought I'd give it a stab.

    There's now a branch here: https://github.com/espruino/Espruino/tre­e/nrf52_multiple_central

    Although it's not enabled yet - CENTRAL_LINK_COUNT needs to be set to 2 and you need to adjust the RAM (LD_APP_RAM_BASE) to make room for the extra connection

  • Multiple connections at once (2 central, 1 peripheral) and now supported on cutting edge builds for MDBT42Q, Pixl.js and Puck.js

    Potentially higher connection numbers can be handled but each time you add the options of a connection it lowers the available RAM, so if you need extra we'd have to do a special build

  • Oh, cool, many thanks, will test it. I wonder how it deals with possibly different MTU negotiated with each device.

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

Example of robustly subscribing to BLE gatt characteristicvaluechanged

Posted by Avatar for user145265 @user145265

Actions