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",conne­ctable: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/?i­d=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:tr­ue}) 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:true 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",conne­ctable: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.

  • 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