5

I am attempting to build a webapp on a Chromebook, I need it to read RFID card serial numbers with an ACR122U NFC. I am using chrome-nfc.

I am reading cards happily, but I do not know how to fire an event when a card is presented.

Are there any events in chrome-nfc I can use to know when a card has been presented to the reader?

EDIT: I have been trying to use chrome.nfc.wait_for_tag, but it does not behave as I would expect.

// With a card on the reader
chrome.nfc.wait_for_tag(device, 10000, function(tag_type, tag_id){
  var CSN = new Uint32Array(tag_id)[0];
  console.log ( "CSN: " + CSN );
});

[DEBUG] acr122_set_timeout(round up to 1275 secs)
DEBUG: InListPassiveTarget SENS_REQ(ATQA)=0x4, SEL_RES(SAK)=0x8
DEBUG: tag_id: B6CA9B6B
DEBUG: found Mifare Classic 1K (106k type A)
[DEBUG] nfc.wait_for_passive_target: mifare_classic with ID: B6CA9B6B
CSN: 1805372086



// with no card on the reader
chrome.nfc.wait_for_tag(device, 10000, function(tag_type, tag_id){
  var CSN = new Uint32Array(tag_id)[0];
  console.log ( "CSN: " + CSN );
});

[DEBUG] acr122_set_timeout(round up to 1275 secs)
DEBUG: found 0 target, tg=144

Both return the results as above immediately, it does not seem to matter what number I use for a timeout...

If I call the function with no card on the reader, and then immediately put the card on the reader after function call, I get no output in the console.

approxiblue
  • 6,982
  • 16
  • 51
  • 59
Hank
  • 731
  • 6
  • 10

2 Answers2

2

I'm not familiar with chrome-nfc, but taking a shot in the dark by reverse engineering the source, it looks like you would want to use the wait_for_tag method, like:

chrome.nfc.wait_for_tag(device, 3000, function(tag_type, tag_id) {
    // Do your magic here.
});

...Where device is your reader, 3000 is the maximum time to wait (in ms), and replacing // Do your magic here. with your desired logic. If it times out, both tag_type and tag_id will be null.

If you wanted to wait indefinitely, you could just recursively call a function with the above code. Example:

function waitAllDay(device) {
    chrome.nfc.wait_for_tag(device, 1000, function(tag_type, tag_id) {
        if(tag_type !== null && tag_id !== null)
        {
            // Do your magic here.
        }
        waitAllDay(device);
    });
}

That's assuming you want it to continue waiting even after a tag has been presented. Wrap the waitAllDay(device); in an else if you want it to stop once a tag is read.

UPDATE: It seems the wait_for_tag method does not work as intended, so I'm proposing a second solution. I'm leaving the existing solution in place in case the method is fixed by the developers of chrome-nfc.

Another thing to try is to use chrome.nfc.read, passing in a timeout option, inside a window.setInterval.

var timer = window.setInterval(function () {
        chrome.nfc.read(device, { timeout: 1000 }, function(type, ndef) {
            if(!!type && !!ndef) {
                // Do your magic here.
                // Uncomment the next line if you want it to stop once found.
                // window.clearInterval(timer);
            }
        });
    }, 1000);

Be sure and call window.clearInterval(timer) whenever you want it to stop watching for tags.

Grinn
  • 5,370
  • 38
  • 51
  • Thanks @Grinn for your suggestion. I am having problems however, that its not actually doing any waiting, it always returns straight away. I have updated the question with an example of output. – Hank Sep 10 '15 at 01:31
  • @Hank what is the value of `tag_id` when there is no card in the reader? – Grinn Sep 10 '15 at 12:40
  • it is undefined... its as if the function is cancelled and it never makes it to my callback – Hank Sep 10 '15 at 12:45
  • @Hank It seems that `wait_for_tag` doesn't call the callback in all execution paths. See my updated and let me know how it goes. – Grinn Sep 10 '15 at 14:15
  • Thanks for your efforts! I tried your second solution and it gave the same result. returned immediately with `DEBUG: found 0 target, tg=144`. – Hank Sep 10 '15 at 14:18
  • @Hank do you mean the `window.setInterval` solution that I proposed above? I ask because I briefly posted another solution. With this latest solution you will see that `DEBUG: found 0 target, tg=144` every second or so, as it looks for tags at each interval, but it should find the tag once present. – Grinn Sep 10 '15 at 14:49
0

While I do not consider this a proper solution; here is a workaround I am using for the time being.

function listen_for_tag(callback, listen_timeout){

  var poll_delay = 400; //ms
  var listen_loop = null;
  if(!listen_timeout){
    listen_timeout = 99999999;
  }

  function check_for_tag(){
    if(listen_timeout < 0) {
      clearInterval(listen_loop);
      console.log("we didnt find a tag. finished");
    }
    chrome.nfc.wait_for_tag(dev_manager.devs[0].clients[0], 10, function(tag_type, tag_id){
      console.log ( "FOUND A TAG!!" );
      clearInterval(listen_loop);

      // handle the callback (call it now)
      var C = callback;
      if (C) {
        callback = null;
        window.setTimeout(function() {
        C(tag_type, tag_id);
        }, 0);
      }
    });
    listen_timeout -= poll_delay;
  }
    listen_loop = setInterval(check_for_tag, poll_delay);
}
Hank
  • 731
  • 6
  • 10