From 6cf099e9fafbb05b54c1f66d50c134be3ac15c42 Mon Sep 17 00:00:00 2001 From: Gordon Turner Date: Fri, 26 Jun 2015 08:42:57 -0400 Subject: [PATCH 1/2] Added device serial number support, enabling multiple devices. Added device serial number support, enabling multiple devices. --- lib/xbox.js | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/lib/xbox.js b/lib/xbox.js index 214947c..a89229b 100644 --- a/lib/xbox.js +++ b/lib/xbox.js @@ -23,8 +23,12 @@ function uint8Toint16(low, high) { return int16View[0]; } -function XboxController(name) { - this.name = name || 'controller'; +function XboxController(serialNumber) { + + if( serialNumber) { + this.serialNumber = serialNumber.toUpperCase(); + } + this.position = 0; for (var button in buttons) { @@ -263,12 +267,30 @@ util.inherits(XboxController, events.EventEmitter); XboxController.prototype.loadController = function () { HID.devices().forEach((function (d) { - var product = (typeof d === 'object' && d.product) || ''; - if (product.toLowerCase().indexOf(this.name.toLowerCase()) !== -1) { - this.hid = new HID.HID(d.path); - console.log(chalk.green('notice: '), 'Xbox controller connected.'); - this.emit('connected'); - location = this.hid; + + if( this.serialNumber ) + { + // If the serial number is set, look for device with that serial number. + var deviceSerialNumber = (typeof d === 'object' && d.serialNumber) || ''; + + if (deviceSerialNumber.indexOf(this.serialNumber) !== -1) { + console.log(chalk.green('notice: '), 'serial number found.'); + this.hid = new HID.HID(d.path); + console.log(chalk.green('notice: '), 'Xbox controller connected.'); + this.emit('connected'); + location = this.hid; + } + } else { + // The serial number is not set, grab the first device. + var product = (typeof d === 'object' && d.product) || ''; + if (product.toLowerCase().indexOf('controller') !== -1) { + this.hid = new HID.HID(d.path); + console.log(chalk.green('notice: '), 'Xbox controller connected, serial number: ' + + d.serialNumber); + this.serialNumber = d.serialNumber; + this.emit('connected'); + location = this.hid; + } } }).bind(this)); From 521ea67b968f39a366c8bb9a4ce1eeb9a11fec76 Mon Sep 17 00:00:00 2001 From: Gordon Turner Date: Fri, 26 Jun 2015 09:39:18 -0400 Subject: [PATCH 2/2] Updating Readme, improved multiple device handling, added example.js Updating Readme, improved multiple device handling, added example.js --- Readme.md | 20 ++++- example.js | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/xbox.js | 14 ++- 3 files changed, 272 insertions(+), 6 deletions(-) create mode 100644 example.js diff --git a/Readme.md b/Readme.md index 27b1198..f8eb859 100644 --- a/Readme.md +++ b/Readme.md @@ -49,6 +49,8 @@ xbox.on('not-found', function(){ }); ``` +Also see the `example.js` for usage. + ## LEDs Set LED pattern on controller: @@ -97,14 +99,26 @@ xbox.within('righttrigger', [50,100], function(err, data){ }); ``` -## Third Party Controllers +## Multiple Devices + +On startup, if a device is in use, it will be skipped and the next available device will be used. The serial number and +path will be printed to the console for debugging. + +Use the printed serial number to specifically address devices if required, see Serial Numbers below. -If you have a third party controller with a different name you can specify the name when creating the controller: +## Serial Numbers + +Each device has own serial number. On startup, the serial number of the device detected will be printed to the console. + +To use a specific serial number, specify it when creating the controller: ```javascript -var xbox = new XboxController('flight stick'); +var xbox = new XboxController('9BB004D0'); ``` +If you have a third party controller without 'controller' in the name, specify the device serial number to use that + device. + ## Configuring a Third Party Controller To configure a third party controller: diff --git a/example.js b/example.js new file mode 100644 index 0000000..477a748 --- /dev/null +++ b/example.js @@ -0,0 +1,244 @@ + +var XboxController = require('xbox-controller'); +var xbox = new XboxController(); + +console.log(xbox.serialNumber + ' online'); + + +/* + * A,B,X,Y buttons + */ + +xbox.on('a:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'a', action:'press' }); + console.log(message); +}); + +xbox.on('a:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'a', action:'release' }); + console.log(message); +}); + + +xbox.on('b:press', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'b', action:'press' }); + console.log(message); +}); + +xbox.on('b:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'b', action:'release' }); + console.log(message); +}); + + +xbox.on('x:press', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'x', action:'press' }); + console.log(message); +}); + +xbox.on('x:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'x', action:'release' }); + console.log(message); +}); + + +xbox.on('y:press', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'y', action:'press' }); + console.log(message); +}); + +xbox.on('y:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'y', action:'release' }); + console.log(message); +}); + + +/* + * Triggers + */ + +xbox.on('lefttrigger', function(position){ + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'lefttrigger', action:position }); + console.log(message); + + xbox.rumble(0,position); +}); + +xbox.on('righttrigger', function(position){ + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'righttrigger', action:position }); + console.log(message); + + xbox.rumble(position,0); +}); + + + +/* + * Analog sticks + */ + +xbox.on('left:move', function(position){ + if(position.x != 0 || position.y != 0) { + + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'leftmove', action:position }); + console.log(message); + } +}); + +xbox.on('right:move', function(position){ + if(position.x != 0 || position.y != 0) { + + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'rightmove', action:position }); + console.log(message); + } +}); + + +xbox.on('leftstick:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'leftstick', action:'press' }); + console.log(message); +}); + +xbox.on('leftstick:release', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'leftstick', action:'release' }); + console.log(message); +}); + + +xbox.on('rightstick:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'rightstick', action:'press' }); + console.log(message); +}); + +xbox.on('rightstick:release', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'rightstick', action:'release' }); + console.log(message); +}); + + +/* + * Top buttons + */ + +xbox.on('back:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'back', action:'press' }); + console.log(message); +}); + +xbox.on('back:release', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'back', action:'release' }); + console.log(message); +}); + + +xbox.on('xboxbutton:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'xboxbutton', action:'press' }); + console.log(message); +}); + +xbox.on('xboxbutton:release', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'xboxbutton', action:'release' }); + console.log(message); +}); + + +xbox.on('start:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'start', action:'press' }); + console.log(message); +}); + +xbox.on('start:release', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'start', action:'release' }); + console.log(message); +}); + + +/* + * D pad + */ + +xbox.on('dup:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'dup', action:'press' }); + console.log(message); +}); + +xbox.on('dup:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'dup', action:'release' }); + console.log(message); +}); + + +xbox.on('ddown:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'ddown', action:'press' }); + console.log(message); +}); + +xbox.on('ddown:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'ddown', action:'release' }); + console.log(message); +}); + + +xbox.on('dleft:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'dleft', action:'press' }); + console.log(message); +}); + +xbox.on('dleft:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'dleft', action:'release' }); + console.log(message); +}); + + +xbox.on('dright:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'dright', action:'press' }); + console.log(message); +}); + +xbox.on('dright:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'dright', action:'release' }); + console.log(message); +}); + + +/* + * Shoulder + */ + +xbox.on('rightshoulder:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'rightshoulder', action:'press' }); + console.log(message); +}); + +xbox.on('rightshoulder:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'rightshoulder', action:'release' }); + console.log(message); +}); + + +xbox.on('leftshoulder:press', function (key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'leftshoulder', action:'press' }); + console.log(message); +}); + +xbox.on('leftshoulder:release', function(key) { + var message = JSON.stringify({ serialNumber: xbox.serialNumber, button: 'leftshoulder', action:'release' }); + console.log(message); +}); + + + + + +/* + * Setup + */ + +xbox.on('connected', function() { + console.log('Xbox controller connected'); + xbox.setLed(LED) +}); + +xbox.on('not-found', function() { + console.log('Xbox controller could not be found'); +}); diff --git a/lib/xbox.js b/lib/xbox.js index a89229b..a19f08c 100644 --- a/lib/xbox.js +++ b/lib/xbox.js @@ -268,6 +268,8 @@ XboxController.prototype.loadController = function () { HID.devices().forEach((function (d) { + + try { if( this.serialNumber ) { // If the serial number is set, look for device with that serial number. @@ -276,7 +278,8 @@ XboxController.prototype.loadController = function () { if (deviceSerialNumber.indexOf(this.serialNumber) !== -1) { console.log(chalk.green('notice: '), 'serial number found.'); this.hid = new HID.HID(d.path); - console.log(chalk.green('notice: '), 'Xbox controller connected.'); + console.log(chalk.green('notice: '), 'Xbox controller connected (serial number: ' + + d.serialNumber + ', path: ' + d.path + ')'); this.emit('connected'); location = this.hid; } @@ -285,13 +288,18 @@ XboxController.prototype.loadController = function () { var product = (typeof d === 'object' && d.product) || ''; if (product.toLowerCase().indexOf('controller') !== -1) { this.hid = new HID.HID(d.path); - console.log(chalk.green('notice: '), 'Xbox controller connected, serial number: ' - + d.serialNumber); + console.log(chalk.green('notice: '), 'Xbox controller connected (serial number: ' + + d.serialNumber + ', path: ' + d.path + ')'); this.serialNumber = d.serialNumber; this.emit('connected'); location = this.hid; } } + } catch (ex) { + console.log(chalk.green('notice: '), 'Xbox controller already in use (serial number: ' + + d.serialNumber + ', path: ' + d.path + ')' ); + } + }).bind(this)); if (this.hid === false && !this._controllerLoadingInterval) {