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
m (Added data from two more motionplus modules)
m (The word protocol was accidentally spelled "Ppotocol" in the 3rd paragraph)
 
(32 intermediate revisions by 18 users not shown)
Line 1: Line 1:
[[File:Wii_Connector.jpg|200px|thumb|right|Pins on the Wii expansion controller cable]]The Wii Remote includes a 6-pin expansion port that allows external peripherals to be connected to it. Communications are bidirectional synchronous serial I2C, and the devices provide a virtual register block of length 0x100 that is mapped at 0xa40000 in the Wii Remote's address space (0x52 if addressed over I2C). '''Communications are encrypted''', as detailed in [[Wiimote#Extension Controllers]]. Nintendo has currently released two extensions, the [[#Nunchuk|Nunchuk]] and the [[#Classic Controller|Classic Controller]]. In addition, Guitar Hero guitars and drums also act as extension controllers, although the Rock Band guitars and drums connect using their own system. The Balance board acts like a dummy Wiimote with its own type of extension controller. There are also many third party versions of classic controllers and nunchuks.
+
[[File:Wii_Connector.jpg|200px|thumb|right|Pins on the Wii expansion controller cable]]The Wii Remote includes a 6-pin expansion port that allows external peripherals to be connected to it. Communications are bidirectional synchronous serial I2C, and the devices provide a virtual register block of length 0x100 that is mapped at 0xa40000 in the Wii Remote's address space (the 7-bit I2C address is 0x52). '''Communications are encrypted''', as detailed below. Nintendo released two extensions, the [[Wiimote/Extension Controllers/Nunchuck|Nunchuk]] and the [[Wiimote/Extension Controllers/Classic Controller|Classic Controller]]. In addition, Guitar Hero guitars and drums also act as extension controllers. The [[Wii Balance Board|balance board]] acts like a dummy Wiimote with its own type of built-in extension controller. There are also many third party versions of classic controllers and nunchuks.
  
 
The Wii Motion Plus is a small expansion which itself has an expansion port, allowing people to plug the Nunchuk into the Wii Motion Plus and the Wii Motion Plus into the Wii Remote.
 
The Wii Motion Plus is a small expansion which itself has an expansion port, allowing people to plug the Nunchuk into the Wii Motion Plus and the Wii Motion Plus into the Wii Remote.
  
Peripheral Protocol is 400kHz "fast" I2C, with slave address 0x52. It is easy to make homebrew peripherals; see the [http://www.kako.com/neta/2007-003/2007-003.html Tenkey numberpad project](japanese), [http://www.kako.com/neta/2007-004/2007-004.html gyro project](japanese), the [http://www.twiidler.org Twiidler project], [http://code.google.com/p/circle-of-current/wiki/WiiDrumController the DIY Wii drum controller], the [http://www.openchord.org OpenChord Guitar],or the [http://youtube.com/watch?v=eBN5kq_VuiU DIY Wii guitar proof of concept demo video].
+
The peripheral Protocol is 400kHz "fast" I2C, with slave address 0x52. It is easy to make homebrew peripherals; see the [http://www.kako.com/neta/2007-003/2007-003.html Tenkey numberpad project](Japanese), [http://www.kako.com/neta/2007-004/2007-004.html gyro project] (Japanese), the [http://www.twiidler.org Twiidler project], [http://code.google.com/p/circle-of-current/wiki/WiiDrumController the DIY Wii drum controller], the [http://www.openchord.org OpenChord Guitar], or the [http://youtube.com/watch?v=eBN5kq_VuiU DIY Wii guitar proof of concept demo video].
  
== Nunchuk ==
+
== Registers / Initialization ==
[[File:Wii Remote Dissection-60.jpg|200px|thumb|right|Wii 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 (Nunchuk) ===
 
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'''):
 
  
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em; text-align: center;"
+
{{BoxCenter|'''Reminder'''<br />Remember to set bit 2 (0x04) on the first byte of the Output Reports to write to registers!}}
|- 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" | '''SX'''<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;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''SY'''<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" | '''AX'''<span style="color: #777;">&lt;<span style="color: #c00;">9:2</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" | '''AY'''<span style="color: #777;">&lt;<span style="color: #c00;">9:2</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" | '''AZ'''<span style="color: #777;">&lt;<span style="color: #c00;">9:2</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="2" | '''AZ'''<span style="color: #777;">&lt;<span style="color: #c00;">1:0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="2" | '''AY'''<span style="color: #777;">&lt;<span style="color: #c00;">1:0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="2" | '''AX'''<span style="color: #777;">&lt;<span style="color: #c00;">1:0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">C</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">Z</span>
 
|}
 
SX,SY are the Analog Stick X and Y positions, while AX, AY, and AZ are the 10-bit accelerometer data (in the same format as described in [[Wiimote#Accelerometer]]).
 
  
The values returned by the analog stick in the nunchuk enclosure do not encompass the full possible range, but rather have upper and lower bounds.  These bounds seem to be in the same range across Nunchuks, but there is some variation. Analog stick X returns data from around 35 (fully left) to 228(fully right), while analog stick Y returns from around 27 to 220.  Center for both is around 128.
+
Wii Motion Plus is mapped at register 0xa60000.
  
The accelerometer data uses the full range of 0-1024.  However, the full range is only seen when moving or rotating the Nunchuk sharply.  To measure still Nunchuk rotation in space, the following approximate bounds apply: X goes from around 300 (fully tilted left) to 740 (tilted right), turning further starts bringing the value closer to 512 (neutral position). Similarly, Y goes from around 280 (tilted backwards) to 720 (forwards).  Z goes from 320 (upside-down) to 760 (right-side up).
+
Other extension Controllers are mapped at register address 0xa40000. The data is 0x100 bytes long, and it is mirrored across the entire 16-bit address space up to 0xa4FFFF. These registers are readable and writable. Communications are optionally encrypted, and explicit initialization is required to disable encryption (see below).
  
BC and BZ are the state of the C and Z buttons (0=pressed).
+
In encrypted mode, bytes can be decrypted using the following transformation:
  
Nintendo games calibrate the center position of the Analog Stick upon power-up or insertion of the Nunchuk. The mechanism for that is unknown.
+
decrypted_byte = (encrypted_byte XOR table1[address%8]) + table2[address%8]
  
=== Hardware (Nunchuk) ===
+
Where table1 and table2 are 8-byte tables calculated based on the 16-byte key sent by the host, and address is the address of the byte being read (only the bottom 3 bits matter). If the host key is 16 zero bytes, table1[x] and table2[x] are all 0x97. The value 0x17 was used previously, which is equivalent. Proof of why any two pairs of table entries a,b and x,y are equivalent if (a^b^x^y)&0x80 == 0 is left as an exercise to the reader.
 
 
[[File:Wii-Nunchuk-top.jpg|200px|thumb|right|Wii nunchuk circuit board, top surface]][[File:Wii-Nunchuk-bottom.jpg|200px|thumb|right|Wii nunchuk circuit board, bottom surface]]The official Nintendo wired nunchuk appears to be electrically much simpler than the other controller extensions. It has a single joystick comprised of a 30KΩ potentiometer per axis, two switches, an accelerometer chip, and a microcontroller.
 
 
 
{| class="wikitable" border="1"
 
! Function
 
! Hardware
 
! Circuit board surface and mounting
 
|-
 
| C
 
| [http://en.wikipedia.org/wiki/Membrane_switch membrane switch]
 
| daughterboard, [http://en.wikipedia.org/wiki/Through-hole_technology through-hole]
 
|-
 
| Z
 
| membrane switch
 
| daughterboard, through-hole
 
|-
 
| Joystick X
 
| axial [http://en.wikipedia.org/wiki/Potentiometer potentiometer], 30KΩ
 
| through-hole
 
|-
 
| Joystick Y
 
| axial potentiometer, 30KΩ
 
| through-hole
 
|-
 
| Accelerometer
 
| ST 8XRJ 3L02AE 820 MLT
 
| [http://en.wikipedia.org/wiki/Surface-mount surface mount], top
 
|-
 
| Microcontroller
 
| FNURVL 405 849KM (48-pin [http://howto.wikia.com/wiki/Howto_identify_chip_packages/Quad_package QFP])
 
| surface mount, bottom
 
|}
 
  
Like the classic controller, the joystick potentiometers appear to be wired in parallel. The accelerometer chip is in the LIS3L02 series from [http://www.st.com STMicroelectronics]. The AE variant is not on their web site; their closest public product is their [http://www.st.com/stonline/stappl/productcatalog/app?path=/comp/stcom/PcStComOPNTableView.onTheClickOfOPNLink&code=88227&producttype=product LIS3L02AT], in the same LGA-8 package, but possibly with a different pinout.
+
The calculations should be performed '''mod 256''', that is, truncated to 8 bits (in languages such as C and Python, use <span style="font-family: monospace;">&0xFF</span> or work directly with 8-bit datatypes).
  
The microcontroller chip appears to be a relabeled NEC (now [http://www2.renesas.com/micro/en/product/index.html Renesas]) uDP78F05 microcontroller, or a pin-compatible equivalent.
+
If the Wii Remote is initialized using the new method listed below, then the encryption of the extension bytes is disabled and they need not be decrypted using the transform listed above.
  
=== Wireless Nunchuks ===
+
The Wii Remote will stream data bytes from the Extension Controller starting at offset 0x08, and continuing for however many bytes the current [[Wiimote#Data_Reporting| Data Reporting Mode]] requires. Data streamed through the Input Reports must also be decrypted using the above transformation if encryption is enabled.
It looks like third-party Wireless Nunchuks operate differently than the original Nunchuk-Extension. Anyone have a clue?
 
  
==== Nyko Kama ====
+
== Identification ==
 +
Once initialized, the last '''six''' bytes of the register block identify the connected Extension Controller. A six-byte read of register 0xa400fa will return these bytes. The Extension Controller must have been initialized prior to this. There are two ways of initializing the extension.
  
The Nyko Kama is just a simple wireless Nunchuk, with a Sync and Power button. It uses two AAA batteries.
+
=== The Old Way ===
 +
The old way to initialize the extension was by writing the single encryption byte 0x00 to 0x(4)A40040, but that only works on Nintendo's own brand extensions and the GH3 Guitar, and will fail on 3rd party wireless nunchuks and GHWT extensions. If it fails, the 6 bytes will be FFFF FFFF FFFF. With this method you must decrypt the extension bytes to read them.
  
The Nyko Kama does not work with current homebrew or PC Wiimote software. It is unknown how to make it work.
+
=== The New Way ===
 +
The new way to initialize the extension is by writing 0x55 to 0x(4)A400F0, then writing 0x00 to 0x(4)A400FB. It works on all extensions, and makes the extension type bytes '''unencrypted'''. This means that you no longer have to decrypt the extension bytes using the [[#Registers / Initialization | transform]] listed above.  
  
:I was able to initialize the Kama and get data from it. My procedure is as follows: Write 0x55 to a400f0, write 0x00 to a400fb; then set up the encryption key (without it, the Nunchuk doesn't work) at a40040 (16 bytes). As a last step, set Data Reporting Mode to 0x37 (my Kama does not work when I set Data Reporting Mode prior to setting up the registers).
 
:This way, buttons are reported correctly, but the joystick values seem to be wrong. Do I need to decrypt the values? The original Nunchuk still works with this altered initialization sequence (unencrypted!).--[[User:Andyboeh|Andyboeh]] 23:45, 19 April 2009 (UTC)
 
  
==== Snakebyte Wireless Motion XS ====
+
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;"
 
+
|- style="text-align: center;"
Snakebyte is a German company that makes 3rd party Wii Remotes, Nunchuks, Classic Controllers, and Sensor Bars.
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #fdd;" | '''Encrypted'''
 
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dfd;" | '''Decrypted'''
On the Discussion page, the user "Grid" supplied the following information:
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddf;" | '''Meaning'''
(Abridged. Spelling and grammar have been corrected.)
 
 
 
:"I am using a wireless Nunchuk controller by some third party company (Snakebyte), and I was trying many, many times to get the wireless Nunchuk running on any lib out there. But anytime I plug it into my WiiMote my application slows down and I don't get any response from the Nunchuk. I've got no idea, my Wii accepts the wireless Nunchuk without any problem.
 
 
 
:I don't see any problem with any Wii game. Some WiiMote libs, which support the original Nunchuk perfectly, toggle between "nothing inserted" and "partially inserted" when the wireless Nunchuk is plugged in. Also no Data is streamed from the Nunchuk. It's extremely strange!!!! I've got no clue!
 
 
 
:I'm still trying to run a Wireless Nunchuk. One problem is that the address areas where the calibration data is normally stored is write-only on the wireless Nunchuks. But the weird thing about this wireless Nunchuk from Snakebyte [http://www.amazon.de/Wii-Nunchuk-Controller-schnurlos-wei%C3%9F/dp/B0013F4W9Q/ref=pd_bxgy_vg_img_a] is that I got no response at all until I played Metroid Prime 3 or Zelda with it. I am not kidding!!! After playing one of these games, I get all the data, only without the calibration, so I can't really use the data because I don't know how to calibrate the accelerometers and the joystick."
 
 
 
That appears to be similar behaviour to what I observed with the Datel Blade-FX as documented below. It returns 0xFF 0xFF as the extension type, but then when you try to read the calibration data it disconnects and then reconnects later, thus producing the observed "toggle between "nothing inserted" and "partially inserted" when the wireless Nunchuk is plugged in".
 
[[User:CarlKenner|CarlKenner]] 04:20, 28 November 2008 (UTC)
 
 
 
==== Datel Blade-FX ====
 
 
 
This wireless Nunchuk can emulate either a Nunchuk or a Classic Controller. At startup it behaves like a Nunchuk, but pressing the "Classic" button puts it into Classic Controller mode. While in Classic Controller mode, the FUNCTION LED will be solidly lit (red). Classic controller emulation allows it to be used in the Wii system menu, with the joystick controlling the cursor, and the Z button selecting, and the C button having no visible effect. It also allows it to work (according to the instructions) with some Virtual Console games.
 
 
 
This wireless Nunchuk also has a cheat feature that remembers a motion that you do and repeats it continuously without you having to keep doing the motion. That is done with the "FX" button.
 
 
 
There is also a "SYNC" button where the cord would be. Pressing it once connects the wireless nunchuk. While connected, the STATUS LED will slowly flash.
 
 
 
When the wireless adapter is plugged in, but the wireless nunchuk has not been synced or turned on, then it behaves as though nothing was plugged in. No status report is generated when the wireless adapter is plugged in or unplugged, unless the nunchuk is synced. Querying the status report returns 0 for the extension flag (instead of 2).
 
 
 
But when the wireless nunchuk is synced, then it sends a status report indicating that an extension is connected. Trying to read the 16 bytes from 0xF0 of the expansion (to identify the expansion) successfully returns "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF", which isn't particularly helpful. Trying to read any 16 byte block has the same effect, it returns success, but it is all FFs.
 
 
BUT... trying to read the calibration data from 0x20 or 0x30 (although it still returns success as above) causes the Nunchuk to disconnect, sending a status report to indicate no extension is plugged in. It will automatically reconnect 0.5 seconds later. While disconnected, attempting to read from the Nunchuk returns error 7.
 
 
 
Expansion data (in the input reports that include expansion data) is all 0xFF, just like trying to read the Nunchuk memory.
 
 
 
As soon as the "Classic" button is pressed, a status message is sent saying that the extension has been unplugged. It will stay "unplugged" until the status button is released again, however long they hold down the button for. Once the "Classic" button has been released, it will wait about half a second and then send a status message saying the extension has been plugged in again. If the Classic button is pressed twice before it sent the released message, then it may send another disconnect and connect message after the connect message. It is not currently possible to tell whether it is in Classic Controller or Nunchuk mode. But we can use this method to read when the "Classic" button is held down (although it will always look like it was held down longer than it really was).
 
 
 
Actually unplugging the adapter will give the same disconnect message, so after a few seconds one should assume that they did a real disconnect instead of holding down the "Classic" button. In one case, after unplugging and replugging the adapter, the BladeFX started returning all 00 instead of FF when reading the expansion type from 0xF0. The data returned from report 0x34 also had 00 00 00 as the last 3 extension bytes, even though the first 16 (starting from 0x08 in extension memory) were all FF. Trying to read the calibration from 0x20 still returned all 0xFF and then disconnected as usual. Pressing buttons on the BladeFX had no effect on the data returned in report 0x34. I have not done any additional experiments with this state yet.
 
 
 
Clearly the current method of turning on an expansion doesn't work for the Datel Blade-FX, and we need some way to turn it on. Perhaps then the calibration can be read without an error, and we can get real data.
 
 
 
It is not yet known how to make the Datel Blade-FX work, although it can be detected when it is synced, due to its strange behaviour, and the "Classic" button can be read. Nothing else is readable yet.
 
 
 
[[User:CarlKenner|CarlKenner]] 03:50, 28 November 2008 (UTC)
 
 
 
==== Datel Wireless Duo-FX ====
 
 
 
Using the standard initalization sequence, this nunchuck does not work. However, it works perfectly well with the sequence posted above for the Nyko Kama. The data is streamed unencrypted and the Datel can be fully read. However, the Nunchuk must be synced before initalizing the Extension Controller, otherwise, strange errors occur. For now, simply repeat the initialization sequence. After some tries, the Nunchuk works correctly (can be up to 10).
 
 
 
== 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 (Classic Controller) ===
 
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'''):
 
 
 
{| 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="2" | '''RX'''<span style="color: #777;">&lt;<span style="color: #c00;">4:3</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''LX'''<span style="color: #777;">&lt;<span style="color: #c00;">5:0</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="2" | '''RX'''<span style="color: #777;">&lt;<span style="color: #c00;">2:1</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''LY'''<span style="color: #777;">&lt;<span style="color: #c00;">5: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;" | '''RX'''<span style="color: #777;">&lt;<span style="color: #c00;">0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="2" | '''LT'''<span style="color: #777;">&lt;<span style="color: #c00;">4:3</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''RY'''<span style="color: #777;">&lt;<span style="color: #c00;">4:0</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="3" | '''LT'''<span style="color: #777;">&lt;<span style="color: #c00;">2:0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''RT'''<span style="color: #777;">&lt;<span style="color: #c00;">4: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;" | '''B'''<span style="color: #c00;">DR</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">DD</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">LT</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">-</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">H</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">+</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">RT</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color: #888;" | 1
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 5
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">ZL</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">B</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">Y</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">A</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">X</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">ZR</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">DL</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">DU</span>
 
|}
 
LX,LY are the left Analog Stick X and Y (0-63), 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.
 
 
 
=== Hardware (Classic Controller) ===
 
 
 
[[File:Wii Remote Classic Controller top.jpg|200px|thumb|right|Wii Classic Controller circuit board, top surface]][[File:Wii_Remote_Classic_Controller_bottom.jpg|200px|thumb|right|Wii Classic Controller circuit board, bottom surface]]The classic controller uses several different hardware parts for its various inputs.
 
 
 
{| class="wikitable" border="1"
 
! Input
 
! Hardware
 
! Circuit board surface and mounting
 
 
|-
 
|-
| A
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 0000 0000*
| [http://en.wikipedia.org/wiki/Membrane_switch membrane switch]
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0x2E2E
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | BladeFX adapter that has been initialised old way, unplugged then replugged
 
|-
 
|-
| B
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | FFFF FFFF FFFF*
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0xFFFF
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | GHWT Guitar or Drums or synced BladeFX or other wireless nunchuk initialised the old way
 
|-
 
|-
| -
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #fee;" | 0xFEFE
| [http://en.wikipedia.org/wiki/Micro_switch microswitch]
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0000
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension_Controllers/Nunchuck|Nunchuk]]
 
|-
 
|-
| Home
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #fee;" | 0xFDFD
| microswitch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0101
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension_Controllers/Classic_Controller|Classic Controller]]
 
|-
 
|-
| +
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #fee;" | 0xFDFD
| microswitch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0100 A420 0101
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension_Controllers/Classic_Controller_Pro|Classic Controller Pro]] & NES/SNES controller from the NES/SNES mini
 
|-
 
|-
| X
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #fee;" | 0xFEEB
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | FF00 A420 0013
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension_Controllers/Drawsome_Tablet|Drawsome Graphics Tablet]]
 
|-
 
|-
| Y
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #fee;" | 0xFDFB
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0103
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension_Controllers/Guitar Hero (Wii) Guitars|GH3 or GHWT Guitar]]
 
|-
 
|-
| Up
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #fee;" | 0xFDFB
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0100 A420 0103
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension_Controllers/Guitar Hero World Tour (Wii) Drums|Guitar Hero World Tour Drums]]
 
|-
 
|-
| Down
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0300 A420 0103*
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension Controllers/DJ Hero (Wii) Turntable|DJ Hero Turntable]]
 
|-
 
|-
| Left
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0111*
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension Controllers/TaTaCon|Taiko no Tatsujin TaTaCon (Drum controller)]]
 
|-
 
|-
| Right
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | FF00 A420 0112*
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| top
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension_Controllers/uDraw_GameTablet|uDraw GameTablet (Graphics tablet)]]
 
|-
 
|-
| Left joystick X
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0310*
| axial [http://en.wikipedia.org/wiki/Potentiometer potentiometer], 30KΩ
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| daughterboard, [http://en.wikipedia.org/wiki/Through-hole_technology through-hole]
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wiimote/Extension_Controllers/Densha_de_GO!_(Wii)_Shinkansen_Controller|Densha de GO! Shinkansen Controller]]
 
|-
 
|-
| Left joystick Y
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0402*
| axial potentiometer, 30KΩ
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0x2A2C
| daughterboard, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | [[Wii Balance Board]]
 
|-
 
|-
| Right joystick X
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0005*
| axial potentiometer, 30KΩ linear
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| daughterboard, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | Inactive [[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]] (Built-in)
 
|-
 
|-
| Right joystick Y
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0405*
| axial potentiometer, 30KΩ linear
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| daughterboard, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | Activated [[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]]
 
|-
 
|-
| L trigger range
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0505*
| slider potentiometer, 30KΩ linear
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| bottom, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | Activated [[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]] in Nunchuck passthrough mode
 
|-
 
|-
| R trigger range
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A420 0705*
| slider potentiometer, 30KΩ linear
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| bottom, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | Activated [[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]] in Classic Controller passthrough mode
 +
|}
 +
 
 +
(4)A60000:
 +
 
 +
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;"
 +
|- style="text-align: center;"
 +
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #fdd;" | '''Encrypted'''
 +
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dfd;" | '''Decrypted'''
 +
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddf;" | '''Meaning'''
 
|-
 
|-
| L trigger bottom-out switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A620 0005*
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| daughterboard, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | Inactive [[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]]
 
|-
 
|-
| R trigger bottom-out switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A620 0405*
| membrane switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| daughterboard, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | No-longer active [[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]]
 
|-
 
|-
| ZL
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A620 0505*
| [http://en.wikipedia.org/wiki/SPST_switch SPST] switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |
| bottom, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | No-longer nunchuk-passthrough [[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]]
 
|-
 
|-
| ZR
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" | 0000 A620 0705*
| SPST switch
+
| style="border: 1px solid #ccc; padding: 0.2em; text-align: center; background-color: #efe;" |  
| bottom, through-hole
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eef;" | No-longer classic-passthrough [[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]]
|}
 
 
 
The left and right trigger buttons are force-sensitive. As the trigger is pressed, a mechanism slides a 30KΩ linear potentiometer. However, the mechanism only uses about 1/4 of the full travel of the potentiometer. At the bottom of that travel, the mechanism actuates a switch. One might speculate that the bottom-out switch allows the controller to tolerate manufacturing differences between potentiometers without going through a calibration step. Regardless of the variation in the potentiometer, the trigger is considered fully pressed when the bottom-out switch closes.
 
 
 
It appears that all six of the potentiometers on the device: both triggers, both axes of each joystick, appear to be wired in parallel. All of the ends appear to be wired to the unit's power supply and ground, and the wiper (the electrical part that indicates the position of the slider) is probably are connected to analog-to-digital inputs on the microcontroller. Thus, one might speculate that the voltage that the microcontroller sees is between 3.3 and 0 volts. So it may be possible to repurpose these ranged inputs to measure other electrical signals in the same voltage range.
 
 
 
The through-hole switches should be easy to replace with soldered-in leads and moved to an off-board switch. Membrane switches should also be repurposable, but not as readily.
 
 
 
== Guitar Hero (Wii) Guitars ==
 
 
 
''Note: These are different from Rock Band guitars, which are USB.''
 
 
 
These Guitars are identified by the '''6''' bytes: 00 00 A4 20 01 03 at register address 0x(4)a400fa. The first 00 indicates that it is a guitar and not drums (which would be 01).
 
 
 
If you initialise the expansion the old way, by writing 0 to 0x(4)a40040, then on a Guitar Hero 3 Gibson Les Paul guitar those 6 bytes will be readable but encrypted, and on a Guitar Hero World Tour or 3rd party Guitar those bytes will be FF FF FF FF FF FF. To make a GHWT or 3rd Party guitar work, you need to write 0x55 to 0x(4)a400f0, then 0 to 0x(4)a400fb. That will allow the 6 bytes to be read, and has the side effect of making all the expansion data, including those 6 bytes, unencrypted. Testing with the old method first allows you to know whether it is a GH3 Guitar or a GHWT Guitar.
 
 
 
=== Third party ===
 
Nyko Frontman: requires the new kind of initialisation
 
 
 
MetopGame: once sold at Walmart
 
 
 
RAGE wireless guitar for Wii: Has another set of fret buttons lower down the neck, presumably these button trigger both the fret and one of the strum buttons at the same time.
 
 
 
CTA Digital Shred Axe:
 
 
 
Neutac NJoy:
 
 
 
Datel Vii:
 
 
 
TGC Wii Wireless Guitar: Has another set of fret buttons lower down, probably identical to upper buttons
 
 
 
Wii Dragon Wireless Guitar: Has another set of fret buttons lower down, probably identical to upper buttons
 
 
 
INTEC G5689 NINTENDO WII(TM) ROCK ICON GUITAR G5689:
 
 
 
Smart Guitar III:
 
 
 
=== Data Format (Guitar Hero (Wii) Guitars) ===
 
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'''):
 
 
 
{| 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; background-color: #ddd; color:#888;" | GH3
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | GH3
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''SX'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | GH3
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | GH3
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''SY'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 2
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''TB'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 3
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''WB'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 4
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">D</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">-</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">+</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 5
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">O</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">R</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">B</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">G</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">Y</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">U</span>
 
|}
 
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, on the GHWT Guitars the B- is the StarPower button. BU and BD are up and down on the strum bar, respectively. WB is the analog whammy bar. Bits marked GH3 seem to be 1 on GH3 Gibson Les Paul Guitars and 0 on GHWT Guitars.
 
 
 
TB is the analog touchbar found on the neck of the Guitar Hero World Tour Guitars, which does not exist on Guitar Hero 3 Guitars.
 
 
 
Not touching it  -  0F
 
1st (top) fret  -  04
 
1st AND 2nd      -  07
 
2nd              -  0A
 
2nd AND 3rd      -  0C/0D (keeps changing)
 
3rd              -  12/13
 
3rd AND 4th      -  14/15
 
4th              -  17/18
 
4th and 5th      -  1A
 
5th (bottom)    -  1F
 
 
 
You can hold two (touchbar) frets at once, as long as those two (touchbar) frets are adjacent, otherwise it will take the value of the lowest fret held (Eg, if you hold the highest and lowest fret, it reads 1F)
 
Note that high/low means physically on the guitar neck (in musical terms I think it's the other way around, so I thought I'd better specify)
 
 
 
== Guitar Hero World Tour (Wii) Drums ==
 
 
 
''Note: This is different from Rock Band drums, which are USB.''
 
 
 
The Drums are identified by the '''6''' bytes: 01 00 A4 20 01 03 at register address 0x(4)a400fa. The first 01 indicates that it is drums and not a guitar (which would be 00). To read these bytes unencrypted, you must first write 0x55 to 0x(4)a400f0, then 0 to 0x(4)a400fb. Trying to read the 6 bytes after initialising the old way will just return FF FF FF FF FF FF, like many other expansions.
 
 
 
=== Data Format (Guitar Hero World Tour (Wii) Drums) ===
 
The drum kit reports its information as 6 bytes of data, readable at 0x(4)a40008 and streamable using Data Reporting Modes that include Extension bytes. The Guitar Hero World Tour game uses mode 0x37 with continuous reporting. The data is packed into the six bytes as follows ('''after decryption'''):
 
 
 
{| 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; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''SX'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''SY'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 2
 
| style="border: 1px solid #ccc; padding: 0.2em;" | HHP
 
| style="border: 1px solid #ccc; padding: 0.2em;" | None
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | Which
 
| style="border: 1px solid #ccc; padding: 0.2em;" | ??
 
|- 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="3" | Softness
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="4" | 0110
 
| style="border: 1px solid #ccc; padding: 0.2em;" | ??
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 4
 
| style="border: 1px solid #ccc; padding: 0.2em;" | ??
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">-</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">+</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" | ??
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 5
 
| style="border: 1px solid #ccc; padding: 0.2em;" | <span style="color: #c00;">O</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | <span style="color: #c00;">R</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | <span style="color: #c00;">Y</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | <span style="color: #c00;">G</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | <span style="color: #c00;">B</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | <span style="color: #c00;">Bass</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
 
|}
 
|}
R, B, and G are the drum pads by colour (Red, Blue, and Green). O and Y are the cymbals. Bass is the pedal.
 
B- and B+ are the black - and + buttons behind the Wii Remote. '''They will be 0 when hit, 1 when not.'''
 
 
SX and SY are the black analog stick behind the Wii Remote. 0x20 means centered.
 
 
None will be 0 if there is velocity data, and 1 if there is none. If there is none, bytes 2 and 3 will be FF FF and contain no data, and all the ??s will be 1.
 
 
If there is velocity data, then "Which" tells you which pad it is for:
 
 
Pedal =  11011 = 27 dec, 0x1B
 
Red =    11001 = 25 dec, 0x19
 
Yellow = 10001 = 17 dec, 0x11
 
Blue =  01111 = 15 dec, 0x0F
 
Orange = 01110 = 14 dec, 0x0E
 
Green =  10010 = 18 dec, 0x12
 
 
"Softness" is how hard or soft you hit the pad. It ranges from 0 = Very hard to 6 = very soft, with 7 = not hit at all
 
 
"HHP" is 0 if the velocity data is for the hi-hat pedal (unmarked 3.5mm jack above bass pedal jack), and 1 otherwise. When hi-hat pedal data is sent, "Which" is set as it is for the bass drum pedal (ie 11011). The velocity varies according to how far the pedal is pressed. The pedal to connect to the jack is not the same as the bass drum pedal; it must be a some sort of variable resistor (varying between 20k Ohms when down and 40 Ohms when up seems to give a good spread of velocity values from 0 to 7). The messages are not always sent and are delayed by around 35ms (probably due to the home-made pedal I'm using working wrong).
 
 
"0110" is 0110 if there is velocity information, or 1111 if there is not. Its meaning is unknown.
 
 
The data in the "??" bits is also unknown, although they are always 1 if there is no velocity data.
 
 
''Thanks to Metallica1969, death_au, l0stsign, MonkeyJamboree and Carl Kenner.''
 
 
 
 
== DJ Hero Wii ==
 
 
This is the turntable for the DJ Hero Wii game. The Wii Remote plugs in to the slot under the black flap at the top, with the buttons facing up and the DPad on the left.
 
 
Not only can the turntable be plugged into either side to choose left or right handed use, it seems you could actually plug two turntables (if you own two) into the one controller at once, so there is a turntable on either side. You can then read both turntables individually.
 
 
The turntable(s) can spin forever in either direction.
 
 
=== Data Format (DJ Hero Turntable) ===
 
 
{| 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="2" | '''RTT'''<span style="color: #777;">&lt;<span style="color: #c00;">4:3</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''SX'''<span style="color: #777;">&lt;<span style="color: #c00;">5:0</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="2" | '''RTT'''<span style="color: #777;">&lt;<span style="color: #c00;">2:1</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''SY'''<span style="color: #777;">&lt;<span style="color: #c00;">5: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;" | '''RTT'''<span style="color: #777;">&lt;<span style="color: #c00;">0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="2" | '''ED'''<span style="color: #777;">&lt;<span style="color: #c00;">4:3</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="4" | '''CS'''<span style="color: #777;">&lt;<span style="color: #c00;">3:0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; | '''RTT'''<span style="color: #777;">&lt;<span style="color: #c00;">5</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="3" | '''ED'''<span style="color: #777;">&lt;<span style="color: #c00;">2:0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''LTT'''<span style="color: #777;">&lt;<span style="color: #c00;">4: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; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''LB'''<span style="color: #c00;">R</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">-</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">+</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''RB'''<span style="color: #c00;">R</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; | '''LTT'''<span style="color: #777;">&lt;<span style="color: #c00;">5</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;" | '''LB'''<span style="color: #c00;">B</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''RB'''<span style="color: #c00;">G</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">E</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''LB'''<span style="color: #c00;">G</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''RB'''<span style="color: #c00;">B</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
|}
 
 
BE is for Euphoria button
 
 
CS : Crossfade Slider, lower is left and upper is right
 
 
SX and SY are the black analog stick.
 
 
ED is the Effect Dial
 
 
RTT is the turntable on the right as a 6-bit signed integer (positive = CW; negative = CCW)
 
 
RBG,RBR,RBB are the Green, Red and Blue buttons on the right
 
 
LTT is the turntable on the left as a 6-bit signed integer (positive = CW; negative = CCW)
 
 
LBG,LBR,LBB are the Green, Red and Blue buttons on the left
 
 
== 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.
 
 
== Wii Motion Plus ==
 
The Wii Motion Plus starts off at register 0xA60000 instead of register 0xA40000, because it has its own extension port on the back allowing a Nunchuk for example to be plugged in along with the Wii Motion Plus. BUT it changes to 0xA40000 once it is activated by writing 04 to 0xa600fe.
 
 
The Wii Motion Plus is first identified by the 6 bytes: 00 00 A6 20 00 05 at register address 0x(4)a600fa (instead of 0x(4)a400fa like a regular extension). Games attempt to detect the Wii Motion Plus by trying to read the two-byte expansion identifier at 0xA600FE (they try up to 3 times, then wait 8 seconds, then check again). If a Wii Motion Plus is not present, or it has already been activated, then the attempt to read those bytes will fail with error 7.
 
 
The extension is initialised by writing 0x55 to 0x(4)a600f0. But there is no need to write 00 to 0x(4)a500fb, since Wii games don't do that. While the Motion Plus is initialising, the value at 0x(4)a600f7 changes from 0x02 to 0x04 to 0x08 to 0x0C to 0x0E then stays at 0x0E. There is no need to read this byte, since games don't. While initialising, the 128 bytes from 0x(4)a60050 - 0x(4)a600cf also change briefly, but randomly, after the extension is initialized. More examples of this data block changing over time can be found here: [https://docs.google.com/Doc?id=dds4pks_606fmcd6zwt&hl=en Three Data Samples from Wii Motion Plus (Google Doc)]
 
 
It appears that the 32 bytes from 0x(4)a60020 are, as usual, calibration information, but it is unknown how they work.
 
 
Writing 0x04 to 0x(4)A600FE activates the MotionPlus as the "active" extension. This does 3 things (with no additional initialization):
 
* A status report (0x20) will automatically be sent indicating that a normal extension has been plugged in, if and only if there was no extension plugged into the MotionPlus pass-through extension port.
 
* The standard extension identifier at 0x(4)A400FA now reads 00 00 A4 20 04 05
 
* Extension reports now contain MotionPlus data.
 
 
Writing 0x55 to 0x(4)A400F0 deactivates the MotionPlus, and activates the Nunchuk or other extension plugged into the back of the Motion Plus. It does these things (with no additional initialization):
 
* A status report (0x20) will always be sent indicating that a normal extension has been unplugged.
 
* The Motion Plus extension identifier at 0x(4)A600FA now reads 00 00 A6 20 04 05
 
* Another status report (0x20) will always be sent indicating that a normal extension has been plugged in.
 
* The standard extension block at 0x(4)A40000 now reads from the Nunchuk (or other extension)
 
* Extension reports no longer contain MotionPlus data
 
 
 
 
It is possible to read from both Motion Plus and an extension controller at the same time by activating the MotionPlus in one of the pass-through modes suggested by DogP. When activated, this interleaves extension controller data with MotionPlus data on every other read. Data passing through are modified to make room for 3 bookkeeping bits. Two pass-through modes are currently known, one with modifications adapted to the NunChuck, and one with modifications adapted to the Classic Controller (but suitable for Guitar, Drums, or Turntable).
 
 
Nunchuck pass-through mode :
 
* Activated by writing 0x05 instead of 0x04 to 0x(4)A600FE
 
* Data passing through drops the least significant bit of the three accelerometer values
 
* Bit 7 of byte 5 is moved to bit 6 of byte 5, overwriting it
 
* Bit 0 of byte 4 is moved to bit 7 of byte 5
 
* Bit 3 of byte 5 is moved to bit 4 of byte 5, overwriting it
 
* Bit 1 of byte 5 is moved to bit 3 of byte 5
 
* Bit 0 of byte 5 is moved to bit 2 of byte 5, overwriting it
 
 
Classic Controller or Musical Instrument pass-through mode:
 
* Activated by writing 0x07 instead of 0x04 to 0x(4)A600FE
 
* Data passing through drops the least significant bit of the axes of the left (or only) joystick
 
* Bit 0 of Byte 4 is overwritten
 
* Bits 0 and 1 of Byte 5 are moved to bit 0 of Bytes 0 and 1, overwriting what was there before
 
 
There is no requirement to use the correct mode for the extension, but otherwise the bitshift/move wouldn't make sense. Using the Nunchuk in classic controller mode would clobber a significant bit in the middle of the Z acceleration. Using the Classic controller in Nunchuk mode would clobber some of the buttons.
 
 
 
=== Data Format (Wii Motion Plus) ===
 
 
The Wii Motion Plus reports its information as 6 bytes of data, readable at 0x(4)a40008 (or 0x(4)a40000 in some cases) 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:
 
 
{| 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" | '''Yaw Left Speed'''<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;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''Roll Left Speed'''<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" | '''Pitch Down Speed'''<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;" | 3
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="6" | '''Yaw Left Speed'''<span style="color: #777;">&lt;<span style="color: #c00;">13:8</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''Yaw slow mode'''
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''Pitch slow mode'''
 
|- 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="6" | '''Roll Left Speed'''<span style="color: #777;">&lt;<span style="color: #c00;">13:8</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''Roll slow mode'''
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''Extension connected'''
 
|- 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="6" | '''Pitch Down Speed'''<span style="color: #777;">&lt;<span style="color: #c00;">13:8</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
|}
 
 
While the Wiimote is still, the values will be about 0x1F7F (8,063), although it is best to calibrate for a few seconds every time you start, to get the actual zero values.
 
 
Voltage reference is 1.35V that you can assume it as 8192 unit (half of the ADC range), using 2.7272 mV/deg/s, 8192 is 594 deg/s (1.35v/2.72mv), you must divide by  ~13.79 unit/deg/s (594/8192) to know the correct deg/s.
 
 
At high speed (slow bit = 0) raw values read are small with the same deg/s to reach higher values on top, so you must multiply it by 2000/440 (they are the max reference in the two modes in deg/s [http://invensense.com/mems/gyro/idg650.html]). Example: reading 8083 raw value and assuming 8063 as zero, 20 unit in slow/normal mode are 1,45 deg/s and in fast mode are 1.45*2000/440=6.59 deg/s.
 
 
Yaw/Roll/Pitch fast/slow bits are 1 when the Wii Remote is rotating slowly (or not rotating at all), 0 when the Wii Remote is rotating fast.
 
 
Extension connected is 1 when an extension is connected to the MotionPlus extension port.
 
 
Note: The definition of yaw, pitch, and roll, are slightly different for the gyros and accelerometers. Accelerometers measure angles relative to gravity. Gyros measure angles relative to the Wii Remote. If the Wii Remote is up the right way, then they are the same. But if the Wii Remote is on its side, then what the gyros call "pitch" is actually what the accelerometers would call "yaw".
 
 
The correct way to measure orientation is to maintain a rotation matrix (or alternatively a quaternion) of the current orientation (relative to gravity), and update it each time you get a gyro reading. It will drift a little, so you should reset the matrix's pitch and roll (but not yaw) with the values from the accelerometers whenever the accelerometers and gyros indicate no movement. After significant rotation, you should reset the matrix's yaw to zero when the Wii Remote is pointing near the middle (horizontally) of the sensor bar.
 
 
 
==== Nunchuck pass-through mode ====
 
 
In this mode, MotionPlus data and modified Nunchuck data are interleaved. The data format for the Motion Plus does not change. Here is the data format '''for the Nunchuck''' in this mode:
 
 
 
{| 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" | '''SX'''<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;" | 1
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="8" | '''SY'''<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" | '''AX'''<span style="color: #777;">&lt;<span style="color: #c00;">9:2</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" | '''AY'''<span style="color: #777;">&lt;<span style="color: #c00;">9:2</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="7" | '''AZ'''<span style="color: #777;">&lt;<span style="color: #c00;">9:3</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''Extension connected'''
 
|- 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="2" | '''AZ'''<span style="color: #777;">&lt;<span style="color: #c00;">2:1</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="1" | '''AY'''<span style="color: #777;">&lt;<span style="color: #c00;">1</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="1" | '''AX'''<span style="color: #777;">&lt;<span style="color: #c00;">1</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">C</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">Z</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
|}
 
 
 
Note that AZ, BC and BZ  and the least significant bits of AX, AY and AZ are moved. Also, the least significant bit of each accelerometer axis are lost, consider them 0 to keep 10 bit values. Extension connected is usually 1.
 
 
Bit 1 of Byte 5 is used to determine which type of report is received : it is 1 when it contains MotionPlus Data and 0 when it contains extension data.
 
 
==== Classic Controller pass-through mode ====
 
 
In this mode, MotionPlus data and modified Classic Controller data are interleaved. The data format for the Motion Plus does not change. Here is the data format '''for the Classic Controller''' in this mode:
 
 
 
{| 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="2" | '''RX'''<span style="color: #777;">&lt;<span style="color: #c00;">4:3</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''LX'''<span style="color: #777;">&lt;<span style="color: #c00;">5:1</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">DU</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="2" | '''RX'''<span style="color: #777;">&lt;<span style="color: #c00;">2:1</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''LY'''<span style="color: #777;">&lt;<span style="color: #c00;">5:1</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">DL</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;" | '''RX'''<span style="color: #777;">&lt;<span style="color: #c00;">0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="2" | '''LT'''<span style="color: #777;">&lt;<span style="color: #c00;">4:3</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''RY'''<span style="color: #777;">&lt;<span style="color: #c00;">4:0</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="3" | '''LT'''<span style="color: #777;">&lt;<span style="color: #c00;">2:0</span>&gt;</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" colspan="5" | '''RT'''<span style="color: #777;">&lt;<span style="color: #c00;">4: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;" | '''B'''<span style="color: #c00;">DR</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">DD</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">LT</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">-</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">H</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">+</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">RT</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''Extension connected'''
 
|- style="background-color: #ded;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eee;" | 5
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">ZL</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">B</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">Y</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">A</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">X</span>
 
| style="border: 1px solid #ccc; padding: 0.2em;" | '''B'''<span style="color: #c00;">ZR</span>
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd; color:#888;" | 0
 
|}
 
 
 
Note that BDL and BDU are moved, and each axis of the left joystick loses its least significant bit. Extension connected is usually 1.
 
 
Bit 1 of Byte 5 is used to determine which type of report is received : it is 1 when it contains MotionPlus Data and 0 when it contains extension data.
 
 
=== Hardware (Wii Motion Plus) ===
 
[[File:Wii_MotionPlus_top.jpg|200px|thumb|right|Wii Motion Plus, circuit board, top]][[File:Wii_MotionPlus_bottom.jpg|200px|thumb|right|Wii Motion Plus, circuit board, bottom]]The Wii Motion Plus contains two gyro sensors: A dual-axis gyro by InvenSense, the [http://www.invensense.com/products/idg_600.html IDG-600](pitch and roll), and a single-axis gyro by EPSON TOYOCOM labelled ''X3500W'' (yaw).
 
 
Until its release it was speculated that only a dual-axis gyro was included in the Wii Motion Plus. The combined use of a dual-axis gyro and a single-axis gyro is what enables the Wii Motion Plus to report the angular rate in all three axis, thus allowing full orientation tracking.
 
 
Specifications of the X3500W are currently unknown, but may be similar to the specifications of the similarly named [http://www.epsontoyocom.co.jp/english/product/Sensor/set01/xv3500cb/index.html XV-3500CB] (same manufacturer.)
 
 
Wii MotionPlus contains RVL-GU chip and EEPROM. RVL-GU chip is a microprocessor NEC 78K0/KC2. It has two firmware modes. I2C bus repeater mode and 'Activated' Gyro mode.
 
[http://www.kako.com/neta/2009-017/2009-017.html Wii_motion_plus_kaiseki] (japanese)
 
 
=== Information ===
 
 
When not activated, the MotionPlus is detected by regular polling (every 8 seconds or so) of 0x(4)a600fe. Writing 0x55 to 0x4A400F0, then 0x00 to 0x4A400FB (standard extension init, works fine even with no extension) re-activates the standard extension, if any, plugged into the MotionPlus pass-through port. The development version of the CWiid driver currently implements this method (without automatic 8 second checks) on the motionplus branch: http://abstrakraft.org/cwiid/browser/branches/motionplus/. Additional information on MotionPlus workings and implementation requirements are at http://abstrakraft.org/cwiid/wiki/MotionPlus.
 
  
The combination of 3 linear accelerations with 3 angular rates allows what Nintendo refers to as 1:1 motion tracking, which is another way of saying 6DOF (degrees of freedom) over a short time. It's only valid over short times because of the integration involved to convert accelerations and rates into positions (input errors, when integrated, blow up over time).
 
  
In addition to providing yaw, the gyros also allow the software to tell the difference between orientation and acceleration, which are difficult to tell apart from the accelerometers which measure a mixture of both.
+
The values marked with a * are actually already unencrypted, and should not be decrypted. They are given here along with unencrypted version for those wanting to use simplified detection code. You can easily tell whether a value should be decrypted or not by looking at the other values in the 0xa400fa to 0xa400fd region.
  
[http://www.ailive.net/lm2.html Wii Motion Plus Documentation at AiLive]
+
The "Partially inserted" condition allegedly occurs when the connector is loose or has a bad connection. Usually, this will correct itself upon full insertion. However, it has been known to "stick" in the partially inserted state rarely. This is a hardware glitch, the fix is to simply disconnect and reconnect the Extension Controller. Third party controllers such as wireless nunchuks also return this value if initialized with the old method, in which case the whole last 16 bytes will be FF.  
  
 +
Contrary to previous documentation, the 0000 0000 0000 value does NOT occur when nothing is inserted. Instead you get error 7 when you try to read the expansion type. A successful 0000 0000 0000 only occurs when a BladeFX wireless nunchuk is synced, initialized with the old method, then the adapter is unplugged, then the adapter is replugged.
  
Reading 0x100 bytes from 0x(4)a60000 produces the following:
+
A [[Wii Balance Board]] extension is only found in a Wii Balance Board. Although it exposes functionality as an Extension Controller, they are not separable and this controller is documented separately.
  
<pre>
+
=== Data format code ===
4a60000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
After some research of [https://www.nintendo.co.jp/support/oss/index.html NES/SNES Classic Mini's Classic Controller driver source code], it turned out that the penultimate byte of the register block identify (e.g. the byte at offset 0x(4)A400FE) is data format code. So 0x00 is the [[Wiimote/Extension Controllers/Nunchuck|Nunchuck]] data format and 0x01 is the default [[Wiimote/Extension Controllers/Classic Controller|Classic Controller]] data format. Actually, this byte is writable for some controllers. So, official Classic Controller supports data formats 0x01, 0x02 and 0x03. Most old third party Classic Controllers supports only 0x01, NES/SNES Classic Mini tries to set the data format byte to 0x03, that's why most of them don't work. Guitar Hero controller uses mode 0x03 by default, so it shares the data format with Classic Controller, that's why guitar can be used in Wii's main menu.
4a60010: 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff
 
4a60020: 78 d9 78 38 77 9d 2f 0c cf f0 31 ad c8 0b 5e 39
 
4a60030: 6f 81 7b 89 78 51 33 60 c9 f5 37 c1 2d e9 15 8d
 
4a60040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a60050: b9 3f 25 93 9d 17 bb 9c 05 9d c3 38 18 3c ba 33
 
4a60060: ba 18 d1 7a bc 03 d3 55 32 ec 81 38 7d a6 77 a8
 
4a60070: 4c e6 c7 11 7c 50 78 80 77 35 08 81 f6 14 4e 67
 
4a60080: d4 b5 cb de 6a 54 5f 66 3c c4 25 fd 33 da 1d 75
 
4a60090: 58 98 15 6d 5e 63 51 ee 8f dd 3a b2 94 fe 5b 58
 
4a600a0: bf 17 91 78 7f 84 b4 9b b0 f9 75 c2 2e 7f 1f ed
 
4a600b0: e5 6b 02 f4 f2 7d 74 17 3d 23 35 5c e0 72 22 6e
 
4a600c0: 3b a7 7b 65 6c 3c 72 7e 5b ae e7 09 09 f0 01 00
 
4a600d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a600e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a600f0: 55 ff ff ff ff ff ff 10 ff ff 00 00 a6 20 00 05
 
</pre>
 
  
A different (Carl Kenner's) Wiimote and Motion Plus:
+
=== Encryption setup ===
<pre>
+
After the identification is read, the encryption can be set up if required. This is done by enabling encryption by writing 0xAA to extension register 0xF0, and then writing the 16-byte key to register 0x40. The key is written in 3 blocks of 6, 6, and 4 bytes. (Writing a single encryption byte to register 0x40 will work on genuine Nintendo controllers, but not on others). After this the extension can be operated in full encryption mode.
4a60000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
4a60010: 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff
 
4a60020: 79 83 73 54 72 E8 30 C3 CC 4A 34 FC C8 4F CC 5B
 
4a60030: 77 49 75 A4 73 9A 35 52 CA 22 37 26 2D E5 B5 A2
 
4a60040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a60050: 78 76 DD F5 6A 3C CF F7 2A 0E 32 EE 82 FE 2E FD
 
4a60060: 19 E7 0A CA 67 3B 3A 75 F6 45 55 8E 9D 33 CC EA
 
4a60070: 6E 52 C6 C6 16 9B EE 12 2E 3F 77 B1 A1 80 0B 0E
 
4a60080: C2 25 05 EA C3 2F 85 1E 31 53 74 C7 F1 93 F1 2D
 
4a60090: C1 6D 84 2A D8 6F 8A E5 2D 3B 7B CC D2 59 D5 D1
 
4a600A0: 9F 5B 6F AE 82 DE EA C3 73 42 06 A9 77 FF 61 A8
 
4a600B0: 1A 70 E4 16 90 7A 80 F7 79 4B 41 18 82 6C 62 1A
 
4a600C0: 3B BF FC FF 2C F2 32 97 B8 2F 17 E7 BD 35 1D 0A
 
4a600d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a600e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a600f0: 55 ff ff ff ff ff ff 10 ff ff 00 00 a6 20 00 05
 
</pre>
 
  
Two more:
+
== List of extension controllers ==
<pre>
+
*[[Wiimote/Extension Controllers/Nunchuck|Nunchuck]]
4a60000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
*[[Wiimote/Extension Controllers/Classic Controller|Classic Controller]] ([[Wiimote/Extension Controllers/Classic Controller Pro|Pro]])
4a60010: 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff
+
*[[Wiimote/Extension_Controllers/Drawsome_Tablet|Drawsome Graphics Tablet]]
4a60020: 7a 1a 79 ac 79 86 2f 2c d3 6a 2e ed c8 03 67 3c
+
*[[Wiimote/Extension Controllers/Guitar Hero (Wii) Guitars|Guitar Hero (Wii) Guitars]]
4a60030: 6b d2 7b cf 7b 05 35 1c cd 3c 34 88 2d b6 c9 e8
+
*[[Wiimote/Extension Controllers/Guitar Hero World Tour (Wii) Drums|Guitar Hero World Tour (Wii) Drums]]
4a60040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+
*[[Wiimote/Extension Controllers/DJ Hero (Wii) Turntable|DJ Hero (Wii) Turntable]]
4a60050: 69 cf 84 40 81 7b e2 6b 9a d7 95 c6 36 6e 98 38
+
*[[Wiimote/Extension Controllers/TaTaCon|Taiko no Tatsujin (Wii) TaTaCon (Drum controller)]]
4a60060: 8d 50 41 45 f5 aa 3f b6 f7 2b 6e 55 6a 72 00 f8
+
*[[Wiimote/Extension Controllers/Wii Motion Plus|Wii Motion Plus]]
4a60070: 79 4f bd 5f 51 34 b5 6e f5 2e 6d fb a3 10 05 b0
 
4a60080: c9 c7 68 2c ef d9 e0 2c 3f ce e8 3c b8 21 61 3f
 
4a60090: b7 6d 18 44 07 af 5b 01 3e 1c 40 83 d3 f2 89 d0
 
4a600a0: 76 55 f9 ac e8 03 0a 16 f9 92 b0 59 49 69 3b 04
 
4a600b0: d8 d1 fe 39 b1 23 5c f7 fc 40 36 c9 34 c8 31 e7
 
4a600c0: f4 0d cc 4d f3 e6 f5 10 b6 1f 76 18 d1 42 32 0c
 
4a600d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a600e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a600f0: 55 ff ff ff ff ff ff 10 ff ff 00 00 a6 20 00 05
 
</pre>
 
and
 
<pre>
 
4a60000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
4a60010: 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff
 
4a60020: 7c 3a 77 b1 77 e3 2f 56 d4 4b 31 13 c8 03 04 8c
 
4a60030: 83 ca 79 4b 7a 68 34 ef d1 2a 34 58 2d b4 12 41
 
4a60040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a60050: f9 f4 30 55 14 64 20 2d e3 f0 7b 30 49 dc 52 17
 
4a60060: 15 ab e0 78 39 2c 9a 30 6b 93 24 83 b4 88 6f 07
 
4a60070: 3e 94 17 b5 cf 8b 1f c8 50 a4 6a 15 49 71 99 49
 
4a60080: 39 5c d1 f8 43 f4 f9 a9 67 e1 7b a6 11 e5 66 7e
 
4a60090: fb 1c 6e 6b 97 a7 f8 6e 9f 5a c7 7b c2 7b 82 cb
 
4a600a0: 17 44 e3 66 ef 03 25 ea 01 36 a7 a7 08 6f bd 69
 
4a600b0: a5 3f 02 5c 49 00 23 89 9d 35 36 a7 31 fb eb 77
 
4a600c0: a5 c3 c5 d8 3d 95 4c 76 f4 74 b4 ba 5b 09 25 1f
 
4a600d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a600e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 
4a600f0: 55 ff ff ff ff ff ff 10 ff ff 00 00 a6 20 00 05
 
</pre>
 
  
[[Category:Hardware]]
+
[[Category:Peripherals]]

Latest revision as of 19:46, 27 February 2024

Pins on the Wii expansion controller cable

The Wii Remote includes a 6-pin expansion port that allows external peripherals to be connected to it. Communications are bidirectional synchronous serial I2C, and the devices provide a virtual register block of length 0x100 that is mapped at 0xa40000 in the Wii Remote's address space (the 7-bit I2C address is 0x52). Communications are encrypted, as detailed below. Nintendo released two extensions, the Nunchuk and the Classic Controller. In addition, Guitar Hero guitars and drums also act as extension controllers. The balance board acts like a dummy Wiimote with its own type of built-in extension controller. There are also many third party versions of classic controllers and nunchuks.

The Wii Motion Plus is a small expansion which itself has an expansion port, allowing people to plug the Nunchuk into the Wii Motion Plus and the Wii Motion Plus into the Wii Remote.

The peripheral Protocol is 400kHz "fast" I2C, with slave address 0x52. It is easy to make homebrew peripherals; see the Tenkey numberpad project(Japanese), gyro project (Japanese), the Twiidler project, the DIY Wii drum controller, the OpenChord Guitar, or the DIY Wii guitar proof of concept demo video.

Registers / Initialization

Reminder
Remember to set bit 2 (0x04) on the first byte of the Output Reports to write to registers!

Wii Motion Plus is mapped at register 0xa60000.

Other extension Controllers are mapped at register address 0xa40000. The data is 0x100 bytes long, and it is mirrored across the entire 16-bit address space up to 0xa4FFFF. These registers are readable and writable. Communications are optionally encrypted, and explicit initialization is required to disable encryption (see below).

In encrypted mode, bytes can be decrypted using the following transformation:

decrypted_byte = (encrypted_byte XOR table1[address%8]) + table2[address%8]

Where table1 and table2 are 8-byte tables calculated based on the 16-byte key sent by the host, and address is the address of the byte being read (only the bottom 3 bits matter). If the host key is 16 zero bytes, table1[x] and table2[x] are all 0x97. The value 0x17 was used previously, which is equivalent. Proof of why any two pairs of table entries a,b and x,y are equivalent if (a^b^x^y)&0x80 == 0 is left as an exercise to the reader.

The calculations should be performed mod 256, that is, truncated to 8 bits (in languages such as C and Python, use &0xFF or work directly with 8-bit datatypes).

If the Wii Remote is initialized using the new method listed below, then the encryption of the extension bytes is disabled and they need not be decrypted using the transform listed above.

The Wii Remote will stream data bytes from the Extension Controller starting at offset 0x08, and continuing for however many bytes the current Data Reporting Mode requires. Data streamed through the Input Reports must also be decrypted using the above transformation if encryption is enabled.

Identification

Once initialized, the last six bytes of the register block identify the connected Extension Controller. A six-byte read of register 0xa400fa will return these bytes. The Extension Controller must have been initialized prior to this. There are two ways of initializing the extension.

The Old Way

The old way to initialize the extension was by writing the single encryption byte 0x00 to 0x(4)A40040, but that only works on Nintendo's own brand extensions and the GH3 Guitar, and will fail on 3rd party wireless nunchuks and GHWT extensions. If it fails, the 6 bytes will be FFFF FFFF FFFF. With this method you must decrypt the extension bytes to read them.

The New Way

The new way to initialize the extension is by writing 0x55 to 0x(4)A400F0, then writing 0x00 to 0x(4)A400FB. It works on all extensions, and makes the extension type bytes unencrypted. This means that you no longer have to decrypt the extension bytes using the transform listed above.


Encrypted Decrypted Meaning
0000 0000 0000* 0x2E2E BladeFX adapter that has been initialised old way, unplugged then replugged
FFFF FFFF FFFF* 0xFFFF GHWT Guitar or Drums or synced BladeFX or other wireless nunchuk initialised the old way
0xFEFE 0000 A420 0000 Nunchuk
0xFDFD 0000 A420 0101 Classic Controller
0xFDFD 0100 A420 0101 Classic Controller Pro & NES/SNES controller from the NES/SNES mini
0xFEEB FF00 A420 0013 Drawsome Graphics Tablet
0xFDFB 0000 A420 0103 GH3 or GHWT Guitar
0xFDFB 0100 A420 0103 Guitar Hero World Tour Drums
0300 A420 0103* DJ Hero Turntable
0000 A420 0111* Taiko no Tatsujin TaTaCon (Drum controller)
FF00 A420 0112* uDraw GameTablet (Graphics tablet)
0000 A420 0310* Densha de GO! Shinkansen Controller
0000 A420 0402* 0x2A2C Wii Balance Board
0000 A420 0005* Inactive Wii Motion Plus (Built-in)
0000 A420 0405* Activated Wii Motion Plus
0000 A420 0505* Activated Wii Motion Plus in Nunchuck passthrough mode
0000 A420 0705* Activated Wii Motion Plus in Classic Controller passthrough mode

(4)A60000:

Encrypted Decrypted Meaning
0000 A620 0005* Inactive Wii Motion Plus
0000 A620 0405* No-longer active Wii Motion Plus
0000 A620 0505* No-longer nunchuk-passthrough Wii Motion Plus
0000 A620 0705* No-longer classic-passthrough Wii Motion Plus


The values marked with a * are actually already unencrypted, and should not be decrypted. They are given here along with unencrypted version for those wanting to use simplified detection code. You can easily tell whether a value should be decrypted or not by looking at the other values in the 0xa400fa to 0xa400fd region.

The "Partially inserted" condition allegedly occurs when the connector is loose or has a bad connection. Usually, this will correct itself upon full insertion. However, it has been known to "stick" in the partially inserted state rarely. This is a hardware glitch, the fix is to simply disconnect and reconnect the Extension Controller. Third party controllers such as wireless nunchuks also return this value if initialized with the old method, in which case the whole last 16 bytes will be FF.

Contrary to previous documentation, the 0000 0000 0000 value does NOT occur when nothing is inserted. Instead you get error 7 when you try to read the expansion type. A successful 0000 0000 0000 only occurs when a BladeFX wireless nunchuk is synced, initialized with the old method, then the adapter is unplugged, then the adapter is replugged.

A Wii Balance Board extension is only found in a Wii Balance Board. Although it exposes functionality as an Extension Controller, they are not separable and this controller is documented separately.

Data format code

After some research of NES/SNES Classic Mini's Classic Controller driver source code, it turned out that the penultimate byte of the register block identify (e.g. the byte at offset 0x(4)A400FE) is data format code. So 0x00 is the Nunchuck data format and 0x01 is the default Classic Controller data format. Actually, this byte is writable for some controllers. So, official Classic Controller supports data formats 0x01, 0x02 and 0x03. Most old third party Classic Controllers supports only 0x01, NES/SNES Classic Mini tries to set the data format byte to 0x03, that's why most of them don't work. Guitar Hero controller uses mode 0x03 by default, so it shares the data format with Classic Controller, that's why guitar can be used in Wii's main menu.

Encryption setup

After the identification is read, the encryption can be set up if required. This is done by enabling encryption by writing 0xAA to extension register 0xF0, and then writing the 16-byte key to register 0x40. The key is written in 3 blocks of 6, 6, and 4 bytes. (Writing a single encryption byte to register 0x40 will work on genuine Nintendo controllers, but not on others). After this the extension can be operated in full encryption mode.

List of extension controllers