NRF multiple connections?

Posted on
  • Having 5 pucks at hand I'd like to do some round-robin communication:

    • request a list of available pucks around me (works)
    • iterate through the list (issue A below)
    • receive feedback during the UART connection (issue B below)

    I am aware, that connection multiple peripherals at the same time is not possible atm, so I do it sequentially (with recursive callbacks).

    This is my connection code:

    function transfer(device, text, callback) {
      var char;
      var result = "";
      console.log( "connecting " + device.name );
      return device.gatt.connect().then(function(d) {
        device = d;
        console.log( "connected" );
        return d.getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
      }).then(function(s) {
        console.log( "service found" );
        return s.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
      }).then(function(c) {
        char = c;
        console.log( "characteristic found" );
        function sender(resolve, reject) {
          console.log( "sending" );
          if (text.length) {
            char.writeValue(text.substr(0,20)).then(function() {
              sender(resolve, reject);
            }).catch(reject);
            text = text.substr(20);
          } else  {
            resolve();
          }
        }
        return new Promise( sender );
    /* 
       }).then(function() {
        function receiver(resolve, reject) {
          console.log( "receiving" );
          char.readValue().then(function(chunk) {
            console.log(chunk);
            if( chunk.length > 0 ) {
              result += chunk;
              receiver(resolve, reject);
            }
            else {
              resolve();
            }
          }).catch(reject);
        }
        return new Promise( receiver ); */
      }).then(function() {
        device.disconnect();
        if (callback) callback(result);
      });
    }
    

    Issue A:
    As long as I disable (/**/) the receiving part I can pass commands to the first puck successfully.
    But when I try to connect the second one I get BLE error 18 - why?

    found Puck.js f002
    found Puck.js 38a4
    found Puck.js c9fc
    connecting Puck.js c9fc
    connected
    service found
    characteristic found
    sending
    sending
    done
    connecting Puck.js 38a4
    Uncaught Error: Unhandled promise rejection: Error: Got BLE error code 18

    Question: What does that mean and what can I do about it?

    Issue B:
    I also like to get the feedback of the command sent to the pucks.
    So I tried to add the receiver part (in comments) but it always receives the echo of the data I just sent.

    Question: How can I get the full response and how do I detect the end of a transmission?

    I'll upload the full sourcecode as attachment so you have the complete picture.

    Thanks in advance,
    Christian


    1 Attachment

  • Try adding a delay between disconnecting from one puck and connecting to the other. Disconnect starts a disconnect but it takes some time to complete, and the web Bluetooth spec doesn't seem to remove a return a promise.

    Unfortunately notifications aren't implemented yet, so you can't get the result. It'll be in a firmware update in the new year though

  • Thanks again, Gordon.

    Adding the timeout solved it:

    scan( function( queue ) {
        // recurse through queue
        function process() {
          if( queue.length ) {
              transfer( queue.pop(), command, function( result ) {
                console.log( "done" );
                setTimeout( process, 150 );
              });
          }
        }
        process();
      });
    

    150 ms seems sufficient.
    I was able to go down to about 145 ms, but everything below still caused some errors.

    I'm very thrilled to get the notifications.
    Good work - keep it up!

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

NRF multiple connections?

Posted by Avatar for ChristianW @ChristianW

Actions