Wiimotecomm

From WiiLi

Jump to: navigation, search

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]
  1. Search for a Wiimote that is in discoverable mode
  2. Connect to it and send byte sequence "0x52 0x15 0x00" (0x52: (HID)SET_REPORT, 0x15: "Controller status", 0x00: Payload) to the Wiimote
  3. (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]
  1. Connect to Wiimote at bluetooth address 00:19:1C:2B:C9:A3
  2. Send byte sequence "0x52 0x11 0xF1" (0x52: (HID)SET_REPORT, 0x11: Set LEDs/Rumble, 0xF1: All LEDs and rumble on)
  3. Wait for 1 second (1000 milliseconds)
  4. Send byte sequence "0x52 0x11 0x10" (0x52: (HID)SET_REPORT, 0x11: Set LEDs/Rumble, 0xF1: LED 1 on, rumble off)
  5. 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)
  6. Wait for 30 seconds (30000 milliseconds), dump any incoming data
  7. (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


Personal tools
Online Casino - best online casino reviews.
Facebook Developers - facebook applications, facebook developers, facebook development, social network application development and viral widget social media strategy