USB, NodeJS und der Raspberry Pi

 

Nach meinen letzten Experimenten mit einem XBOX360-Controller und dem USB-Shield auf einem Arduino wollte ich mal sehen ob man den Controller nicht auch an einem Raspberry Pi mit NodeJS auslesen kann. Die überlegung ist mittlerweile die Basisstation für den Roboter komplett auf einem RasPi zu realisieren. Hier sind mehr “Schweinereien” möglich als auf einem Arduino Board. Ich denke da an die Steuerung per Webinterface etc.pp.

Also “Tante Google” angeworfen und ein wenig geschaut.

Mein erster Treffer war das NodeJS-Modul “node-hid“. Das Modul soll einfachen Zugriff auf USB-HID-Devices wie Tastatur, Maus und andere Controller geben – also eigentlich auch auf den XBOX-Controller. “To cut a long story short”: Hat nicht kompiliert. Stundenlang weitergesucht und gepatch – hat dann kompiliert aber nicht funktioniert – erstmal alles in die Ecke gefeuert und andere Dinge gemacht… KACKE

Kacke

Nächster Versuch

Heute wieder ein wenig rumgesucht, sowas lässt mir ja keine Ruhe. Gibt es eine Alternative zum “node-hid” Modul?

JA! NODE-USB

Das Modul bekommt man bei Github: https://github.com/nonolith/node-usb

Also per SSH auf den Raspberry eingeloggt und schnell mal das Repo geholt:

git clone https://github.com/nonolith/node-usb

Clone node-usb

In das Verzeichnis “node-usb” gewechselt und dann die Installation gestartet:

npm install

Ergebnis:

node-usb compile error

KACKE, kompiliert wieder nicht…

Kurzer Blick auf den Fehler und ein wenig google: Das Flag “-msse2″ wird als Kompileroption auf dem raspberry nicht erkannt.

Lösung: Die Datei “binding.gyp” öffnen und beide Zeilen die “-msse2″ enthalten löschen. Dann das Unterverzeichnis “build” löschen und nochmal “npm install” laufen lassen.

node-usb done

Geht doch! Hatta fein gemacht :)

Jetzt aber

Der XBOX360-Controller hat ja wie hier schonmal beschrieben einiges an Ein- und Ausgabemöglichkeiten. 2 Joysticks, 11 Buttons, 1 Steuerkreuz und zwei analoge Taster. Dazu noch 4 Leds und 2 Motoren die den Controller durchrütteln können (sowas wie der Vibrationsalarm bei einem Handy aber viel stärker).

Das bedeutet: Auf der einen Seite möchte ich die Daten einlesen, auf der anderen Seite aber auch die LEDs und die Motoren steuern.

Die Basics

Jedes USB-Gerät hat ersteinmal zwei wichtige Informationen ohne die man eigentlich nicht viel anfangen kann: Die “Vendor ID” (kurz VID) und die “Product ID” (kurz PID). (ja, es gibt Ausnahmen, aber darauf gehe ich hier nicht ein). Die Vendor ID wird gegen Zahlung von einigen tausend Dollar vom USB-Konsortium vergeben, die Product ID kann darunter vom Hersteller selber vergeben. Mit einer entsprechenden Liste kann man anhand der VID und der PID ganz genau das Gerät herausfinden.

Für meinen Controller sind das die VID 0x045e (Microsoft) und die PID 0x028e (Xbox360 Controller). Diese Werte benötigt man später um auf das Gerät zuzugreifen.

Desweiteren hat jedes USB-Gerät ein oder mehrere Konfigurationen, dazu ein oder mehrere Interfaces mit Ein-/Ausgabe Endpunkten.

HÄ?

Ok, Beispiel – Eine USB Webcam mit Mikrofon ist das Device. Das Device hat 2 Interfaces, nämlich Interface 1 für das Bild, und Interface 2 für den Ton. Für das Betriebsystem sind diese beiden Komponenten im Prinzip zwei getrennte Geräte. Man könnte die Webcam nur als Mikrofon benutzen ohne die Kamera zu aktivieren und umgekehrt. Jedes der beiden Interfaces hat 2 Endpunkte: Einen Ausgabeendpunkt der z.B. das Bild oder den Ton sendet (je nach Interface!) und einen Eingabeendpunkt mit dem man z.B. das Mikrofon oder die Kamera ausschaltet usw.

Um rauszufinden welche Interfaces das Gerät bietet kann man unter Linux den Befehl “usb-devices” nehmen:

Wenn ich das richtig sehe hat der Controller also 4 Interfaces und insgesamt 7 Endpunkte. So, und wo kommen nun die Daten raus? Und wo kippt man die Befehle für die LEDs rein?

Detailinformationen dazu habe ich hier gefunden: http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/UsbInfo

Relevant ist nur das erste Interface. Dieses bietet genau zwei Endpunkte: Einen für die Ausgabe der Daten und einen für die Eingabe der Befehle.

Dann mal los, erstes Testscript:

Wenn man nun den Joystick bewegt oder einen Button drückt wird ein NodeJS-Buffer ausgegeben:

XBOX360 Buffer

Und wie man das Auswertet zeige ich beim nächste mal :)

 

Ein Gedanke zu „USB, NodeJS und der Raspberry Pi“

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">