Puck to Puck Communication - Some Errors

Posted on
  • I tweaked some puck example code from various places to make a remote button for a puck. A silly use case but a chance to try out connecting to a puck. This is the target device. A button press turns the blinking on and off and changes the color.

    var on = false;
    var stop = 0;
    var c = 1;
    function startBlink() {
      on = false;
      if (stop !== 0) {
        clearInterval(stop); stop = 0;
        LED1.write(0); LED2.write(0); LED3.write(0);
      }
      else {
        switch (c) {
          case 1:
            led = LED1; //print("red");
            c = 2;
            break;
          case 2:
            led = LED2; //print("green");
            c = 3;
            break;
          case 3:
            led = LED3; //print("blue");
            c = 1;
            break;
        }
        stop = setInterval(function() {
          on = !on;
          led.write(on);
        }, 500);
      }
    }
    setWatch(startBlink, BTN, { repeat:true, edge:'rising', debounce : 20 });
    
    

    And this is the remote button code. It will try and connect to the target and issue a command that simulates pressing the button.

    
    function flashLed(led) {
      flashLed.count = 0;
      flashLed.h = setInterval(function() {
        if (flashLed.count++ == 6) {
          led.write(0);
          clearInterval(flashLed.h);
          flashLed.count = 0;
        }
        else {
          led.write(flashLed.on = !flashLed.on);
        }
      }, 500);
    }
    
    function sendCmd() {
      var name = "Puck.js d958"; // change me to your target puck's name
      var gatt = null;
      console.log("searching for " + name);
      NRF.requestDevice(
        {
          filters: [
            { namePrefix: name }
            //{ namePrefix: 'EspruinoHub' }
          ]
        }
      ).then(function(dev) {
          console.log("device found", dev);
          return dev.gatt.connect();
        }
      ).then(function(conn) {
          gatt = conn;
          console.log("connected", conn);
          return conn.getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
        }
      ).then(function(s) {
          console.log("service found", s);
          return s.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
        }
      ).then(function(c) {
          console.log("characteristic found", c);
          c.writeValue("startBlink()\n");
        }
      ).then(function() {
          gatt.disconnect();
          console.log("disconnected");
        }
      ).then(function() {
          console.log("success!");
          flashLed(LED2);
        }
      ).catch(function(e) {
          console.log( "catch caught an error!");
          console.log( "error:", e );
          if (gatt !== null) {
            gatt.disconnect();
            console.log("disconnected");
          }
          flashLed(LED1);
          console.log("all done");
        }
      ).catch(function(e) {
          console.log( "catch caught another error!");
          console.log( "error:", e );
          flashLed(LED1);
          console.log("all done");
        }
      );
    }
    setWatch(sendCmd, "D0", { repeat:true, edge:'rising', debounce : 50 });
    
    

    It works about half the time. But very often I get the following error output. I have tried to look up the BLE error code but I can't find anything on it.

    searching for Puck.js d958
    device found BluetoothDevice {
      "id": "ca:78:ab:df:d9:58 random",
      "rssi": -57,
      "services": [  ],
      "data": new ArrayBuffer([2, 1, 5, 13, 9, 80, 117, 99, 107, 46, 106, 115, 32, 100, 57, 53, 56]),
      "name": "Puck.js d958"
     }
    connected BluetoothRemoteGATTServer {
      "device": BluetoothDevice {
        "id": "ca:78:ab:df:d9:58 random",
        "rssi": -57,
        "services": [  ],
        "data": new ArrayBuffer([2, 1, 5, 13, 9, 80, 117, 99, 107, 46, 106, 115, 32, 100, 57, 53, 56]),
        "name": "Puck.js d958",
        "gatt":  ...
       },
      "connected": true }
    catch caught an error!
    error: Error {
      "msg": "Got BLE error code 12290",
      "type": "Error",
      "stack": " at line 35 col 75\n...5a3-f393-e0a9-e50e24dcca9e\");\n                              ^\nin function called from system\n"
     }
    catch caught another error!
    error: Error {
      "msg": "Got BLE error code 8",
      "type": "Error",
      "stack": " at line 57 col 25\n        gatt.disconnect();\n                        ^\nin function called from system\n"
     }
    all done
    > 
    

    This is the interesting bit:

    error: Error {
    "msg": "Got BLE error code 12290",
    "type": "Error",
    "stack": " at line 35 col 75\n...5a3-f393-e0a9-e50e24dcca9e\");\n ^\nin function called from system\n"

    The puck appears to connect ok but then it looks like the code blows up attempting to get the service. Like I said this happens about half the time. When it works properly it works very well.

    Clearly I am not doing something entirely right here. Any thoughts would be appreciated.

  • Are you using the 1v90 firmware (or even better, the one I posted up in response to the issues with uncaught promises) on both devices?

    What you've done looks good...

    I've never seen error code 12290 before though! All I can think is that perhaps the connection broke down before the service could be found.

    ... and I just looked it up (nRF errors can be tricky to find, but it's BLE_ERROR_INVALID_CONN_HANDLE)... So it seems like that's likely the problem - the connection broke down while the services were being scanned. It also explains why the disconnect failed.

    The BLE communications aren't totally reliable, so you have to expect that things will fail occasionally - however 1 in 2 times does seem a bit high.

    Does it work more reliably when you're not connected to the first Puck with your PC? It's possible that all the communications between it in the PC (~50 packets per second) are making it less able to communicate with the other Puck.

  • Yes I should have mentioned that 1v90.5 is running on the 'remote button' puck and 1v90 on the target.

    I'll have to try and characterize results when connected from the IDE and not. I'm trying several examples including 'ble_simple_uart' and results aren't much different.

    I've also seen situations where the 'get service' simply doesn't return. Re-entering the function causes an error saying a BLE request is in progress or something like that. At this point I have to do a reset() and load() to recover.

  • I've also seen situations where the 'get service' simply doesn't return

    Argh, that's not good. Looks like it's caused by a disconnection in the middle of requesting services. I've uploaded a new firmware below that may help, and I checked it out by moving the Pucks apart until their radio signals got really intermittent.

    Hopefully that'll fix a lot of your problems.


    1 Attachment

  • The firmware works and it cleans up the error reporting, but doesn't seem to improve my results very much. I wrapped a 30 second interval and some counters around the remote button code and let it run for awhile. Consistently the success rate is 59% to 65%. It's about the same whether or not the IDE is connected. I also noticed that after awhile, the remote button Puck stops transmitting entirely and I have to pop the battery to get it restarted. So maybe something in the code doesn't like being executed every 30 seconds. In any case I'll fiddle around with it for the next few weeks. Happy holidays!

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

Puck to Puck Communication - Some Errors

Posted by Avatar for dklinkman @dklinkman

Actions