In memory of Ben “bushing” Byer, who passed away on Monday, February 8th, 2016.

Difference between revisions of "Wiimote/Extension Controllers"

From WiiBrew
Jump to navigation Jump to search
(Document Balance Board extension protocol)
(→‎Balance Board: Move Balance Board extension info to the Wii Balance Board page.)
Line 168: Line 168:
  
 
= Balance Board =
 
= Balance Board =
The Balance Board extension-side is identified by the 16-bit constant 0x2A2C (0x0402 encrypted) at register address 0xa400fe. It provides four 16-bit pressure sensors. '''None of the values coming from the extension reports or register area for the Balance Board are encrypted'''.
+
The Balance Board extension is identified by the 16-bit constant 0x2A2C (0x0402 encrypted) at register address 0xa400fe. This extension is only found connected to the [[Wii Balance Board]] device, and is documented on that page.
== Data Format ==
 
The Balance Board reports its information as at least 8 bytes of data, readable at 0xa40008 and streamable using Data Reporting Modes that include Extension bytes (unused bytes are filled with 0x00). The data in the first 8 bytes is as follows:
 
 
 
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em; text-align: center;"
 
|- style="background-color: #ddd;"
 
| style="background-color: #fff;" |  
 
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center;" colspan="8"| '''Bit'''
 
|- style="background-color: #cdc;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | '''Byte'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''7'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''6'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''5'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''4'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''3'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''2'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''1'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''0'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Right'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Right'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 2
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Right'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 3
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Right'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 4
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Left'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 5
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Left'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 6
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Left'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 7
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Left'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
|}
 
 
 
The next byte and the byte after the byte after that also appear to have values, although of unknown utility.
 
 
 
== Calibration Data ==
 
 
 
Calibration Data for the Balance Board sensors is found unencrypted in the 24 bytes from 0xa40024 to 0xa4003a, as follows:
 
 
 
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em; text-align: center;"
 
|- style="background-color: #ddd;"
 
| style="background-color: #fff;" | &nbsp;
 
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center;" colspan="8"| '''Bit'''
 
|- style="background-color: #cdc;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | '''Byte'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''7'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''6'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''5'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''4'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''3'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''2'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''1'''
 
| style="border: 1px solid #ccc; padding: 0.2em; width:3.3em;" | '''0'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Right 0kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Right 0kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 2
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Right 0kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 3
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Right 0kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 4
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Left 0kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 5
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Left 0kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 6
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Left 0kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 7
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Left 0kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 8
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Right 17kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 9
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Right 17kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 10
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Right 17kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 11
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Right 17kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 12
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Left 17kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 13
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Left 17kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 14
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Left 17kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 15
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Left 17kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 16
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Right 34kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 17
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Right 34kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 18
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Right 34kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 19
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Right 34kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 20
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Left 34kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 21
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Top Left 34kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 22
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Left 34kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">15:8</span>&gt;</span>
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 23
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Bottom Left 34kg value'''<span style="color: #777;">&lt;<span style="color: #c00;">7:0</span>&gt;</span>
 
|- style="background-color: #ded;"
 
|}
 
 
 
Calculating the weight on each sensor simply involves interpolating between the two calibration values your reading falls between (or using the higher two values if your reading exceeds the highest calibration value), and the total weight on the board is the sum of these values.
 
 
 
There's still a few more bytes unknown (four following, and four preceeding) in the range 0xa40020 to 0xa4003f.
 
  
 
[[Category:Hardware]]
 
[[Category:Hardware]]

Revision as of 22:48, 31 May 2008

The Wiimote includes a 6-pin expansion port that allows external peripherals to be connected to it. Communications are bidirectional synchronous serial (the protocol is unknown), and the devices provide a virtual register block of length 0x100 that is mapped at 0xa40000 in the Wiimote's address space. Communications are encrypted, as detailed in Wiimote#Extension Controllers. Nintendo has currently released two extensions, the Nunchuk and the Classic Controller. In addition, Guitar Hero guitars also act as extension controllers. The Balance board acts like a dummy Wiimote with its own type of extension controller.

Peripheral Protocol is 400kHz "fast" I2C, with slave address 0x52. It should be possible to make homebrew peripherals; see the Tenkey project (japanese) or the Twiidler project

Nunchuk

The Nunchuk is identified by the 16-bit constant 0x0000 (0xFEFE encrypted) at register address 0xa400fe. It provides three-axis acceleration data, two digital buttons, and an X-Y analog stick.

Data Format

The Nunchuk reports its information as 6 bytes of data, readable at 0xa40008 and streamable using Data Reporting Modes that include Extension bytes (unused bytes are filled with 0x00). The data is packed into the six bytes as follows (after decryption):

  Bit
Byte 7 6 5 4 3 2 1 0
0 SX<7:0>
1 SY<7:0>
2 AX<7:0>
3 AY<7:0>
4 AZ<7:0>
5 Unknown BC BZ

SX,SY are the Analog Stick X and Y positions, while AX, AY, and AZ are the accelerometer data (in the same format as described in Wiimote#Accelerometer). BC and BZ are the state of the C and Z buttons (0=pressed).

Nintendo games calibrate the center position of the Analog Stick upon power-up or insertion of the Nunchuk.

Wireless Nunchuk

It looks like Wireless Nunchuks operate diffrent to original Nunchuk-Extension. Anyone a clue?

Classic Controller

The Classic Controller is identified by the 16-bit constant 0x0101 (0xFDFD encrypted) at register address 0xa400fe. It provides 15 buttons, two of which are analog triggers and provide both "clicked" status and a distance pressed measurement, and two X-Y analog sticks.

Data Format

The Classic Controller reports its information as 6 bytes of data, readable at 0xa40008 and streamable using Data Reporting Modes that include Extension bytes (unused bytes are filled with 0x00). The data is packed into the six bytes as follows (after decryption):

  Bit
Byte 7 6 5 4 3 2 1 0
0 RX<4:3> LX<5:0>
1 RX<2:1> LY<5:0>
2 RX<0> LT<4:3> RY<4:0>
3 LT<2:0> RT<4:0>
4 BDR BDD BLT B- BH B+ BRT 1
5 BZL BB BY BA BX BZR BDL BDU

LX,LY are the left Analog Stick X and Y (0-61), RX and RY are the right Analog Stick X and Y (0-31), and LT and RT are the Left and Right Triggers (0-31). The left Analog Stick has twice the precision of the other analog values.

BD{L,R,U,D} are the D-Pad direction buttons. B{ZR,ZL,A,B,X,Y,+,H,-} are the discrete buttons. B{LT,RT} are the digital button click of LT and RT. All buttons are 0 when pressed.

Nintendo games calibrate the center position of the Analog Sticks upon power-up or insertion of the Classic Controller.

Guitar Hero Guitar

The Guitar is identified by the 16-bit constant 0x0103 (0xFDFB encrypted) at register address 0xa400fe. It a two-axis analog thumbstick, a one-axis analog "whammy bar" and 9 buttons.

Data Format

The Guitar reports its information as 6 bytes of data, readable at 0xa40008 and streamable using Data Reporting Modes that include Extension bytes (unused bytes are filled with 0x00). The data is packed into the six bytes as follows (after decryption):

  Bit
Byte 7 6 5 4 3 2 1 0
0 SX<7:0>
1 SY<7:0>
2 Unknown
3 WB<7:0>
4 ? BD ? B- ? B+ ? ?
5 BO BR BB BG BY ? ? BU

SX,SY are the Analog Stick X and Y positions. BG,BR,BY,BB,BO are the fret buttons by color (Green, Red, Yellow, Blue, Orange). B-,B+ are the + and - buttons at the base of the controller. BU and BD are up and down on the strum bar, respectively. WB is the analog whammy bar.

Balance Board

The Balance Board extension is identified by the 16-bit constant 0x2A2C (0x0402 encrypted) at register address 0xa400fe. This extension is only found connected to the Wii Balance Board device, and is documented on that page.