From WiiBrew
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This page is intended to be a technical guide to the Wii Remote. For an excellent high-level overview of the Wii Remote (aka Wiimote), see the Wikipedia entry. New information and status updates should be posted to the Wiimote driver page, and will eventually be digested and summarized here.


   * 1 Communication
         o 1.1 HID Interface
         o 1.2 Linux Notes
         o 1.3 MacOS X Notes
         o 1.4 Windows XP Notes
   * 2 Inputs
         o 2.1 Buttons
         o 2.2 Motion Sensor
         o 2.3 IR Sensor
   * 3 Outputs
         o 3.1 Player LEDs
         o 3.2 Force Feedback
         o 3.3 Speaker
   * 4 On-board Memory
   * 5 Exjavascript:insertTags('\n== ',' ==\n','Headline text');

Level 2 headlinepansion Port

   * 6 Random Findings
   * 7 See Also:


The Wiimote communicates with the Wii via a Bluetooth wireless link. The Bluetooth controller is a Broadcom 2042 chip, which is designed to be used with devices which follow the Bluetooth Human Interface Device (HID) standard, such as keyboards and mice. The Bluetooth HID is directly based upon the USB HID standard, and much of the same documentation applies.

When queried with the Bluetooth Service Discovery Protocol (SDP), the Wiimote reports back a great deal of information, listed at Wii_bluetooth_specs#spd info. In particular it reports: Name Nintendo RVL-CNT-01 Vendor ID 0x057e Product ID 0x0306

The Wiimote does not appear to require any of the authentication or encryption features of the Bluetooth standard. In order to interface with it, one must first put the controller into discoverable mode by either pressing the 1 and 2 buttons at the same time, or by pressing the red sync button under the battery cover. Once in this mode, the Wiimote can be queried by the Bluetooth HID driver on the host. If the HID driver on the host does not connect to the Wiimote within 20 seconds, the Wiimote will turn itself off. Holding down the 1 and 2 buttons continuously will force the Wiimote to stay in discoverable mode without turning off. This does not work with the sync button, however. When in discoverable mode, all 4 of the Player LEDs will blink. [edit] HID Interface

The HID standard allows devices to be self-describing, using a HID descriptor block. This block includes an enumeration of reports that the device understands. A report can be thought of similar to a network port assigned to a particular service. Reports are unidirectional however, and the HID descriptor lists for each port the direction (Input or Output) and the payload size for each port. Like all Bluetooth HID devices, the Wiimote reports its HID descriptor block when queried using the SDP protocol. A human-readable version of the block is shown at Wii_bluetooth_specs#HID_Descriptor, and is summarized in the following table:

Output Report ID Payload Size Known Functions 0x11 1 Player LEDs, Force Feedback 0x12 2 Report type / ID 0x13 1 IR Sensor Enable 0x14 1 Enable speaker 0x15 1 Controller status 0x16 21 Write data 0x17 6 Read data 0x18 21 Speaker data 0x19 1 Mute speaker 0x1a 1 IR sensor??

Input Report ID Payload Size Known Functions 0x20 6 Expansion Port 0x21 21 Read data 0x22 4 Write data 0x30 2 Buttons only 0x31 5 Buttons | Motion Sensing Report 0x32 16 Buttons | IR?? 0x33 17 Buttons | Motion Sensing Report 0x34 21 Buttons | IR?? 0x35 21 Buttons | Motion Sensing Report 0x36 21 Buttons | IR?? 0x37 21 Buttons | Motion Sensing Report 0x3d 21 Buttons | IR?? 0x3e 21 Buttons | Motion Sensing Report | IR?? 0x3f 21 Buttons | Motion Sensing Report | IR??

Note that "Ouput" refers to packets are sent from the host to the Wiimote, and "Input" refers to packets that are sent from the Wiimote to the host. For clarity, the convention in this document is to show packets including the Bluetooth header (in parentheses), report ID (also called channel ID in some places), and payload, as described in sections 7.3 and 7.4 of the Bluetooth HID specification. Each byte is written out in hexidecimal, without the 0x prefix, separated by spaces. For example

(a1) 30 00 00

is a DATA input packet (0xa1), on channel 0x30, with the two byte payload 0x00, 0x00.

It actually seems that Force Feedback is accessible through ALL output channels the same way.

Linux Notes

On Linux hosts, the BlueZ bluetooth drivers, included in recent 2.4 and 2.6 kernels, allow communication with Bluetooth devices. The BlueZ stack includes a kernel module, hidp, which connects to Bluetooth HID-capable devices. To instruct the kernel to connect to the Wiimote, you will need the bluez-utils package, which includes the hidd daemon. First put the Wiimote into discoverable mode, then run

hidd --search

This will scan for all HID-capable devices and connect to them. After receiving the connection, the Player LEDs will continue to blink, but the Wiimote will not power down until the connection is broken. By default, hidd will maintain the connection for 30 minutes beyond the last packet exchange. Received packets can be observed using the hcidump command:

hcidump -X

Sending packets to the Wiimote requires access to the control and interrupt Bluetooth sockets established by hidd. A modified version of hidd is needed to retain these sockets, and a customized version for the Wiimote will be posted soon.

It should be noted that the HIDP driver creates a /dev/input/eventX when the Wiimote connection is established (see dmesg for a message reporting which event device it is). Preliminary tests suggest this interface is unsuitable for accessing the Wiimote because of the unusual HID information it reports. This is why a lower-level userspace daemon is thought to be required to communicate with the Wiimote directly via Bluetooth sockets.

MacOS X Notes

The Wiimote does not yet work on OS X. The Bluetooth Setup Assistant can be used to setup the connection, by selecting the "Any Device" option, and then selecting "Do not use a passkey with this device" in the Passkey options. However, due to the unusual HID descriptor for the Wiimote, OS X does not activate the Bluetooth HID driver, and the Wiimote powers off at the end of the 20 second timeout. An OS X application that connects to the Wiimote and manually reimplements the HID protocol is in progress, as described in this forum topic.

It is possible to access the Wiimote from Linux running directly on Mac hardware, or a Linux virtual machine running inside a virtualizer like Parallels. See this post for more information about how to use Bluetooth devices from a Linux VM.

Windows XP Notes

There is a Windows "driver" called GlovePIE. It can read the buttons and accelerations, and it can set the leds and the rumble.

The wiimote is accessible exacly like a USB HID device: using Delphi and the TJvHidDeviceController component. You can access all the info with the demo program (ReadWriteDemo\SimpleHIDWrite.dpr). I am using W2K.

The wiimote can be paired with Windows XP and a generic driver is installed. It appears in the game controller's panel but cannot be configured in any way.

Some people have had trouble sending reports to the Wiimote. Some people have got around this by using a different bluetooth stack. Being unable to send reports to the wiimote makes it impossible to read the acceleration data. The Bluesoleil bluetooth stack is most recommended to fix these problems. The problem of sending reports occurs with the TJvHidDeviceController component.



There are 12 buttons on the Wiimote. Four of them are arranged into a directional pad, and the rest are spread over the controller.

By default, whenever a button is pressed or released, a packet is sent to the host via HID input report 30H, with a payload containing a 2-byte bitmask with the current state of all the buttons.

The button state also seems to be included in the first two bytes of all other input reports.

Some of the bits in the first two bytes don't seem to be directly related to button presses, and are somewhat unknown.

For example, when the A button is pressed, this HID DATA input packet is received:

(a1) 30 00 08

and when it is released, this is packet received:

(a1) 30 00 00

The bit assignments (in big endian order) for the buttons are: Button Number (dec) Value (hex) Two 1 0x0001 One 2 0x0002 B 3 0x0004 A 4 0x0008 Minus 5 0x0010

? motion ? 	6 	0x0020
? motion ? 	7 	0x0040

Home 8 0x0080 Left 9 0x0100 Right 10 0x0200 Down 11 0x0400 Up 12 0x0800 Plus 13 0x1000

? motion ? 	14 	0x2000
? motion ? 	15 	0x4000
? Reading Mii ? 	16 	0x8000

The power button is unusual in that it sends a disconnect request when held down instead of emitting a normal button code.

Motion Sensor

File:Http://www.auby.no/files/wii/wiimote/Wiimote files/Wiimote axes.png Coordinate system used by Wiimote

The motion of the remote is sensed by a 3-axis linear accelerometer located slightly left of the large A button. The integrated circuit is the ADXL330 (data sheet), manufactured by Analog Devices. This device is physically rated to measure accelerations over a range of at least +/- 3g with 10% sensitivity.

Inside the chip is a small micromechanical structure which is supported by springs built out of silicon. Differential capacitance measurements allow the net displacement of the tiny mass to be converted to a voltage, which is then digitized. It is important to note that the sensor does not measure the acceleration of the Wiimote, but rather the force exerted by the test mass on its supporting springs. Due to the sign convention used, this quantity is proportional to the net force exerted by the player's hand on the Wiimote when holding it. Thus, at rest on a flat table, the accelerometer reports vertical force of +g (the mass can be normalized away into the aribitrary units), and when dropped reports a force of nearly zero.

The sensor uses a right-handed coordinate system with the positive X-axis to the left, and the positive Z-axis pointing upward, when the remote is held horizontally, as shown in the diagram at the right. Forces on each axis are digitized to 8 bit unsigned integers, with the zero scale set to 0x80. Manufacturing and calibration defects of course cause some intrinsic zero offsets. However, the Earth's gravitational field and a flat, level surface upon which to rest the remote, in principle, allow any offsets or chip skew to be measured and calibrated away in software. Decomposing the force measured by the sensor into rotation and linear components is tricky, and discussed further on the Motion analysis page.

The Wiimote does not normally report motion sensor readings to the host, but can be requested by sending SET_REPORT request to channel 0x12:

(52) 12 00 31

The 3rd byte is a bitmask. 0x01 turns on the rumble, and 0x04 turns on continuous output. If 0x04 is not set, packets are only output when the values change (almost always when the motion sensor is enabled). If 0x04 is set, values are output continuously (it's obvious when channel/mode 0x30 is chosen, which disables motion readback. With byte3=0x04, the button values are output multiple times a second. With byte3=0x00, they are output only when you press or release a button). The 4th byte specifies which HID channel to which log sensor output should be sent. After receiving this command once, the Wiimote will send back stream of DATA INPUT packets on the requested channel/mode (0x31 in the above example), where the 5th, 6th and 7th bytes contain the X, Y, and Z readings of the accelerometer. A sample packet when the Wiimote is at rest, face up, on a table is:

(a1) 31 40 20 86 8a a5

where 0x86 is the X-axis measurement, 0x8a is the Y-axis measurement, and 0xa5 is the Z-axis measurement. The first two bytes of the payload, 0x40 and 0x20, are the button values and some unknown bits. It is not known what these bits are, as they change apparently randomly with no obvious pattern. One possible explanation is that they are the LSBs of the motion sensor values. The button values are still in the same place and have the same meanings as in the Buttons section.

Other channels can be selected for motion sensor reports, including 0x31, 0x33, 0x35, 0x37, 0x3e and 0x3f. If either 0x3e or 0x3f are selected then sensor readings will alternate between the two channels. The length of the report payload will depend upon the channel, as show in the table in HID Interface section. Channels which have payloads longer than needed for the motion sensor will apparently pad the end of the packet with 0xff bytes:

(a1) 33 40 00 86 8a a5 ff ff ff ff ff ff ff ff ff ff ff ff ff

Motion sensor reports can be stopped by setting the output channel to 0x30:

(52) 12 00 30

It seems that the channel mode is actually a mode selection / bitmask. Button output is always enabled. Mode 0x30 is just buttons, 0x31 is motion sensor, 0x32 is IR camera (???), and 0x33 is both IR camera and motion sensor. The two sets of data are tacked onto each other, first the button values, then the three motion sensor bytes, then the camera bytes. Other modes seem to include motion data and / or IR data in different ways. What looks like it might be IR data is always 0xff currently, as we don't know how to enable the camera yet.

IR Sensor

During R&D, Nintendo discovered the motion sensors were not accurate enough to use the remote to control an on-screen cursor. To correct this, they augmented the remote with an infrared image sensor on the front designed to locate two IR beacons within the controller's field of view. The beacons are housed within a device misleadingly called the sensor bar. The sensor bar is powered by the Wii base unit, and contains 2 groups of IR LEDs, spaced 7.5 inches apart. Each group is composed of 5 LEDs, but homemade sensor bars have been effective with fewer LEDs, so long as the intensity is sufficient. The cable from the Wii to the sensor bar only carries power. No information is passed either to or from the sensor bar, and the intensity is not modulated in any way.

These two sources of IR light are tracked by a PixArt sensor in the front of the Wiimote housing. By tracking the locations of these two points in the sensors 2D field of view, the system can derive more accurate pointing information. Not much is known about this feature yet, but circumstantial evidence from the Nintendo/PixArt press release suggests that Nintendo is using a PixArt System-on-a-Chip to process the images on-board the Wiimote and sends the minimum information needed for tracking back to the base unit. Transmitting full 2D images constantly would require a prohibitive amount of bandwidth, especially when multiple remotes are in use.

Wiimote detects and transfers up to four IR hotspots back to the host. Various amounts of data can be requested, from position values only, position and size, to position, size and pixel value. The amount of different configurations are quite numerous, and also ties in with the connected peripheral device.

The sensitivity will likely have to be set before this will work, and there is likely some initialization required. It is possible that this data is the 0xff data seen in the longer channel reports as described in the motion section. The 0xff data does not appear unless the IR sensor has been enabled.

According to Cliff:

Set the report 0x12 to a report number such as 0x33.

You need to start by setting reports 0x13 and 0x1a to 0x04 to enable transmission.

Then to activate the IR Sensor you need to write to the wiimote's memory. Set 0x04b00030 to 1, then set the sensitivity, then set 0x04b00033 to 5, then set 0x04b00030 to 8.

The sensitivity data is 9 bytes at 0x04b00000 and 2 bytes at 0x04b0001a. For midrange sensitivity, it's {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0xaa, 0x00, 0x64}, and {0x63, 0x03}.

According to someone else:




senddata writes to 0x16









Neither of these techniques works for me.


Player LEDs

The bottom edge of the remote body contains 4 blue LEDs. These LEDs are used during normal play to indicate that the remote is in Bluetooth discoverable mode (all blinking), or to indicate the player number of the controller (one light illuminated). The LEDs are independently controllable, however, using SET_REPORT ouput packet to channel 11, which has a payload size of 1. The most-significant 4 bits control each LED, with bit 4 corresponding to the player 1 LED. Channel 11 also can control the rumble feature, so it is best to keep the 4 least-significant bits zero in order to avoid vibrating the controller. For example, this packet turns on the player 1 LED only:

(52) 11 10

Since each LED has its own bit, any combination of LEDs can be illuminated.

Force Feedback

Force feedback is provided via a "rumble pack" style device inside the Wiimote body. It is roughly an off-center weight connected to a motor which can be activated to cause the controller to vibrate. The motor can be activated by sending a SET_REPORT output packet to channels 0x11, 0x13, 0x14, 0x15, 0x19 or 0x1a with the least significant bit set:

(52) 13 01

And the vibration can be turned off by clearing the bit:

(52) 13 00

So far, it appears all channels are equivalent, though using channel 0x11 is not advised because it also controls the player LEDs. [edit] Speaker

A small speaker is embedded in the top face of the controller to provide audio feedback. The control method of this speaker is still somewhat unknown. [edit] On-board Memory

The remote carries 4 KB of on-board memory, used by the Wii to store the Mii character users can construct when playing games like Wii Sports.

We can now read data. Here's the command:

(52) 17 0r 00 FF FF SS SS

FF FF is the offset (big-endian format). SS SS is the size in bytes. The low bit of r is the usual rumble flag. Others unknown.

The responses look like this:

        btns? S  FF FF data
        vvvvv v  vv vv v------>
(a1) 21 80 00 f0 11 f0 80 6c 8c c7 c2 5d 2e bd 40 00 4e 00 99 80 08 b1                              

S is the size in bytes, minus one, for the current packet. FF is the offset of the current packet (big-endian). Everything else is the data (16 bytes max, if there is an incomplete trailer S is set to something other than 0xF and the data is padded out.)

Writing data is as follows:

        FF FF FF FF SS data
        vv vv vv vv vv v------>
(52) 16 00 00 00 00 10 57 69 69 57 69 6c 6c 52 6f 63 6b 59 6f 75 21 21

FF,SS same meaning as reading (you can only write 16 bytes at a time here, so SS is only one byte). 16 bytes of data follow. It seems we get some kind of acknowledge on Input 0x22.

The offset is 32 bits at least on the Write Data command. Offsets with the "rumble bit" set will trigger rumble. The high byte of the offset seems to specify a different memory type other than internal Flash. Offsets beginning with 0x04B00000 are used to configure the IR sensor. [edit] Expansion Port

The expansion port on the bottom of the unit is used to connect the remote to auxiliary controllers which augment the input options of the Wiimote. Auxiliary controllers use the Bluetooth interface of the remote to communicate with the Wii base unit, allowing them to be much simpler and cheaper to build. Currently available controllers are the Nunchuk and the Classic controller.

The expansion port itself is a ???-style connector with 6 contacts. Two of the contacts are slightly longer, which allows them to make contact first when a plug is inserted. Presumably these contacts carry Vcc and ground, much like standard USB connectors. The remaining 4 contacts most likely carry data, and the small number suggests that a serial interface of some sort is used. The connector is not suitable for charging the remote. More information is needed on the electrical specifications of this connector.

The status of the expansion port is indicated with report 20H. This report is sent whenever the status of the expansion port changes, or when the computer sends output report 15H to request the status.

After an attachment is plugged in or unplugged, no other reports are sent except 20H. The computer needs to send an output request (report 12H) to retrieve new input reports.

The format of input report 20H consists of the report number, then two bytes which are presumably the button state like in other reports, then a status flags byte, then two unknown 00 bytes, then a device byte.

Status byte flags bit Value (hex) Flag 0 0x01 ? 0 ? 1 0x02 any attachment plugged in 2 0x04 ? 0 ? 3 0x08 continuous output mode 4 0x10 LED 1 5 0x20 LED 2 6 0x40 LED 3 7 0x80 LED 4

Device byte values Value Device 0x00 Nothing, just the remote 0x63 Nunchuk 0x84 Classic Controller 0x85 Classic Controller 0x86 Classic Controller

For example, when the classic controller is plugged in, input report 20H is sent:

(a1) 20 00 00 02 00 00 86

The 02H indicates the classic controller has been plugged in. The 86H varies between 84H, 85H and 86H, with no apparent pattern.

When the classic controller is unplugged, input report 20H is sent again, but with 00 instead of the 02:

(a1) 20 00 00 00 00 00 84

Note that the 84H could be 84 85 or 86. It seems irrelevant which one it is. It is the 00 in the middle which is important.

The 84, 85, 86 seems to indicate the attachment. A nunchuk attachment behaves identically, except that the last byte is 63H always:

(a1) 20 00 00 02 00 00 63

Random Findings

Sending a byte to ID 0x15 returns the Extension status report (at 0x20, see above), besides setting rumble. Seems everything sets rumble if bit 0 of the first byte is set.

The third byte in the extension status report (00/02 above) can take other values. It seems only that bit is the status, other bits can take on other values depending on the bytes sent to 0x13 and 0x14. For example, sending 0x04 to ID 0x13 makes the values in byte 3 be 08/0a instead of 00/02.