techniq / node-pn532

Native Node.js driver for the PN532 NFC chip
73 stars 32 forks source link

Issue with i2C #15

Open val34m opened 7 years ago

val34m commented 7 years ago

Hello

I have an issue when i try to use the PN532.

First this is what i use:

=>Raspberry pi 3 => debian => node 4.3.2 =>npm 2.14.12 => pn532 on 0x24 (i2c) => i2c active

I create a file (test.js) with this code:

var pn532 = require('pn532'); var i2c = require('i2c'); var address = 0x24; var wire = new i2c(address, {device:'/dev/i2c-1',debug:false}); var rfid = new pn532.PN532(wire);

When i run a : node test.js i have this issue : home/pi/node_modules/i2c/lib/i2c.coffee:88 return callback(err); ^

TypeError: callback is not a function at Immediate._onImmediate (/home/pi/node_modules/i2c/lib/i2c.coffee:54:9) at processImmediate [as _immediateCallback] (timers.js:383:17)

I'm lost.

Thank for your help

justgeek commented 7 years ago

I had same issue, I think the write function expects a callback but it doesn't exist. Anyway I commented this line#54 in i2c.coffee:

write: (buf) ->
    @setAddress @address
    unless Buffer.isBuffer(buf) then buf = new Buffer(buf)
    wire.write buf, (err) ->
      tick ->
       # callback err

Now im not getting the ready event fired, but don't think it is related to this comment.

techniq commented 7 years ago

I need this documented better, but currently what is in master (and released on NPM) is not working. There is an I2C branch that I had working, but it still has some work to do that I just haven't had time to finish (I haven't had a recent project using this library in a while, and what I've deployed was using UART).

See this comment for a little more details.

If anyone is willing to finish this up, I'd be more than willing to review your PR and cut a new release. I wasn't sure how best to handle the explicit pin/polling and haven't had time to see how other libraries handle this (or if it is unique to how the PN532 operates).

cthayer commented 7 years ago

I submitted a PR for this error (it's missing a callback when calling write on the i2c wire)

https://github.com/techniq/node-pn532/pull/16

I don't have the I2C version of pn532 working yet, but the above PR fixes this error.

cthayer commented 7 years ago

I'm looking at the i2c branch. I'll give that go and see what I make work.

This is my first foray into i2c, but I need it for my project, so I'll give it a shot :)

justgeek commented 7 years ago

I have used this library https://github.com/Alabate/node-freefare , and it works flawlessly, give it a try guys.

techniq commented 7 years ago

@cthayer Thanks for the PR. I'm not sure it's needed though since I2C on master is not functional (with or without the PR). I would rather merge in the I2C branch than apply a fix which just removes the error but doesn't improve any functionality.

My first and only foray into I2C has been this project (outside of using some node-pixel's I2C backpacks).

I had successfully used a firmata-flashed board and I2C to communicate with the PN532 after updating this library (see the last commit to the I2C branch here).

With I2C it seems you have to pull the data from the pn532 by calling i2cReadOnce. You can setup an IRQ pin to have the PN532 notify you when the next value to read is ready but trying to do that generically within the library I was struggling with (from firmata I can use this.board.digitalRead but if running directly on a device such as a Raspberry Pi I wouldn't know how best to interface with the GPIO. I was trying to think of a good abstraction (maybe have the user of the library provide a callback for these types of operations) but didn't want to complicate the library too much. I also don't think the IRQ was a requirement and could probably just poll, which I think I was trying to do outside of firmata here. I've been meaning to look at other libraries using I2C with Node and see how they work (although a lot of just sensors and not as sophisticated as the PN532 chip)

Anyways, I was making progress from the last 2 commits to the I2C branch, but both of minimal understanding of I2C and my free time has hindered official support getting into the library. I haven't use this library on a new project in over a year, and the last time I did, I was using UART (which works quite well from a Mac using a FTDI cable).

I would love for someone to get this functional and I would gladly review and push a new release. I worked a great deal with @Zhairgling on issue #12 to get card emulation working. He got it working but sadly he didn't submit a PR to add the functionality back, but it's available in his fork. I keep hoping to find time to get it added into the library (it needed some cleanup) but I just haven't had the time myself.

techniq commented 7 years ago

@justgeek that looks great. The reason I created this library was to have a pure node-native library that didn't depend on LibNFC (which I was having trouble building/configuring correctly last I looked at it). As always, use what works for you :)

justgeek commented 7 years ago

@techniq is this possible ? can node talk to hardware kernel ?

techniq commented 7 years ago

@justgeek Not directly from my understanding. I'm still using node-serialport, i2c-bus, or node-i2c which are using C bindings to Node. node-pn532 is a layer on top of these but implementing the communication/protocol between the pn532 and node natively in javascript. So I guess I misspoke saying it was 100% native. It's been a while since I wrote/used this library so my brain is a little rusty. If I recall correctly, it was very difficult to get libnfc to compile/setup on a Mac (maybe impossible/not supported). It was also another thing to have to require to be installed ahead of time, instead of just npm install and use the library.

techniq commented 7 years ago

Btw, I remember switch from node-i2c to i2c-bus due to support for Node > 0.12 (iojs at the time, and later node 4.x+). This may no longer be a problem, but it way the current i2c branch is using i2c-bus.

secit-pl commented 7 years ago

Any updates on this? I'm trying to write some data and than read them using the pn532 code from branch i2c without luck.

Test code:

var pn532 = require('pn532');
var i2c = require('i2c-bus');
var ndef = require('ndef');

var bus = i2c.openSync(1);

var rfid = new pn532.PN532(bus);

rfid.on('ready', function() {
    console.log('Ready...');
    rfid.scanTag().then(function(tag) {
        console.log('Scanned...');
        var messages = [
            ndef.uriRecord('http://www.google.com'),
            ndef.textRecord('test')
        ];
        var data = ndef.encodeMessage(messages);

        console.log('Data ready...');

        rfid.writeNdefData(data).then(function(response) {
            console.log('Write successful');
            rfid.readNdefData().then(function(data) {    
                var records = ndef.decodeMessage(data.toJSON());
                console.log(records);
            });
        });
    });
});

The console output:

Ready...
Scanned...
Data ready...
Write successful
error: [pn532] ERROR: Error: Unable to locate NDEF TLV (0x03) byte in block:
    at /home/pi/Desktop/pn532/node_modules/pn532/src/pn532.js:221:31
techniq commented 7 years ago

@secit-pl I don't know if I'll be able to get around to finishing the I2C in any reasonable timeframe. I'm over committed on other projects already, and I'm personally not using I2C at this point. I think I was close enough on the I2C branch to have someone hopefully take it from there and submit a PR, and I'll try to provide guidance where I can.