Bangle.js 2: Bluetooth Long Range

Posted on
  • Hi! Just an update on this - it was a stretch goal on the KickStarter, and I never got around to implementing it. However I have just got something working! (cutting edge build, 2v14.63).

    Right now, you can't advertise as connectable or scannable, but this still seems to be pretty powerful...

    For instance:

    // on transmitter
    NRF.setTxPower(8);
    NRF.setAdvertising({},{phy:"coded",connectable:false,scannable:false}); // this works!
    
    // on receiver...
    var age = 0;
    NRF.setScan(function(d) {
      g.clear(1).setFont("6x8").drawString(`
    id ${d.id}
    name : ${d.name}
    rssi: ${d.rssi}
    `);
      age = 0;
    },{phy:"coded"});
    setInterval(function() {
      g.drawString("age: "+age+"   ",0,100,true);
      age++;
    }, 1000);
    

    Will advertise on one Bangle, and show when a packet is received on another. I'm still seeing the signal received all the way through the house at the other end of the garden.

    It'll be really interesting to see what you come up with :)

  • Nice one!

  • Ok, there's now an app:

    https://espruino.github.io/BangleApps/?id=shownearby

    • Get 2 (or more!) Bangles
    • Ensure you have the latest cutting edge firmware on your bangle
    • Install openstreetmap
    • Install Assisted AGPS (optional!)
    • Install Show Nearby
    • Run the Show Nearby app on both Bangles, wait until they both have GPS - then go for a walk.

    Your location is shown as a red dot, and the location of other Bangles running the app is shown in green. I'd be interested to see how far away from each other you can get!

  • Excellent!
    What exactly makes this a long distance transmission? The call to setTxPower or the specifics of the setAdvertising invocation?
    If it is the former, the Show Nearby app does not seem to contain a call to setTxPower...

  • the Show Nearby app does not seem to contain a call to setTxPower...

    Yes, I spotted that when I went to try it - It should include it now!

    That helps with the range, but what really increases the range is phy:"coded" - this uses a different transmission method where it sends 8x as much data, where pretty much all of it is error correcting code. So that way there can be a bunch of corruption in the data that is received, but the packet can still be reconstructed.

  • I don't have two Bangle JS 2 watches to test this but I tested it briefly with the other part being NRF52840 dongle with latest Espruino built from source and it worked, this code finds only the watch with the app running so the coded phy works.

    NRF.setScan(function(d) {
      print(`
    id ${d.id}
    name : ${d.name}
    rssi: ${d.rssi}
    `);
    },{phy:"coded"});
    

    The watch was outside and dongle inside house but not very far so I'll try to test the range somehow. I guess walking outside while using IDE relay from phone to the dongle inside could work so I could see console output and rssi values.

    BTW the app does not cleanup after itself so after exiting I could not connect to it until reboot

    Could the watch advertise with coded phy while still being connencted to phone over 1mbps link? I think I was connected to dongle over BLE and the scan worked however I guess for now espruino can't advertise while being connected(?).

  • BTW the app does not cleanup after itself so after exiting I could not connect to it until reboot

    :o thanks! That's a very good point!

    Could the watch advertise with coded phy while still being connencted to phone over 1mbps link?

    In theory, yes. I wasn't quite sure how to expose that nicely though as the NRF.sleep/wake command is a bit messy. I guess NRF.setAdvertising({},{whileConnected:true}) could work?

  • I guess NRF.setAdvertising({},{whileConnected:tr­ue}) could work?

    So this flag would be set before any connection when advertising? And when you would connect from Web IDE/phone to it with this flag set, it would continue to advertise (as not connectable) while accepting connection? Or is this call meant to start advertising while being already connected? If the former then how to start advertising later while already connected without this flag or how to switch to coded phy (and back) = modify advertising? If the latter then why such flag is needed? NRF.setAdvertising could simply enable advertising while being already connected to. Only if there are no more available connections to accept (now the limit is 1 but could be more in future) it would permit only non connectable mode.

  • Or is this call meant to start advertising while being already connected?

    Yes, I think it should do that...

    If the latter then why such flag is needed?

    Well what if you want it to not advertise when connected?

    I think not everyone will want setAdvertising to always enable advertising. I can imagine it getting very confusing if they see the device but then can't connect to it because it's already got something connected to it.

    ... also, if the default behaviour changes it may well mess with existing code :)

    it would permit only non connectable mode.

    Yes, that makes sense. It's another reason to have the flag, because without it, calls to setAdvertising that used to work would then throw an exception ('can't advertise as connectable when already connected')

  • Oh, got it. There is no startAdvertising/stopAdvertising and currently NRF.setAdvertising is not a substitute for that. It only sets the data but currently does not affect whether it is on or off. So calling it after being connected may modify the data but does not turn it back on now. That's why the flag is needed. So if it is already off because it is connected the whileConnected:tr­ue would turn it on (and false would turn it off if it was on). That looks sensible.

  • OK so I made another test with range and unfortunately cannot see any difference when compared to normal mode.

    I've put nrf52840 dongle on the table on the terrace then connected webide relay from notebook inside to the dongle (over BLE) and then entered relay code on the phone in the browser so I could see dongle console over phone data connection. Then I started nearby app on the watch and waited for fix and scan output from the dongle showing watch and its rssi. Then I went outside with the watch and phone. I already lost it on the scan while goin down the stairs inside house but when I got outside and walked around house to be near the terrace I got the device in scan again, then I went a little bit over 50m away which was furthest when I still mostly saw the device in the scan output, lowest rssi value was -97.

    Surprise was that when I disconnected IDE over relay at that point I could not reconnect (relay is probably one time only connection) so I searched for BLE devices and I saw the dongle and could connect to it from phone over BLE (still same place, over 50 meters away). Then I again saw scan output and went back home. I lost the dongle BLE connection in about same place where I saw watch in scan output when I went outside. So it looks like normal BLE connection from phone to dongle over BLE has about the same range as dongle scan for watch via coded phy. the terrace is higher and has wall around it so those 50 meters was not direct line of sight but with this one wall in between (pretty thin one, no bricks or concrete).

  • It is strange that the rssi I saw never went over -97, it is similar to what people saw here https://devzone.nordicsemi.com/f/nordic-q-a/27113/nrf52840-coded-phy-sensitivity?pifragment-684=2 with alpha versions of S140 softdevice and they later claimed that bug was fixed (two bugs actually) and I should see up to -103 dBm in the scan
    also in this article https://www.cnblogs.com/dong1/p/15434159.html they say "With Coded PHY, the scanner can still detect adv packets of signal strength around -101 dBm"

    Did you see lower value than -97?

  • Odd - and you're sure it was actually using the coded phy?

    I don't actually remember I'm afraid, I wasn't looking specifically for RSSI - but when I tested I definitely felt like I got much better range than I experienced from normal advertising.

    But...

    connected webide relay from notebook inside to the dongle (over BLE)

    The dongle should support serial over USB, so maybe connect via USB instead? It's possible that trying to keep a bluetooth connection running while also scanning means it's not able to use the coded phy properly?

  • ... Or you could just advertise with the dongle and try and receive on the Bangle. This is what I used for testing:

    // on transmitter
    NRF.setTxPower(8);
    NRF.setAdvertising({},{phy:"coded",connectable:false,scannable:false}); // this works!
    
    // on receiver...
    var age = 0;
    NRF.setScan(function(d) {
      g.clear(1).setFont("6x8").drawString(`
    id ${d.id}
    name : ${d.name}
    rssi: ${d.rssi}
    `);
      age = 0;
    },{phy:"coded"});
    setInterval(function() {
      g.drawString("age: "+age+"   ",0,100,true);
      age++;
    }, 1000);
    
    
  • It's possible that trying to keep a bluetooth connection running while also scanning means it's not able to use the coded phy properly?

    I have many BLE devices around and I could see only the watch in the scan so I guessed coded phy worked as there are no filters in the scan.

    NRF.setScan(function(d) {
      print(`name : ${d.name}
    rssi: ${d.rssi}`);
    },{phy:"coded"});
    

    I can try usb, I wanted notebook to stay inside and dongle outside so used BLE.

  • It is strange that the rssi I saw never went over -97
    they say "With Coded PHY, the scanner can still detect adv packets of signal strength around -101 dBm"

    I tried testing long range mode, bangle 2 as transmitter, magic 2v21 s140-6.1.0 as receiver, I got to see -101dbm for just a moment , -99/-98 dBm a few more times, but in practice it looks like normal BLE range. If the BLE long range can indeed go 1km, it would be super. Is the 1km an exageration, or maybe the long range on espruino is not really working yet?

    lala=[];
    NRF.setScan(function(d) {
     if (d.rssi<=-97) lala.push(d.rssi);
    },{phy:"coded"});
    
    >lala
    =[ -98, -97, -97, -97, -99, -97, -97, -97, -98 ]
    
  • You could look at this code: https://banglejs.com/apps/?id=shownearby

    I have tested that app in the past when making it and I can't say I got 1km but it was a hell of a lot more than I get with normal BLE - well over 100 meters between two bangles when outside.

    My understanding is that the coded phy kind of just adds error correction, so the actual rssi value you see may not go up with coded phy, it's just that you now receive messages that would previously have failed the CRC check.

  • I've seen some slight difference indoors, one more wall/few meters more works with RSSI over 100.

    So for now advertising over coded phy should work and I think there is no way to improve range more in software.

    However there are some other missing features see https://github.com/espruino/Espruino/issues/2465

    • connections over coded phy do not work
    • extended advertising - advertise more data than 31 bytes (there is no scan response possible over coded phy so less data fits - only 31 instead of 31+31)
      for both SD140 6.1.x is needed

  • You could look at this code: https://banglejs.com/apps/?id=shownearby

    this is how I found out that you have phy working :)

    I will test some more, if you both get longer distance with phy then maybe I didn't test good enough.

    But if it is ~100 meters in openspace, then maybe it is not as impressive as I though it could be. I was hoping for something like 500 meters in city environment, like an info that another euc rider is nearby. :)

    thank both for the info.

  • I was hoping for something like 500 meters in city environment

    Ahh, yes, I don't think it'd be that good. It's more like: 1km in the countryside if one of you is standing on top of a hill with line of sight to the other :(

    In a city I imagine there are literally thousands of BLE devices in even a 500m radius, so there'd just be too much interference

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

Bangle.js 2: Bluetooth Long Range

Posted by Avatar for Gordon @Gordon

Actions