Skip to content

Commit

Permalink
Add initial support for I2C using an Arduino with Firmata / firmata.j…
Browse files Browse the repository at this point in the history
…s. Issue #7
  • Loading branch information
techniq committed Aug 23, 2016
1 parent 555b122 commit b0b4570
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
16 changes: 16 additions & 0 deletions examples/card_scan_i2c_firmata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var pn532 = require('../src/pn532');
var Board = require('firmata');

console.log('Initializing firmata board...');
var board = new Board('/dev/tty.usbmodem1263141', function() {
board.i2cConfig();
var rfid = new pn532.PN532(board);

console.log('Waiting for rfid ready event...');
rfid.on('ready', function() {
console.log('Listening for a tag scan...');
rfid.on('tag', function(tag) {
console.log(Date.now(), 'UID:', tag.uid);
});
});
});
3 changes: 3 additions & 0 deletions src/pn532.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class PN532 extends EventEmitter {
} else if (hal.constructor.name === 'Bus') {
var PN532_I2C = require('./pn532_i2c');
this.hal = new PN532_I2C(hal);
} else if (hal.constructor.name === 'Board') {
var PN532_I2C_Firmata = require('./pn532_i2c_firmata');
this.hal = new PN532_I2C_Firmata(hal);
} else {
throw new Error('Unknown hardware type: ', hal.constructor.name);
}
Expand Down
67 changes: 67 additions & 0 deletions src/pn532_i2c_firmata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use strict';
var EventEmitter = require('events').EventEmitter;
var c = require('./constants');
var logger = require('winston').loggers.get('i2c');

function sleep(time) {
return new Promise(resolve => setTimeout(resolve, time));
}

class PN532_I2C_Firmata extends EventEmitter {
constructor(board) {
super();
this.board = board;
}

init() {
logger.debug('Initializing I2C...');
// TODO: Allow pins to be configurable
const RESET_PIN = 20;
const IRQ_PIN = 21;

return new Promise((resolve, reject) => {
this.board.pinMode(IRQ_PIN, this.board.MODES.INPUT);
this.board.digitalRead(IRQ_PIN, value => {
logger.debug('IRQ', value);

// Wait for IRQ to drop low. See 6.3.3.2 of User Guide
// TODO: Allow using polling instead of IRQ pin (setInterval(..., 500))?
if (!value) {
logger.debug('i2cRead')
this.board.i2cReadOnce(c.I2C_ADDRESS, 26, (data) => {
logger.debug('Read', data);

if (data[0] & 1) { // RDY
// Ready
logger.debug('RDY bit found')

// Slice off RDY bit and convert byte array to Buffer
this.emit('data', new Buffer(data.slice(1)));
}
})
}
});

// Not sure if required. See https://github.com/adafruit/Adafruit-PN532/blob/master/Adafruit_PN532.cpp#L223
this.board.pinMode(RESET_PIN, this.board.MODES.OUTPUT);
this.board.digitalWrite(RESET_PIN, this.board.HIGH);
this.board.digitalWrite(RESET_PIN, this.board.LOW);

sleep(400).then(() => {
this.board.digitalWrite(RESET_PIN, this.board.HIGH);

sleep(10).then(() => {
logger.debug('I2C initialized.');
resolve();
})
})
});
}

write(buffer) {
logger.debug('writing...', 'length', buffer.length, buffer);
this.board.i2cWrite(c.I2C_ADDRESS, Array.from(buffer));
}
}

module.exports = PN532_I2C_Firmata;

0 comments on commit b0b4570

Please sign in to comment.