Wiimotecomm
From WiiLi
Contents |
[edit] A tiny script for testing custom communication with a Wiimote
This is a tiny script for testing communication with a Wiimote, by sending custom data over a L2CAP connection.
Requires Python, PyBluez (and Linux I suppose).
[edit] Usage examples
> wimotecomm discover "52 15 00" [Searching for Wiimotes...] [Found Wiimote at address 00:19:1C:2B:C9:A3] [Connected to Wiimote at address 00:19:1C:2B:C9:A3] Send: (52) 15 00 Receive: (A1) 20 00 00 02 00 00 9C [Disconnected]
- Search for a Wiimote that is in discoverable mode
- Connect to it and send byte sequence "0x52 0x15 0x00" (0x52: (HID)SET_REPORT, 0x15: "Controller status", 0x00: Payload) to the Wiimote
- (Disconnect and Terminate)
> wimotecomm 00:19:1C:2B:C9:A3 5211F1 wait:1000 521110 52120031 wait:30000 [Connected to Wiimote at address 00:19:1C:2B:C9:A3] Send: (52) 11 F1 Receive: (A1) 20 00 00 02 00 00 9E Receive: (A1) 30 00 00 Send: (52) 11 10 Send: (52) 12 00 31 Receive: (A1) 31 00 00 85 81 98 Receive: (A1) 31 40 00 84 81 98 Receive: (A1) 31 60 00 83 81 99 Receive: (A1) 31 00 40 84 82 9A Receive: (A1) 31 60 60 84 82 9B Receive: (A1) 31 00 20 86 81 9A ... (More button and motion sensor data) Receive: (A1) 31 60 40 84 81 98 Receive: (A1) 31 00 60 84 81 9A Receive: (A1) 31 60 60 84 82 9B [Disconnected]
- Connect to Wiimote at bluetooth address 00:19:1C:2B:C9:A3
- Send byte sequence "0x52 0x11 0xF1" (0x52: (HID)SET_REPORT, 0x11: Set LEDs/Rumble, 0xF1: All LEDs and rumble on)
- Wait for 1 second (1000 milliseconds)
- Send byte sequence "0x52 0x11 0x10" (0x52: (HID)SET_REPORT, 0x11: Set LEDs/Rumble, 0xF1: LED 1 on, rumble off)
- Send byte sequence "0x52 0x12 0x00 0x31" (0x52: (HID)SET_REPORT, 0x12: Set Report ID, 0x00: No rumble, no continuous output, 0x31: Choose report ID 0x31 = Buttons and Motion Sensing)
- Wait for 30 seconds (30000 milliseconds), dump any incoming data
- (Disconnect and Terminate)
[edit] Code
#!/usr/bin/python
######################################################
# wiimotecomm 0.1.1 by Cadex #
# #
# Tiny tool for testing communication with a Wiimote #
# by sending custom data #
# #
# Requires Python an PyBluez #
######################################################
import bluetooth
import sys
import thread
import time
# Sockets and status
receivesocket = bluetooth.BluetoothSocket(bluetooth.L2CAP)
controlsocket = bluetooth.BluetoothSocket(bluetooth.L2CAP)
status = "Disconnected"
# Connect to the Wiimote at bluetooth address <address>
def connect(address):
global status
receivesocket.connect((address, 0x13))
controlsocket.connect((address, 0x11))
if receivesocket and controlsocket:
print "[Connected to Wiimote at address " + address + "]"
status = "Connected"
thread.start_new_thread(receivethread, ())
else:
print "[Could not connect to Wiimote at address " + address + "]"
# Disconnect from the Wiimote
def disconnect():
global status
status = "Disconnecting"
while status == "Disconnecting":
wait(1)
print "[Disconnected]"
# Try to discover a Wiimote
def discover():
print "[Searching for Wiimotes...]"
address = None
bluetoothdevices = bluetooth.discover_devices(lookup_names = True)
for bluetoothdevice in bluetoothdevices:
if bluetoothdevice[1] == "Nintendo RVL-CNT-01":
address = bluetoothdevice[0]
print "[Found Wiimote at address " + address + "]"
if address == None:
print "[No Wiimotes discovered. Press buttons 1 + 2 at the same time prior to running the script in order to switch Wiimote to discoverable mode]"
return address
# Create a String that is a hexdump of data
def hexdump(data):
hexdump = ""
for byte in data:
hexdump += str(byte).encode("hex").upper() + " "
return "(" + hexdump[0:2] + ")" + hexdump[2:-1]
# Thread that listens for incoming data
def receivethread():
global status
receivesocket.settimeout(0.1)
while status == "Connected":
try:
data = receivesocket.recv(23)
if len(data):
print "Received: " + hexdump(data)
except bluetooth.BluetoothError:
pass
receivesocket.close()
controlsocket.close()
status = "Disconnected"
# Send <data> to the Wiimote
def send(data):
controlsocket.send(data)
print "Sent: " + hexdump(data)
# Wait <millis> milliseconds
def wait(millis):
time.sleep(millis / 1000.0)
# Main program code
if len(sys.argv) >= 3:
address = sys.argv[1]
if address == "discover":
# Try to discover a Wiimote instead of using a certain bluetooth address
address = discover()
if address != None:
# Try to connect to Wiimote
connect(address)
if status == "Connected":
# If attempt to connect was successfull, then process all commandline arguments
for command in sys.argv[2:]:
if command[0:5] == "wait:":
# If commandline argument was of type "wait:nnnn", then wait for nnnn milliseconds
wait(int(command[5:]))
else:
# Otherwise Convert commandline argument from hex string to byte array
index = 0
data = ""
while index < len(command):
if " ()".find(command[index]) >= 0:
index = index + 1
data += command[index:index+2].decode("hex")
index = index + 2
# Send this byte array to the Wiimote
send(data)
# Wait for about 100 milliseconds for an answer
wait(100)
# Disconnect from the Wiimote
disconnect()
else:
# Print usage information
print "Usage:"
print "wiimotecomm <bluetooth address or \"discover\"> <hex bytes to send or \"wait:nnnn\">"
print
print "The hexadecimal bytes to be sent can be given with (e.g. 501100) or without spaces (e.g. \"50 11 00\")"
print
print
print "Examples:"
print "wiimotecomm discover \"52 11 11\" wait:1000 \"52 11 40\" wait:1000"
print "Search for a Wiimote; if one is found, enable the first LED and rumble, wait for 1000 milliseconds, turn rumble off again and enable the fourth LED, wait another 1000 milliseconds, then terminate"
print
print "wiimotecomm 00:19:1C:2B:C9:A3 521500"
print "Connect to the Wiimote at bluetooth address 00:19:1C:2B:C9:A3 and query the controller status"
print
print "wiimotecomm 00:19:1C:2B:C9:A3 \"52 12 00 31\" wait:30000"
print "Connect to the Wiimote at bluetooth address 00:19:1C:2B:C9:A3, choose report type 0x31 (Buttons and motion sensing), wait for 30 seconds before terminating (Any changes to button and motion status will be shown)"
[edit] Nunchuktest
This is a slightly modified version of Wiimotecomm. It repeatedly dumps the six values that define the current state of the Nunchuk:
- X and Y values of the analog stick ("X(St)" and "Y(St)")
- X, Y and Z acceleration values("X(Acc)", "Y(Acc)" and "Z(Acc)")
- The byte that contains the state of the buttons (at Bits 0 and 1)
Requires Python and PyBlueZ.
Usage: Connect Nunchuk to Wiimote, switch Wiimote to discovery mode and simply run the script:
> ./nunchuktest [Searching for Wiimotes...] [Found Wiimote at address 00:19:1C:2B:C9:A3] [Connected to Wiimote at address 00:19:1C:2B:C9:A3] X(St):6B Y(St):66 X(Acc):5F Y(Acc):5E Z(Acc):94 Buttons:11111100 X(St):6B Y(St):66 X(Acc):5E Y(Acc):5E Z(Acc):95 Buttons:11110000 X(St):6B Y(St):66 X(Acc):5E Y(Acc):5D Z(Acc):94 Buttons:00100000 X(St):6B Y(St):66 X(Acc):5E Y(Acc):5E Z(Acc):94 Buttons:11111000 X(St):6B Y(St):66 X(Acc):5E Y(Acc):5E Z(Acc):94 Buttons:01100000 X(St):6B Y(St):66 X(Acc):5C Y(Acc):5F Z(Acc):95 Buttons:01010000 X(St):55 Y(St):66 X(Acc):58 Y(Acc):5D Z(Acc):93 Buttons:00100100 X(St):09 Y(St):67 X(Acc):57 Y(Acc):59 Z(Acc):93 Buttons:00000100 X(St):09 Y(St):67 X(Acc):58 Y(Acc):58 Z(Acc):91 Buttons:10101100 (...)
#!/usr/bin/python
######################################################
# Nunchuktest 0.2 by Cadex #
# #
# Tiny tool that shows the state of the Nunchuk #
# #
# Requires Python an PyBluez #
######################################################
import bluetooth
import thread
import time
# Sockets and status
receivesocket = bluetooth.BluetoothSocket(bluetooth.L2CAP)
controlsocket = bluetooth.BluetoothSocket(bluetooth.L2CAP)
status = "Disconnected"
# Convert <value> to a binary string
def binarystring(value):
binarystring = ""
for bitindex in range(0, 8):
if value & (0x80 >> bitindex):
binarystring += "1"
else:
binarystring += "0"
return binarystring
# Connect to the Wiimote at bluetooth address <address>
def connect(address):
global status
receivesocket.connect((address, 0x13))
controlsocket.connect((address, 0x11))
if receivesocket and controlsocket:
print "[Connected to Wiimote at address " + address + "]"
status = "Connected"
thread.start_new_thread(receivethread, ())
else:
print "[Could not connect to Wiimote at address " + address + "]"
# Disconnect from the Wiimote
def disconnect():
global status
status = "Disconnecting"
while status == "Disconnecting":
wait(1)
print "[Disconnected]"
# Try to discover a Wiimote
def discover():
print "[Searching for Wiimotes...]"
address = None
bluetoothdevices = bluetooth.discover_devices(lookup_names = True)
for bluetoothdevice in bluetoothdevices:
if bluetoothdevice[1] == "Nintendo RVL-CNT-01":
address = bluetoothdevice[0]
print "[Found Wiimote at address " + address + "]"
if address == None:
print "[No Wiimotes discovered. Press buttons 1 + 2 at the same time prior to running the script in order to switch Wiimote to discoverable mode]"
return address
# Thread that listens for incoming data
def receivethread():
global status
receivesocket.settimeout(0.01)
while status == "Connected":
try:
data = receivesocket.recv(23)
if len(data):
if ord(data[1]) == 0x21:
nunchukdata = data[0xF:0x15]
for index in range(0, len(nunchukdata)):
byteval = ord(nunchukdata[index]) ^ 0x17
labels = ["X(St)", "Y(St)", "X(Acc)", "Y(Acc)", "Z(Acc)", "Buttons"]
if index == 5:
print labels[index] + ":" + binarystring(byteval),
else:
print labels[index] + ":" + ("0" + hex(byteval).upper()[2:])[-2:] + " ",
print
except bluetooth.BluetoothError:
pass
receivesocket.close()
controlsocket.close()
status = "Disconnected"
# Send <data2> to the Wiimote
def send(data2):
data = ""
for datum in data2:
data += chr(datum)
controlsocket.send(data)
# Wait <millis> milliseconds
def wait(millis):
time.sleep(millis / 1000.0)
# Main program code
# Try to discover a Wiimote instead of using a certain bluetooth address
address = discover()
if address != None:
# Try to connect to Wiimote
connect(address)
if status == "Connected":
send([0x52, 0x16, 0x04, 0xa4, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
wait(100)
while(True):
send([0x52, 0x17, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10])
wait(500)
# Disconnect from the Wiimote
disconnect()
Windows
cWiimote | GlovePIE | RMX Automation | Wiim | wiimote-api | WiinRemote | WiimoteLib
Linux
CWiid | WMD | Perlwiimote | libwiimote | lg3d-wii
OSX
DarwiinRemote | Remote Buddy | The Wiinstrument
Multiplatform
OpenPIE | Wiimote_Simple | WiiremoteJ | wiiuse | WiiJuce | WiiuseJ
PyBluez Scripts: Wiiewer | Wiimotecomm

