Ich wollte Splatoon 2 von Nintendo Switch mit einer Maus bedienen. Auf der Straße sind bereits Konverter auf dem Markt, die Nintendo-Schalter mit einer Maus bewegen können. Kommerzielle Konverter ersetzten jedoch nur die Bewegung des Sticks des Gamecontrollers durch die Bewegung der Maus (soweit ich sehen konnte). Ich dachte, dass es mit dieser Methode nicht gut funktionieren würde. Deshalb habe ich ein Gerät hergestellt, das die Bewegung des Kreisels des professionellen Controllers durch die Bewegung der Maus ersetzt.
Es wurde jedoch etwas, das ich mit meinen technischen Fähigkeiten nicht gut bedienen konnte. Ich denke, dass die Methode, die Bewegung des Kreisels durch die Bewegung der Maus zu ersetzen, praktisch ist, wenn sie gut gemacht wird. Ich werde hier veröffentlichen, was ich bisher gemacht habe.
Artikel, der sehr hilfreich war
Die Maus, die ich benutze https://www.elecom.co.jp/products/M-Y8UBXBK.html Ich denke, das ist wahrscheinlich der Fall. Wenn das von der Maus gesendete Datenformat mit dem meiner Maus übereinstimmt, wird dies meiner Meinung nach die Probleme beim Umschreiben des Python-Codes verringern, der später veröffentlicht wird.
Bitte richten Sie Rasppie ein (diesmal habe ich Raspbian als Betriebssystem gewählt). Schalten Sie die Kabelverbindung in den Nintendo Switch-Controller-Einstellungen ein. Schalten Sie den Kreisel in den Splatoon 2-Einstellungen ein. Finden Sie die Vendor ID (VID) Ihrer Maus heraus. Die VID meiner ELECOM-Maus war "04F3" Schließen Sie Ihre Maus, Tastatur und Ihren Pro-Controller an den Raspeye USB Type-A-Anschluss an. Verbinden Sie den HDMI-Anschluss 0 von Raspeye mit dem Display. Das angeschlossene Display dient zur Anzeige des Bildschirms von Raspeye. Das Display, auf dem der Spielbildschirm angezeigt wird, wird mit dem HDMI-Anschluss am Dock des Nintendo Switch verbunden. Nachdem Sie bestätigt haben, dass der Nintendo-Schalter aktiviert ist, Schließen Sie den Nintendo-Switch an den Typ-C-Anschluss an (ich habe ihn an den USB-Anschluss am Nintendo-Switch-Dock angeschlossen). Dann startet Razzpie. Fügen Sie in Raspbian dtoverlay = dwc2 zu /boot/config.txt und dwc2 und libcomposite zu / etc / modules hinzu, um das dwc2-Modul zu laden.
Seien Sie in der Lage, ein Superuser mit "su" in der Befehlszeile zu werden Erstellen Sie eine Datei mit dem Namen add_procon_gadget.sh (siehe unten) Geben Sie in der Befehlszeile "source add_procon_gadget.sh" ein
add_procon_gadget.sh
#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p procon
cd procon
echo 0x057e > idVendor
echo 0x2009 > idProduct
echo 0x0200 > bcdDevice
echo 0x0200 > bcdUSB
echo 0x00 > bDeviceClass
echo 0x00 > bDeviceSubClass
echo 0x00 > bDeviceProtocol
mkdir -p strings/0x409
echo "000000000001" > strings/0x409/serialnumber
echo "Nintendo Co., Ltd." > strings/0x409/manufacturer
echo "Pro Controller" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "Nintendo Switch Pro Controller" > configs/c.1/strings/0x409/configuration
echo 500 > configs/c.1/MaxPower
echo 0xa0 > configs/c.1/bmAttributes
mkdir -p functions/hid.usb0
echo 0 > functions/hid.usb0/protocol
echo 0 > functions/hid.usb0/subclass
echo 64 > functions/hid.usb0/report_length
echo 050115000904A1018530050105091901290A150025017501950A5500650081020509190B290E150025017501950481027501950281030B01000100A1000B300001000B310001000B320001000B35000100150027FFFF0000751095048102C00B39000100150025073500463B0165147504950181020509190F2912150025017501950481027508953481030600FF852109017508953F8103858109027508953F8103850109037508953F9183851009047508953F9183858009057508953F9183858209067508953F9183C0 | xxd -r -ps > functions/hid.usb0/report_desc
ln -s functions/hid.usb0 configs/c.1/
ls /sys/class/udc > UDC
Geben Sie in der Befehlszeile exit
ein, um zu einem normalen Benutzer zurückzukehren.
Geben Sie in der Befehlszeile "sudo dmesg | grep -A7 057e" ein.
pi@raspberrypi:~ $ sudo dmesg | grep -A7 057e
[ 7201.091044] usb 1-1.3: New USB device found, idVendor=057e, idProduct=2009, bcdDevice= 2.00
[ 7201.091060] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 7201.091074] usb 1-1.3: Product: Pro Controller
[ 7201.091087] usb 1-1.3: Manufacturer: Nintendo Co., Ltd.
[ 7201.091099] usb 1-1.3: SerialNumber: 000000000001
[ 7201.112454] input: Nintendo Co., Ltd. Pro Controller as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.3/1-1.3:1.0/0003:057E:2009.0002/input/input1
[ 7201.114447] hid-generic 0003:057E:2009.0002: input,hidraw0: USB HID v1.11 Joystick [Nintendo Co., Ltd. Pro Controller] on usb-0000:01:00.0-1.3/input0
Es gibt einen Ort, an dem hidraw0 steht. Dies ist wie eine Datei, die einen Pro-Controller darstellt. Die Zahlen unter "Hidraw" können je nach Umgebung variieren. Überprüfen Sie daher die Nummer "Hidraw".
Als nächstes findet die Maus in der Befehlszeile heraus, um welche Zahl es sich handelt
sudo dmesg | grep -A7 Ersetzen Sie den" Maus-VID "-Teil der Maus-VID
durch die Maus-VID und drücken Sie. Die VID meiner ELECOM-Maus war "04F3".
Überprüfen Sie, welche Nummer die Maus versteckt.
Erstellen Sie ein Programm, das Mausbetriebsdaten zwischen der Kommunikation zwischen dem Nintendo-Switch und dem Pro-Controller unterbricht. Erstellen Sie die unten gezeigte Python-Codedatei. (Entschuldigung für den sehr schmutzigen Code).
mouse_gyro.py
#!/usr/bin/env python3
import os
import threading
import time
import random
# Re-connect USB Gadget device
os.system('echo > /sys/kernel/config/usb_gadget/procon/UDC')
os.system('ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC')
time.sleep(0.5)
gadget = os.open('/dev/hidg0', os.O_RDWR | os.O_NONBLOCK)
procon = os.open('/dev/hidraw3', os.O_RDWR | os.O_NONBLOCK)
mouse = os.open('/dev/hidraw2', os.O_RDWR | os.O_NONBLOCK)
mouse_int = bytes([0,0,0,0])
def mouse_input():
global mouse_int
while True:
try:
mouse_int = os.read(mouse, 128)
#print('<<<', output_data.hex())
#print(output_mouse.hex())
#os.write(gadget, output_mouse)
except BlockingIOError:
pass
except:
os._exit(1)
def procon_input():
while True:
try:
input_data = os.read(gadget, 128)
#print('>>>', input_data.hex())
os.write(procon, input_data)
except BlockingIOError:
pass
except:
os._exit(1)
def convert(ou_dt_i, mo_in_i, weight, reflect):
mo_in_i = int.from_bytes(mo_in_i, byteorder='little', signed=True)
ou_dt_i = int.from_bytes(ou_dt_i, byteorder='little', signed=True)
if reflect == True:
mo_in_i = mo_in_i * -1
ou_dt_i = ou_dt_i * -1
merged_gy = ou_dt_i + mo_in_i * weight
if merged_gy > 32767:
merged_gy = 32767
elif merged_gy < -32768:
merged_gy = -32768
else:
pass
merged_gy = merged_gy.to_bytes(2, byteorder='little', signed=True)
return merged_gy
def replace_mouse(output_data, mouse_int):
#a = output_data[0:13]
#mouse no click wo migi no button ni henkan
ri_btn = 0
if mouse_int[0] == 1:#hidari click
ri_btn = 0x80#ZR button
elif mouse_int[0] == 2:#migi click
ri_btn = 0x40#R button
elif mouse_int[0] == 4:#chuu click
ri_btn = 0x08#A button
ri_btn = (output_data[3] + ri_btn).to_bytes(1, byteorder='little')
a = output_data[0:3] + ri_btn + output_data[4:13]
#kasokudo sensor ni tekitou ni atai wo ire naito setsuzoku ga kireru
if mouse_int[1] != 0:
b = 127
else:
b=0
if mouse_int[2] != 0:
b = 127
else:
b = 0
d = bytes([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
ac0 = bytes([255]) if output_data[14] + b > 255 else bytes([output_data[14] + b])
ac1 = bytes([255]) if output_data[16] + b > 255 else bytes([output_data[16] + b])
ac2 = bytes([255]) if output_data[18] + b > 255 else bytes([output_data[18] + b])
ac0_1 = bytes([255]) if output_data[26] + b > 255 else bytes([output_data[26] + b])
ac1_1 = bytes([255]) if output_data[28] + b > 255 else bytes([output_data[28] + b])
ac2_1 = bytes([255]) if output_data[30] + b > 255 else bytes([output_data[30] + b])
ac0_2 = bytes([255]) if output_data[38] + b > 255 else bytes([output_data[38] + b])
ac1_2 = bytes([255]) if output_data[40] + b > 255 else bytes([output_data[40] + b])
ac2_2 = bytes([255]) if output_data[42] + b > 255 else bytes([output_data[42] + b])
#mouse no ugoki wo gyro no ugoki ni henkan
gy0_0 = convert(output_data[19:21], mouse_int[1:2], 250, False)#
gy1_0 = convert(output_data[21:23], mouse_int[2:3], 250, False)#
gy2_0 = convert(output_data[23:25], mouse_int[2:3], 0, False)#
gy0_1 = convert(output_data[31:33], mouse_int[1:2], 250, False)#
gy1_1 = convert(output_data[33:35], mouse_int[2:3], 250, False)#
gy2_1 = convert(output_data[35:37], mouse_int[2:3], 0, False)#
gy0_2 = convert(output_data[43:45], mouse_int[1:2], 250, False)#
gy1_2 = convert(output_data[45:47], mouse_int[2:3], 250, False)#
gy2_2 = convert(output_data[47:49], mouse_int[2:3], 0, False)#
e = a+output_data[13:14]+ac0+output_data[15:16]+ac1+output_data[17:18]+ac2 \
+gy0_0+gy1_0+gy2_0 \
+output_data[25:26]+ac0_1+output_data[27:28]+ac1_1+output_data[29:30]+ac2_1 \
+gy0_1+gy1_1+gy2_1 \
+output_data[37:38]+ac0_2+output_data[39:40]+ac1_2+output_data[41:42]+ac2_2 \
+gy0_2+gy1_2+gy2_2 \
+d
print(int.from_bytes(gy1_0, byteorder='little'))
#print(mouse_int[1])
return e
def procon_output():
global mouse_int
while True:
try:
output_data = os.read(procon, 128)
#output_mouse = os.read(mouse, 128)
#print('<<<', output_data.hex())
#print(output_data)
e = replace_mouse(output_data, mouse_int)
#print(e.hex())
os.write(gadget, e)#output_data
mouse_int = bytes([0,0,0,0])
except BlockingIOError:
pass
except Exception as g:
print(type(g))
print(g)
os._exit(1)
threading.Thread(target=procon_input).start()
threading.Thread(target=procon_output).start()
threading.Thread(target=mouse_input).start()
Schreiben Sie die nächste Anzahl von Hidraws, die den Variablen "procon" und "mouse" zugewiesen sind, auf die zuvor bestätigte Nummer um.
Als nächstes schreibe ich den Python-Code neu, um den Python-Code mit dem von der Maus gesendeten Signal abzugleichen.
Die Maus, die ich benutze
https://www.elecom.co.jp/products/M-Y8UBXBK.html
Ich denke, dass dies wahrscheinlich der Fall ist, aber damit müssen Sie Ihren Code möglicherweise nicht neu schreiben.
Um herauszufinden, welche Daten Ihre Maus sendet, kommentieren Sie "#print (output_mouse.hex ())" in der Funktion "mouse_input ()" aus. Stattdessen ist es einfacher zu erkennen, ob Sie den print ()
- Teil an anderer Stelle auskommentieren.
Um diesen Python-Code auszuführen, geben Sie in der Befehlszeile "sudo python3 mouse_gyro.py" ein.
Wenn alles gut geht, können Sie den Kreisel mit der Maus unbeholfen bewegen, wie im obigen Video.
Es kommt häufig vor, dass der Pro-Controller in der Mitte getrennt wird. Befolgen Sie die Anweisungen auf dem Schalterbildschirm oder halten Sie die kleine runde Taste an der Seite des Controllers gedrückt, um den Controller neu zu registrieren. Zu diesem Zeitpunkt kann sich die nächste Anzahl von Hidraws ändern. Schreiben Sie in diesem Fall den Zuweisungsteil der Variablen "procon" des Python-Codes neu, indem Sie auf den Befehl klicken, um die oben geschriebene Hidraw-Nummer erneut zu überprüfen.
Wenn Sie das obige Video gesehen oder die Operation ausprobiert haben, werden Sie verstehen. Selbst wenn ich die Maus bewege, bewegt sich der Kreisel nicht richtig. Ich möchte um Ihre Hilfe bitten. Der Python-Code ist auf GitHub verfügbar und es gibt keine Lizenz. Sie können ihn also jederzeit ändern. Ich wäre Ihnen sehr dankbar, wenn Sie zusammenarbeiten könnten.
Danke fürs Lesen.
https://github.com/Bokuchin/SwitchProconGyroMouse
Recommended Posts