• Hi all,

    Since the Puck is capable of broadcasting a URL using the NRF.setAdvertising()
    function I was wondering if the Puck can recieve/read an Eddystone-URL broadcast by another Puck. My objective is to extend the range of the Puck Bluetooth broadcast.

    An example is one Puck broadcast a URL which is received by another Puck close by, the second Puck then broadcast the same URL. Only the first Puck knows the URL, the rest just "propagates" the Bluetooth broadcast (something like a very basic Bluetooth Mesh)

    Is this possible with the Puck hardware?

    Thanks.

  • Yes, it should be! You'll just have to decode the data to get the URL (or maybe not? You could just forward the data as-is).

    NRF.findDevices (http://www.espruino.com/Reference#l_NRF_findDevices) is what you want, although you can get finer grain control with NRF.setScan (http://www.espruino.com/Reference#t_l_NRF_setScan) as you receive individual packets that way.

  • Hi Gordon, thanks for your reply.

    I am currently testing out the Eddystone broadcasting function using the NRF.setAdvertising
    examples in the documentation. But when testing the maximum message length that can be sent using Eddystone format, I received an error once the message exceed 24 bytes. I heard that the maximum length supported for a Bluetooth advertising packet is 31 bytes. So why is the packet that I can send much shorter than expected?

    The code that i used is:

    NRF.setAdvertising([0x03,  // Length of Service List
      0x03,  // Param: Service List
      0xAA, 0xFE,  // Eddystone ID
      0x13,  // Length of Service Data
      0x16,  // Service Data
      0xAA, 0xFE, // Eddystone ID
      0x10,  // Frame type: URL
      0xF8, // Power
      0x03, // https://
      '1','2','3','4','5','6','7','8','9','A','B','C','D','E'],
        {interval:100});
    

    Will result in:

    >Uncaught Error: Got BLE error code 9
     at line 1 col 37
    NRF.setAdvertising(d, {interval:100});
    

    Interestingly enough, I saw your answer on another iBeacon question which uses the code below and it works on the puck with a packet size of 30 bytes:

    var d = [0x02, // Number of bytes that follow in first AD structure
        0x01, // Flags AD type
        0x04, // Flags value 0x1A = 000011010  
        //   bit 0 (OFF) LE Limited Discoverable Mode
        //   bit 1 (OFF) LE General Discoverable Mode
        //   bit 2 (ON) BR/EDR Not Supported
        //   bit 3 (OFF) Simultaneous LE and BR/EDR to Same Device Capable (controller)
        //   bit 4 (OFF) Simultaneous LE and BR/EDR to Same Device Capable (Host)
        0x1A, // Number of bytes that follow in second (and last) AD structure
        0xFF, // Manufacturer specific data AD type
        0x4C, 0x00, // Company identifier code (0x004C == Apple)
        0x02, // Byte 0 of iBeacon advertisement indicator
        0x15, // Byte 1 of iBeacon advertisement indicator
        0xe2, 0xc5, 0x6d, 0xb5, 0xdf, 0xfb, 0x48, 0xd2,
        0xb0, 0x60, 0xd0, 0xf5, 0xa7, 0x10, 0x96, 0xe0,// iBeacon proximity uuid
        0x00, 0x00, // major 
        0x00, 0x00, // minor 
        0xc5]; // The 2's complement of the calibrated Tx Power
        NRF.setAdvertising(d, {interval:100});
    

    Now I am not sure if this is a Puck issue or a Eddystone issue. Hope you can help me out. Thanks in advance :)

  • First, I'd say it looks like you might have an out of date Puck.js firmware? It'd be worth updating to 1v92

    But I don't think that is your problem. Error 9 is 'invalid length' (which is reported as text on 1v92 firmware). It's actually saying that the data you're trying to send has the length field set wrong.

    Try changing: 0x13, // Length of Service Data

    to: 0x14, // Length of Service Data

    It should be the number of bytes that are after that byte.

    Also, do you know that if you want to use eddystone, there's a library which will do it all for you? http://www.espruino.com/Puck.js+Eddystone

  • Hi, you are correct that my Puck is now still on 1v88. I didn't update it because I have some other projects in progress and I don't want to potentially affect them through updating.

    I changed 0x13 to 0x14 then add one more character to the message and it worked! Now I found that the maximum value is 0x1A and the entire message is now 31 bytes just as you mentioned.

    Working: (31 bytes total)

    NRF.setAdvertising([0x03,  // Length of Service List
      0x03,  // Param: Service List
      0xAA, 0xFE,  // Eddystone ID
      0x1A,  // Length of Service Data
      0x16,  // Service Data
      0xAA, 0xFE, // Eddystone ID
      0x10,  // Frame type: URL
      0xF8, // Power
      0x03, // https://
      '1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K'],
        {interval:100});
    

    Any further extension will result in BLE Error Code 9 but that is to be expected, I think.

    I am aware that the Eddystone library exists, but I am using this manual way to verify if the message can be maximum 31 bytes long.

    Now I am able to use NRF.findDevices on the receiving beacon to read the information from other Bluetooth beacons nearby. I am looking into a way to filter out everything except the Puck's broadcast. One way I suspect this can be done is using the services key in the devices object as the broadcasting message has the feaa value. Though I have zero experience in js so I think this will take a while.

    BluetoothDevice {
      "id": "e3:55:93:0b:72:1d random",
      "rssi": -66,
      "services": [
        "feaa"
       ],
      "data": new ArrayBuffer([3, 3, 170, 254, 26, 22, 170, 254, 16, 248, 3, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75])
     }
    

    Many thanks for you help.

  • I could be wrong here, but I think FEAA corresponds to the 170, 254 section of the advertising data, and is Google's Bluetooth UUID. So filtering on that will filter out everything except eddystone beacons, which could be what you want?

    Filtering specifically on Puck.js devices could be more painful. I'd suggest maybe making your own URL shortener service - for instance if you shortened all your URLs using something like foob.ar/ee54ce5 then you could detect foob.ar and know that the beacon was one of yours.

  • Yea, I am trying to filter out all the other Puck devices transmitting using Eddystone format.

    But now I am facing an issue of getting the data out, as the data is stored in the devices[i].data object. Now I am using a for loop to get each item in the devices[i].data object, then store it in another array. As I am not familiar with the js ArrayBuffer object.

    new ArrayBuffer([3, 3, 170, 254, 26, 22, 170, 254, 16, 248, 3, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75])
    
  • Well, Google is your friend here I think - but if a for loop works for you, I'd use that :)

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

Can the Puck recieve an Eddystone-URL broadcast?

Posted by Avatar for intern @intern

Actions