Posted on
of 2
/ 2
  • Hi,

    I'm probably missing something somewhere in the docs, but I'm trying to find information about how NFC works on the Puck, basically I want to change the webpage that the default code on the Puck redirects to when it comes near a phone etc.

    Could you point me in the right direction, or is this something that is coming?


  • Do you mean this?­ne

    I've not got it to work yet though.

  • I think you're after NRF.nfcURL(...)

    Eddystone's the one that broadcasts a URL over BLE - to have a play you're best off installing Google's Physical Web App.

  • Does anyone have working code example of how to read an NDEF record from a NFC Tag. I havent been able to scan for cards or read a NFC record from a card.

    NRF.on('NFCon', function() { ... });

  • The NFC in Puck.js is only a programmable tag - there isn't the circuitry in the nRF52 chip to read other tags.

    If you want to do that, you can attach an external reader - there are some simple modules available for common types:

  • Since the nRF52 is read only tag how can I format NDEF records for different TNF types other than URI.

  • At the moment, you can't. I could add the ability to specify the raw NDEF record but there hasn't been any call for it so far. What's you use case?

  • Seems the PuckJS with NFC should be best suited to a task with some form of dynamic message content that could contain some of the on-board sensor data or a time stamp. Also a good use case would be to setup some encrypted secure communications via BLE or wi-fi. Also firmware or software updates could be transfered through NFC. It would be most useful if you could do two way communications but read only is somewhat limited for a vast majority of use cases.

    I can't think of a use case for a dynamic changing URI but would think URI with additional NDEF records with certificate or auth key would make more interesting use case. This would require ability to craft multiple NDEF records which tags allow, especially the larger tags with more bytes of memory. It is very limiting if all you can do with the PuckJS is a simple ultralight tag with a URI record. For the static URI use case it would be much better to purchase an ultralight tag which are very inexpensive and consume no power as they are powered by the reading device and provide read/write functionality.

    For any kind of security use case you would need to make sure the tag had unique serial #ID/MAC that was not programmable, then you could form an NDEF record that could be encoded and validated as belonging to a specific device making for high security application. That is the advantage of NFC over BLE as it is considered more secure because of limited range (Near Field) and could be used for payment transactions. Also nice for providing secure access to specific devices.

    My domain of interest is in Electric Vehicle charging and how to control access to EV charging. Also of interest is vehicle information from OBDII CAN bus for fleet, vehicle VIN, and EV State Of Charge (SOC) information. All possible use cases for the PuckJS as it is a low power consumption device, small footprint and relatively inexpensive.

    If anyone is doing anything with OBDII I would be interested in a post on this topic as the PuckJS might make a good device to remote the CAN Bus info to a mobile device through BLE or NFC for some secure payment, vehicle to EV charger, or access control type applications.


  • I don't believe we can get proper two-way communications at the moment - I think it'd require re-writing Nordic's drivers. It is however all Open Source, so if you really wanted to do that it might be possible for you to make the changes.

    I'm also not 100% sure on the ability to craft multiple NDEF records - it's something that I could possibly add if I was paid for my time, but it's niche enough that I don't think I can justify spending time on it it over other features that would be more useful to others.

    With the URI - it is by no means static. You could still direct someone to a website with dynamic data in the URI itself.

    Also, for CAN - maybe something like an ELM327 is a very cost-efficient way of getting a connection to the car. Then you only have to worry about providing a serial protocol to the ELM327 itself.

  • I’ve recently started a project where I wanted to use NFC for a two way communication between a phone and device. For this reason I changed the Espruino NFC API to expose low level hardware access in JS. To prevent conflicts with Nordic's driver I completely removed support for NRF.nfcRaw and NRF.nfcURL. My branch instead features:

    //Enable NFC (returns tag header, 10 bytes)
    =new ArrayBuffer([95, 42, 58, 199, 216, 35, 65, 189, 7, 3])
    //Disable NFC
    //Register callback to call with incoming data
    NRF.on('NFCrx', function(data) { ... }
    //Send response
    NRF.nfcSend(new Uint8Array([0x01, 0x02, 0x03, 0x04, ...]);
    //Send ACK
    //Send NACK
    //No response, wait for next command

    Below is a usage example that "implements" NRF.nfcURL(""):

    var ndef = new Uint8Array([
      0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0xFF, 0xFF,
      0xE1, 0x11, 0x7C, 0x0F,
      0x03, 0x14, 0xC1, 0x01,
      0x00, 0x00, 0x00, 0x0D,
      0x55, 0x03, 0x65, 0x73,
      0x70, 0x72, 0x75, 0x69,
      0x6E, 0x6F, 0x2E, 0x63,
      0x6F, 0x6D, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00
    //Start NFC
    var header = NRF.nfcStart();
    //Add proper header to NDEF template
    ndef.set(header, 0);
    NRF.on('NFCrx', function(rx) {
      if(rx[0] === 0x30) { //Command: READBLOCK
        //Calculate block index
        var idx = rx[1]*4;
        //Prepare data (pad to 16 bytes)
        var tx = Uint8Array(16);
        tx.set(ndef.slice(idx, idx + 16)); 
        //send response
      } else {
        print("Unknown command: " + rx);
        //wait for next frame

    I hope my extensions are of use for the projects discussed above.­leases

    Edit: Implemented NDEF

  • Wow, nice! Thanks for posting up. How hard do you think it'd be to emulate the current functionality? It might make sense to build on top of that code (as presumably it cuts out the Nordic binary blob?)

  • It should not be to hard. I'is all about crafting a correct tag-header 8-16 bytes and NDEF records.

    Nordic's implementation drops all commands != READ

    So we just need to populate a Uint8Array with tag header + ndef records and respond to READ with the appropriate blocks of 16 byte of the array.

  • I've made an effort to decipher and implement NDEF support:

    1 Attachment

    • ndef.png
  • READ (0x30) should complete within 5ms. Do you known what the delay + execution time of a JS callback is?

  • I've measured the request-response delay with my example above. It is 2.5 ms. Hence we have a good margin for additional code.

  • Thanks - that looks really promising! I'm a bit busy at the moment but I filed an issue on GitHub for this, and I'll see about rolling it in when I get some time.

  • No need to hurry. The code is still in an early state and needs more work anyway.

    I just found another issue calling NRF.nfcStop(); after NRF.nfcStart(); permanently disables the NFC until the Puck.JS is hard reset by lifting the battery.

    Note: I can reproduce this issue also on the official build by setting URL to undef.

  • That's really odd - I'm sure that's one of the things I tested for during development, so I wonder if it has regressed somehow.

    Are you sure? I know most phones don't register NFC if the URL is already open in the web browser. I'd have thought I would have got more complaints if there was such a flaring problem.

  • I can reproduce this same issue using the Web IDE command pane and 1V92.

    1. NRF.nfcURL('');
    2. Touch tag to phone. Observe website is opened.
    3. NRF.nfcURL();
    4. Touch tag to phone. Observe no website is opened.
    5. NRF.nfcURL('');
    6. Touch tag to phone. Observe no website is opened.

    N.B. My Nexus 5X opens a new tab in the foreground with the URL, every time the tag is tapped, if the web browser is in the background.

  • Could the source of this issues be different SoftDevice or Silicon Version?

  • The SoftDevices should be the same, and silicon seems unlikely - you're both using Puck.js? I just tried two here, from two different batches. Both work fine.

    I'd be interested to see if anyone else has problems with this? I'm testing with a Nexus 10 here.

  • I'm using a Puck.js 1.0e

    1. Cold Boot
    2. IDE-Connect
    3. NRF.nfcURL("");

          Start |        End | Src | Data (! denotes   | CRC | Annotation 
              0 |       1056 | Rdr |26                 |     | REQA       
        4517504 |    4518560 | Rdr |26                 |     | REQA       
        9035488 |    9036544 | Rdr |26                 |     | REQA       
       13552976 |   13554032 | Rdr |26                 |     | REQA       
       18071472 |   18072528 | Rdr |26                 |     | REQA       
       22588960 |   22590016 | Rdr |26                 |     | REQA       
       27107984 |   27109040 | Rdr |26                 |     | REQA       
       27110228 |   27112596 | Tag |44  00             |     |           
       27560128 |   27564896 | Rdr |50  00  57  cd     |  ok | HALT       
       27629472 |   27630464 | Rdr |52                 |     | WUPA       
       27631700 |   27634068 | Tag |44  00             |     |           
       27642576 |   27645040 | Rdr |93  20             |     | ANTICOLL   
       27646228 |   27652052 | Tag |88  5f  14  55  9  |     |           
       27660672 |   27671136 | Rdr |93  70  88  5f  1  |  ok | SELECT_UID 
       27672372 |   27675892 | Tag |04  da  17         |     |           
       27684368 |   27686832 | Rdr |95  20             |     | ANTICOLL-2 
       27688004 |   27693892 | Tag |51  9f  5b  a2  3  |     |           
       27702464 |   27712992 | Rdr |95  70  51  9f  5  |  ok | ANTICOLL-2 
       27714164 |   27717748 | Tag |00  fe  51         |     |           
    <--- and so on --->
    1. RF.nfcURL();
    2. NRF.nfcURL("");

          Start |        End | Src | Data     | CRC | Annotation
              0 |       1056 | Rdr |26        |     | REQA      
        4516448 |    4517504 | Rdr |26        |     | REQA      
        9034464 |    9035520 | Rdr |26        |     | REQA      
       13553488 |   13554544 | Rdr |26        |     | REQA      
       18070464 |   18071520 | Rdr |26        |     | REQA      
       22588992 |   22590048 | Rdr |26        |     | REQA      
       27106464 |   27107520 | Rdr |26        |     | REQA      
       31624992 |   31626048 | Rdr |26        |     | REQA      
       36142976 |   36144032 | Rdr |26        |     | REQA      
       40662000 |   40663056 | Rdr |26        |     | REQA      
       45178976 |   45180032 | Rdr |26        |     | REQA      
       49697488 |   49698544 | Rdr |26        |     | REQA      
       54214432 |   54215488 | Rdr |26        |     | REQA      
       58733472 |   58734528 | Rdr |26        |     | REQA      
       63251968 |   63253024 | Rdr |26        |     | REQA      
       67768960 |   67770016 | Rdr |26        |     | REQA      
       72287472 |   72288528 | Rdr |26        |     | REQA      
       76805952 |   76807008 | Rdr |26        |     | REQA            

    Note: The trace is reformatted to fit to line length

    Some how the NFC peripheral is stuck / offline. The handshake does not even start.
    I think its an error in the HAL or how it is used.

  • I had an epiphany: Gordon did you use­ for your tests yesterday? The behaviour seams also to depend on the compiler used.

    Some weeks ago I spent one day debugging an issue, that when away, when I upgraded to the GCC defined in your documentation.

  • I've just tried again to make absolutely sure:

    Are you using that image, or are you using something that you compiled yourself?

    I've also tried with my own builds here, and they work fine. I am using 5.4.1 20160919 though as I found when doing builds for release that the GCC 6 compiled binaries were a bit flakey

  • Are you taking the Puck out of NFC range before changing the tag with NRF.nfcUrl? I wonder whether that could be causing problems...

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


Posted by Avatar for gomako @gomako