Accessing Xbox controller events in Node.JS on a Raspberry Pi
For a recent side project I needed access to events from an Xbox controller plugged into a Raspberry Pi via node.js.
For Mac I had been using the brilliant node-xbox-controller module. It had worked well, but after many hours of fighting I could not get it to work on the debain based Raspbian operating system. In the end I narrowed the problem down to something not working in the hidapi layer or below.
In order to receive the events I instead used a userspace driver called xboxdrv coupled with the node-joystick module.
This results in raw joystick events being passed into node.js. Each event has a value, a type (number or axis) and a number.
From there, I mapped each button from the raw events, into handy names using a nested structure:
var type = {
button: {
0: { 1: "a:press", 0: "a:up" },
1: { 1: "b:press", 0: "b:up" },
2: { 1: "x:press", 0: "x:up" },
3: { 1: "y:press", 0: "y:up" },
5: { 1: "rb:press", 0: "rb:up" },
4: { 1: "lb:press", 0: "lb:up" },
8: { 1: "xbox:press", 0: "xbox:up" },
6: { 1: "back:press", 0: "back:up" },
7: { 1: "start:press", 0: "start:up" }
},
axis: {
7: { 32767: "ddown:press", '-32767': "dup:press" },
6: { 32767: "dright:press", '-32767': "dleft:press" }
}
}
The map is accessed as a big flat array:
var eventIsMapped = function(event){
if (!event.init
&& type[event.type]
&& type[event.type][event.number]
&& type[event.type][event.number][event.value]
) {
return type[event.type][event.number][event.value];
} else {
return false;
}
}
This can then be used to drive further code from a single interface.
joystick.on('button', function(event) {
var action = eventIsMapped(event)
console.log(actions[action]());
});
And there we go! From there I have a separate map to go from controller buttons to actions on the hue lights. The code in use can be found on my github account