Removing beacon mode set with NRF.setScanResponse

Posted on
  • Hi. In the Eddystone beacon tutorial it says that we can broadcast beacon url together with other advertising by using

    NRF.setScanResponse(require("ble_eddysto­ne").get("goo.gl/B3J0Oc"));
    

    Which works fine, but I cannot find a way to turn off beacon advertising,

    NRF.setAdvertising({});
    

    doesn't seems to work, is there another command I should use? Thanks.

  • If you don't want to advertise Puck.js normally at all and just want Eddystone then you can just use the standard Eddystone example:

    require("ble_eddystone").advertise("goo.­gl/B3J0Oc");
    

    This also works too:

    NRF.setAdvertising([require("ble_eddysto­ne").get("goo.gl/B3J0Oc")]);
    

    You can use NRF.sleep() to completely turn off advertising, but the issue there is it turns off everything. A ScanResponse is sent in response to a query on an Advertising packet, so if there's no advertising then it's no use at all. If you use NRF.sleep() without a way to call NRF.wake() (eg. on a button press) then it effectively turns your Puck into a paperweight until you reset it :)

  • What would be the best way to advertise manufacturer data and Eddystone at the same time? I can't figure how to do something like this (obviously not working):

    var bUrl = "stackoverflow.com"; // Updated from Node-Red
      
      function updateAdv() {
        var data = [JSON.stringify(Puck.light().toFixed(3) * 1000), Math.round(E.getTemperature())];
        console.log(data);
        NRF.setAdvertising([
            {manufacturer: 0x0590, manufacturerData:data},
            require("ble_eddystone").advertise(bUrl)­
            ], {interval:1000});
      }
      updateAdv();
      setInterval(updateAdv, 5000); 
    

    Thanks.

  • Ahh, yes. It's a bit frustrating because of the way NRF.setAdvertising was implemented originally - and then I was stuck trying to be backwards compatible.

    Try this:

    var bUrl = "stackoverflow.com"; // Updated from Node-Red
      
      function updateAdv() {
        var data = [JSON.stringify(Puck.light().toFixed(3) * 1000), Math.round(E.getTemperature())];
        console.log(data);
        NRF.setAdvertising([
            NRF.getAdvertisingData({},{manufacturer:­ 0x0590, manufacturerData:data}),
            require("ble_eddystone").advertise(bUrl)­
            ], {interval:1000});
      }
      updateAdv();
      setInterval(updateAdv, 5000); 
    
  • Thanks @Gordon. I can't make the above work, the Eddystone url doesn't show up (the manufacturer data do), and at some point I couldn't connect to the puck, EspruinoHub couldn't see it at all (took the battery out to reset it). The code below worked, not sure if is the best way, but as long as it works, all good :)

    NRF.setAdvertising([
                NRF.getAdvertisingData({},{manufacturer:­ 0x0590, manufacturerData:data}),
                NRF.setScanResponse(require("ble_eddysto­ne").get("goo.gl/B3J0Oc"))
       ], {interval:1000});
    
  • NRF.setScanRespose doesn't return anything, so what you're doing is effectively:

    NRF.setScanResponse(require("ble_eddysto­ne").get("goo.gl/B3J0Oc"));
    NRF.setAdvertising([
                NRF.getAdvertisingData({},{manufacturer:­ 0x0590, manufacturerData:data}),
                undefined
       ], {interval:1000});
    

    Which is just:

    NRF.setScanResponse(require("ble_eddysto­ne").get("goo.gl/B3J0Oc"));
    NRF.setAdvertising({},{manufacturer: 0x0590, manufacturerData:data,interval:1000});
    

    Actually I made the same mistake with the example code - using advertise instead of get. It should be:

    var bUrl = "stackoverflow.com"; // Updated from Node-Red
      
      function updateAdv() {
        var data = [JSON.stringify(Puck.light().toFixed(3) * 1000), Math.round(E.getTemperature())];
        console.log(data);
        NRF.setAdvertising([
            NRF.getAdvertisingData({},{manufacturer:­ 0x0590, manufacturerData:data}),
            require("ble_eddystone").get(bUrl)
            ], {interval:100});
      }
      updateAdv();
      setInterval(updateAdv, 5000); 
    

    I just tried this and it works for me. Your inability to connect is most likely because the interval was 1000ms - BLE broadcasts on 3 frequencies in turn, and it's also alternating advertising packets so a computer trying to connect is only seeing an advertising packet every 6 seconds - pretty much any connecting computer will time out connecting unless you're very lucky.

    Hope that helps!

    Just to add [JSON.stringify(Puck.light().toFixed(3) * 1000), Math.round(E.getTemperature())] is probably not what you want... It's creating a String of ascii characters with quotes around it, which is then being converted to a series of bytes (which could be variable length).

    It's probably best to just pack it into a byte with: [Puck.light()*255, Math.round(E.getTemperature())] (the conversion to integer gets done automatically).

  • @Gordon thanks, your help is much appreciated. The reason I was getting results with NRF.setScanRespose was probably because I am using Google's "Nearby" (Settings->Google->Nearby on android), which is scanning for Eddystone links, but I see now that it's not exactly what I need.

    For reasons I don't understand, the above code doesn't work correctly for me (have tried it on 2 pucks). Manufacturer data are advertised properly, but I don't see the url. I am checking with nRF Connect and 0x0590 is there, very rarely 0xFEAA may pop up very shortly and disappear again. Same on Nearby, if I refresh constantly I may see it at some point, but it's gone once I refresh again. EspruinoHub on console (PuTTY) is showing feaa and the link for the puck though.

    Stringifying data is not the way to go, I know, but I start using it when I couldn't figure out how to send code to change color on a ble bulb from one puck to another, got a little confused with all the conversions among different bases. But it's kind of working, slice and parseInt ftw. I still cannot understand though how you can represent, lets say 1000 states, with 255 numbers.

  • the above code doesn't work correctly for me

    It's strange - it doesn't appear well for me either - but when dumping the raw advertising data received I do see the 2 types of advertising packet being sent as they should be. If Scan Response works then that's probably best then.

    I still cannot understand though how you can represent, lets say 1000 states, with 255 numbers.

    You're right, you can't :) It's basically just turning 1000 states into 256 states, but the light measurement isn't accurate enough that it really matters. You could always use 2 bytes for 16 bits (DataView is good for that).

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

Removing beacon mode set with NRF.setScanResponse

Posted by Avatar for Pi @Pi

Actions