XBox 360 wireless controller and XBox 360 wireless chatpad in Python for Ubuntu / Linux

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
djevil
User
Beiträge: 58
Registriert: Montag 22. August 2016, 14:28

Hallo,
ich habe hier leider ein sehr spezielles Problem.

Und zwar möchte ich meinen XBox 360 Controller unter Ubuntu / Linux zum Laufen bekommen.

D.h. eigentlich möchte ich das Wireless XBox 360 Chatpad unter Ubuntu / Linux zum Laufen bekommen,
der Controller funktioniert prinzipiell mit Xpad oder xboxdrv.

Dafür müsste ich wohl erstmal den XBox 360 Controller zum Leben erwecken, z.B.
den Befehl für "Rumble" an die richtige Adresse senden.

Mein bisheriger Code sieht so aus:

Code: Alles auswählen

#import uinput
import usb.core
import usb.util
import sys

## XBox 360 wireless controller and XBox 360 wireless chatpad in Python for Ubuntu / Linux

## using python3, python3-uinput, python3-usb

## remove xpad first: rmmod xpad

## find device:  lsusb
## Bus 003 Device 002: ID 045e:0719 Microsoft Corp. Xbox 360 Wireless Adapter
dev = usb.core.find(idVendor=0x045e, idProduct=0x0719)
if dev is None:
    raise ValueError('Device is not connected')

sys.stdout.write(str(dev) + '\n')
sys.stdout.write("--------------------------------" + '\n')

# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()

# get an endpoint instance
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]

ep = usb.util.find_descriptor(
    intf,
    # match the first OUT endpoint
    custom_match = \
    lambda e: \
        usb.util.endpoint_direction(e.bEndpointAddress) == \
        usb.util.ENDPOINT_OUT)

assert ep is not None

sys.stdout.write(str(ep) + '\n')
sys.stdout.write("--------------------------------" + '\n')
sys.stdout.write(str(intf) + '\n')

## ENDPOINT 0x81: Interrupt IN
## ENDPOINT 0x1: Interrupt OUT
epoint = 0x81
iface = 0

## rumble cmd
## rumble cmd in C++:  
## uint8_t rumblecmd[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, left, right, 0x00, 0x00, 0x00, 0x00, 0x00 };
dev.write(epoint, '\0x00, \0x01, \0x0f, \0xc0, \0x00, \0x00, \0x00, \0x00, \0x00, \0x00, \0x00, \0x00', iface)

Im Protocol sind noch weitere Infos, auch bezgl. des "Rumble",

http://remotors.de/XBox360Chatpad/PROTOCOL
http://remotors.de/XBox360Chatpad/usb-descriptor.txt

Wäre schön wenn mir da jemand weiter helfen könnte,
auch wenn es wohl eher unwahrscheinlich ist, das jemand gerade dasselbe Problem hat,
oder zufällig noch ein XBox wireless Controller / Chatpad da hat,

Na, ja, wenn nicht, vielleicht hilft es ja irgendwann irgendjemanden :)

Mfg

djevil
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@djevil: die Kommandos sind Bytes und nicht Strings:

Code: Alles auswählen

dev.write(epoint, bytes([0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), iface)
djevil
User
Beiträge: 58
Registriert: Montag 22. August 2016, 14:28

Ok, das gibt schonmal Hoffnung :)

Jetzt geht es noch darum die richtigen Werte für:

Code: Alles auswählen

## ENDPOINT 0x81: Interrupt IN
## ENDPOINT 0x1: Interrupt OUT
epoint = 0x81
iface = 0

## rumble cmd
## rumble cmd in C++:  
## uint8_t rumblecmd[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, left, right, 0x00, 0x00, 0x00, 0x00, 0x00 };
dev.write(epoint, bytes([0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), iface)
zu finden.
Schreiben muss ich wohl an Interrupt IN also 0x81..?

Aber was bedeutet das left, right in "uint8_t rumblecmd[]" (Steht so im source vom xboxdrv) ?

Mfg
djevil
djevil
User
Beiträge: 58
Registriert: Montag 22. August 2016, 14:28

ach, ne,

epoint = 0x1
iface = 0

## rumble cmd
dev.write(epoint, bytes([0x00, 0x01, 0x0f, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00]), iface)

funktioniert!

Super, aber erstmal genug für heute :)
djevil
User
Beiträge: 58
Registriert: Montag 22. August 2016, 14:28

Bevor ich weitermache, stellt sich mir die Frage, ob ich das Python-Skript zeitgleich mit dem xpad / xboxdrv laufen lassen kann?

Beide benutzen das selbe Interface, und sobalt ein zweites Skript/Treiber aufgerufen wird,
kommt halt "Resource busy" .

MFG
djevil
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@djevil: jedes USB-Gerät kann natürlich immer nur von einem Prozess gleichzeitig angesprochen werden. Das ist eine serielle Schnittstelle, wo ziemliches Chaos entstehen würde, würden mehrere Prozesse versuchen gleichzeitig zu kommunizieren.
djevil
User
Beiträge: 58
Registriert: Montag 22. August 2016, 14:28

Hätt ich bloß nicht gefragt.. :)
djevil
User
Beiträge: 58
Registriert: Montag 22. August 2016, 14:28

Guten Abend,

Also ich wollte jetzt die Tasten mit uinput mappen,

aber irgendwie scheint es nicht für alle Tasten codes zu geben, wie, z.B. %&# fehlen.

Öh?

Keycodes:
http://remotors.de/XBox360Chatpad/uinputKeys.py
BlackJack

@djevil: Kannst Du nicht einfach die Taste drücken und schauen welcher Code beim Rechner ankommt?

Edit: Ah, okay ich habe an das falsche Ende der Kommunikation gedacht. UInput sind keine Zeichen sondern *Tasten* auf einem Keyboard. Da gibt es keine %-Taste. Das ist die Shift-Taste und die 5-Taste die ein % erzeugt.
djevil
User
Beiträge: 58
Registriert: Montag 22. August 2016, 14:28

ja, das geht, Danke!
djevil
User
Beiträge: 58
Registriert: Montag 22. August 2016, 14:28

Ein paar Tasten fehlen mir leider noch, nämlich:

Code: Alles auswählen

<>~:ü ä ö |#
Wie kann ich die noch bekommen?

MfG djevil
Antworten