BLE Connection problems + questions

Posted on
  • Hi,

    I have a problem that when connecting two Pucks together using BLE, there seems to be some sort of timeout going on which I did not program. I am using 1v91.

    I have a central and a peripheral Puck. Here is the code for the peripheral, which is pretty vanilla:

    var g_value = 0;
    
    function onInit() {
      NRF.setServices({
        "A4AF09E7-5BC2-46F6-BA08-DA8E0982D84D" :
        {
          0x2A6E:
          {
            readable: true,
            writable: true,
            notify: true,
            value : g_value,
            onWrite : function(evt)
            {
              digitalPulse(LED2, true, 10);
              g_value = evt.data[0];
            }
        }}});
    }
    

    Here is the code for the central:

    var g_gatt = false;
    var g_characteristic = false;
    var g_counter = 0;
    
    function connect(nextStep) {
        console.log("Requesting device");
        NRF.requestDevice({
            filters: [{
                name: 'Puck.js 2061'
            }]
        }).then(function(device) {
            console.log("Connecting to GATT");
            return device.gatt.connect();
        }).then(function(gatt) {
            console.log("Connecting to service");
            g_gatt = gatt;
            return g_gatt.getPrimaryService("A4AF09E7-5BC2-­46F6-BA08-DA8E0982D84D");
        }).then(function(service) {
            console.log("Getting characteristic");
            return service.getCharacteristic("0x2A6E");
        }).then(function(characteristic) {
            console.log("Calling next step");
            g_characteristic = characteristic;
            nextStep();
        }).catch(function() {
            console.log("Error connecting");
        });
    }
    
    function write(value) {
        if (!g_characteristic)
            connect(function() {
                write(value);
            });
        else
        {
            console.log("Writing ", value);
            g_characteristic.writeValue(value).catch­(function() {
                g_characteristic = false;
                write(value);
            });
        }
    }
    
    function onInit() {
        setWatch(function() {
            write(g_counter++);
        }, BTN, {
            edge: "rising",
            debounce: 50,
            repeat: true
        });
    }
    

    Again, nothing special. So when I first press the button on the central, it will connect to the peripheral and write the value. The peripheral will shortly blink green. Connecting of course takes a while, but subsequent writes will be fast. So far so good.

    The problem is that after letting the Pucks rest for a while, the write will fail. Then the catch will come into play and reconnect. So there seems to be some kind of inactivity timeout somewhere. I did not find any documentation for that or any hint how I can avoid that. Any ideas?

    The question is if there is a better way to send integers (preferably not just 8 bits) than sending them as a character and reconverting to an integer? Also, the way I handle the !g_characteristic case feels pretty clumsy. Any better idea on how to handle that? Generally, any hint on how to program the central more elegant is welcome.

    Thanks!

  • How long does it take to time out? and does it time out if it's not inactive (it's writing every few seconds)?

    If it does it repeatedly after some time there may be some issue I have to fix - but realistically the connection will drop at some point, so you need to be able to deal with it in your code.

    For writing, you're stuck with converting to bytes really. I believe you can do:

    value =  new Uint32Array([my_int]).buffer
    

    which will create a 4 element array from a 32 bit int (works with Float32,Float64,Int16,etc as well) - and then you can reconstruct that on the other side.

    You could send the integer just as a string, but you're then sending more data than you really need to.

    With !g_characteristic I wouldn't have said it was too bad. You could return the promise from connect though, and if you moved the catch outside connect then you could deal with the error there?

    Also, if you store the device I think you can check device.gatt.connected to see if the connection has dropped?

    Perhaps an option here is for me to provide some module that handles persistent connections?

  • Hi @Gordon, thanks for your answers!

    I think the timeout is around 2 minutes. It happens whether I write from time to time or not.

    I am pretty sure that the problem is that the connection breaks down: I checked from the iPhone with LightBlue and saw the peripheral Puck listed there after a while. And I was also able to connect to it from LightBlue. I think that is evidence that the connection between the two Pucks is no longer existing.

    Another interesting observation is that when doing the connection from LightBlue as a central I see the same problem: After about 2 minutes I get a "Disconnected Alert" from LightBlue. So for whatever reason the connection is disconnected from the peripheral after 2 minutes (or so).

    I agree that it is necessary to handle the breakdown of connections. But on the other hand having a connection for more than 2 minutes is probably important for a lot of applications. Especially since the reconnect takes about 10-15 seconds.

    I like the idea of using gatt.connected to check upfront if the connection is still existing. However in my case it still returns true, although writing fails. Even with a regular timer it still returns true at a point where the connection is no longer existing (because LightBlue lists the peripheral Puck again as advertising).

  • Presumably you can connect from a PC to the Puck for >2 minutes though? I know I can.

    Also, do you have the up to date firmware (1v91) installed? I did change some things that would have improved matters there - one of them might be the connected flag

  • Yes, no problem from a PC. There was never a timeout when connecting from the Web IDE. And yes, as mentioned in the first post I am using 1v91. On both Pucks.

  • Sorry - just to be clear - when you connect to a Puck from LightBlue it also times out after 2 minutes?

    I guess it might be useful in tracking it down - no idea what the problem could be yet though!

  • Yes, that was the "Disconnect Alert" I mentioned. This is shown in a popup coming from LightBlue. Sorry for being unclear.

  • I just got my Puck-JS today
    It seems awesome! kudos!

    I am here though for a bit of help.

    I am building an Android app that needs to read button clicks (and needs to be pretty fast - 1 second apart). Pebblebee Stone did work but was limited to 1 click per 5 seconds.

    I am having problems with Puck-JS listing the device services. I thought I did see this work once but not since. And without the services, I can't read the characteristics.

    Any advice is much appreciated.

  • Please could you start a new thread for this, with the example code you're using?

    It's worth noting that:

    • Only one device can be connected to Puck.js at a time
    • Changing the services requires you to disconnect and then reconnect before they'll take effect.

    If you're trying to read button clicks, did you consider:

    • Just making it a BLE HID device
    • Using advertising, and setting advertising data to the number of times the button was pressed (there's an example on the forum somewhere) - it's quick, easy, low-power, and doesn't require pairing. Because it's counting button presses it can cope with you pressing the button really fast as well.


    @stevie4711 sorry I didn't get back to this - I think I found the underlying issue a few days ago though. The GitHub version has it fixed, but there's still a bit of tweaking needed (as fixing it caused the data rate to drop).

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

BLE Connection problems + questions

Posted by Avatar for stevie4711 @stevie4711

Actions