Wii Balance Board

From WiiBrew
Jump to navigation Jump to search
This page is intended to be a technical guide to the Wii Balance Board..
For an excellent high-level overview of the Wii Balance Board, see the Wikipedia entry.

The Wii Balance Board is the bundled input device with the Wii game Wii Fit. It is a wireless device, using standard Bluetooth technology to communicate with the Wii. It implements the same protocol as the Wiimote for host communications, and exposes most of its functionality via an extension controller. It is recommended this page be read in conjunction with the Wiimote page.

Summary

Enough information is available to be able to get calibrated readings from the four pressure sensors, receive events from the single button, and drive the single LED. There is other information available in the extension controller registers, but with no identified purpose.

Bluetooth Communication

The Wii Balance Board exposes the sames services over the Bluetooth Service Discovery Protocol (SDP) as a Wiimote.

HID Interface

The Wii Balance Board operates similarly to a Wiimote as a HID device, however the friendly name exposed to HID is Nintendo RVL-WBC-01

Specifically, it will generate reports for the various features of a Wiimote, even though the hardware is absent.

Data Reporting

All Data reporting modes of the Wiimote are supported. Since the weight data is in the first 8 bytes, report 0x32 "Core Buttons with 8 Extension bytes" is most appropriate. To also include battery values, report 0x34 "Core Buttons with 19 Extension bytes" is appropriate.

Memory and Registers

EEPROM Memory

Just like with the Wiimote, the Balance Board exposes 0x1700 bytes of EEPROM that can be read and written normally. This data is initially all 0, and is not known to be used by any games.

The top byte is still ignored, so values are mirrored every 0x10000 bytes (for example, 0x010000 through 0x0116FF). Out of bounds reads and writes will still return error code 8.

Control Registers

Access to the extension controller registers is identical to that of the Wiimote, and these are the only registers that are actually used. There is no IR or speaker hardware in the Wii Balance Board, and attempts to read from those will result in error code 7.

Input Features

The Wii Balance Board has only a single physical button, accessible as core button "A", bit 3 of the second byte of button status.

Note that the Wii Balance Board will generate input reports for hardware it does not have, but that a Wiimote does.

Feedback Features

The Wii Balance Board has only a single LED, controlled by the same reports as the Wiimote uses to control the player 1 LED. There is no rumble or speaker feature.

Extension Controllers

The Wii Balance Board appears as a Wiimote with a Balance Board extension controller permanently connected. The Balance Board extension is accessed similarly to a normal extension controller on a Wiimote

Registers / Initialization

The Balance Board extension is initialized similarly to a normal extension controller, however no encryption or decryption needs to be undertaken on data either read from the registers, or streamed through the output reports.

Identification

The last two bytes of the register block identify the connected Extension Controller. A two-byte read of register 0xa400fe will return these bytes. The Extension Controller must have been initialized prior to this (by writing 0x00 to the key register).

Value Decrypted Meaning
0x0402 0x2A2C Wii Balance Board

Note that the decrypted value is here as a convenience for those dealing with libraries that automatically decrypt this identifier before presenting it to the code that identifies the extension controller. The unencrypted value is more consistent with existing extension controller identifiers.

Extension Controller Documentation

The Wii Balance Board exposes four 16-bit pressure sensors through its extension controller interface, along with the necessary calibration data to allow conversions to mass measurements.

Data Format

The Balance Board reports its information as 11 bytes of data, readable from 0xa40000 to 0xa4000a and streamable using Data Reporting Modes that include Extension bytes (unused bytes that would be streamable (i.e. the first 21) are filled with 0x00). The data is as follows:

  Bit
Byte 7 6 5 4 3 2 1 0
0 Top Right<15:8>
1 Top Right<7:0>
2 Bottom Right<15:8>
3 Bottom Right<7:0>
4 Top Left<15:8>
5 Top Left<7:0>
6 Bottom Left<15:8>
7 Bottom Left<7:0>
8 Temperature
9 0
10 Battery Level

A battery level ≥ 0x82 is 4 bars, less than 0x82 and ≥ 0x7D is 3 bars, less than 0x7D and ≥ 0x78 is 2 bars, less than 0x78 and ≥ 0x6A is 1 bar, and otherwise is considered empty.

Temperature values less than the reference temperature (see below) indicate colder boards with more stiff sensors (so the same weight would result in a lower reading, or the same reading indicates more weight). A balance board that was left in a refrigerator for an hour reported a temperature of 0xc compared to 0x1a at room temperature (~68° Fareinheit or 20° Celcius) (with a Reference Temperature of 0x19).

Wii Fit compensates for the temperature value with the calculation (.999 * totalWeight * -(.007 * ((boardTemp - refTemp) / 10.0) - 1.0)), where .999 is actually 0.9990813732147217 (0x3feff87980000000) and .007 is actually 0.007000000216066837 (0x3f7cac0840000000, (double).007f). This equation simplifies to (.999 * totalWeight * (1.0 - .0007 * (boardTemp - refTemp))); in other words, boardTemp being one less than refTemp results in a .07% increase in the total weight, and boardTemp being 14 more than refTemp results in a .98% increase in the total weight.

Calibration Data

Calibration Data for the Balance Board sensors is found unencrypted in the 32 bytes from 0xa40020 to 0xa4003f, as follows:

  Bit
Byte 7 6 5 4 3 2 1 0
0x20 Unknown (always 0x01)
0x21 Reference Battery Level (always 0x69)
0x22 0
0x23 0
0x24 Top Right 0kg value<15:8>
0x25 Top Right 0kg value<7:0>
0x26 Bottom Right 0kg value<15:8>
0x27 Bottom Right 0kg value<7:0>
0x28 Top Left 0kg value<15:8>
0x29 Top Left 0kg value<7:0>
0x2A Bottom Left 0kg value<15:8>
0x2B Bottom Left 0kg value<7:0>
0x2C Top Right 17kg value<15:8>
0x2D Top Right 17kg value<7:0>
0x2E Bottom Right 17kg value<15:8>
0x2F Bottom Right 17kg value<7:0>
0x30 Top Left 17kg value<15:8>
0x31 Top Left 17kg value<7:0>
0x32 Bottom Left 17kg value<15:8>
0x33 Bottom Left 17kg value<7:0>
0x34 Top Right 34kg value<15:8>
0x35 Top Right 34kg value<7:0>
0x36 Bottom Right 34kg value<15:8>
0x37 Bottom Right 34kg value<7:0>
0x38 Top Left 34kg value<15:8>
0x39 Top Left 34kg value<7:0>
0x3A Bottom Left 34kg value<15:8>
0x3B Bottom Left 34kg value<7:0>
0x3C Checksum<31:24>
0x3D Checksum<23:16>
0x3E Checksum<15:8>
0x3F Checksum<7:0>

Calculating the weight on each sensor simply involves interpolating between the two calibration values your reading falls between (or using the higher two values if your reading exceeds the highest calibration value), and the total weight on the board is the sum of these values.

The reference battery level is unused, but matches the point at which the battery reading (0xA) is considered empty.

There are also values at 0xa40060 and 0xa40061, and the other values in the range of 0xa40050 through 0xa4006f all read 0.

  Bit
Byte 7 6 5 4 3 2 1 0
0x60 Reference Temperature
0x61 Unknown (always 0x01)

The reference temperature is presumably the temperature reading when the board was calibrated.

The checksum is a CRC32 computed using the reversed polynomial 0xEDB88320 of 28 bytes: the 24 bytes from 0x24 through 0x3b, then the bytes at 0x20 and 0x21, and then the bytes at 0x60 and 0x61.

Sample Calibration

Some sample calibration data obtained from various balance boards. Note that this is simply a sample, and different boards will have different data.

Australian Board
The (Australian) Balance Board belonging to Carl Kenner returns the following data for that range:
(4)A40020:   10 69 00 00 
(4)A40024:   07C3  3CF8  048C  296B (bigendian calibrations for 0 kg, TR BR TL BL)     
(4)A4002C:   0ED2  4384  0B3A  3069 (bigendian calibrations for 17 kg)
(4)A40034:   15E9  4A10  11EF  376E (bigendian calibrations for 34 kg)     
(4)A4003C:   5E 40 E9 B6
Brute-forcing for values that match the checksum gives 1a 01 as the values at (4)A40060/1.
Finnish Board
A (Finnish) brand new Balance Board returns the following data for that range:
(4)A40020:   55 69 00 00
(4)A40024:   4D A9 42 7B  4C 23 36 58
(4)A4002C:   54 36 49 6D  53 09 3D 1C 
(4)A40034:   5A C9 50 66  59 FC 43 EF
(4)A4003C:   79 55 CB 1A
Brute-forcing for values that match the checksum gives 18 01 as the values at (4)A40060/1.
US Board
A (US) Balance Board returns the following data:
(4)A40020:   01 69 00 00
(4)A40024:   07 BC 11 8B  06 BA 46 52
(4)A4002C:   0E 6E 18 79  0D 5D 4D 4C
(4)A40034:   15 2E 1F 71  14 07 54 51
(4)A4003C:   A9 06 B4 F0
(4)A40060:   19 01
Japanese Boards
Two Japanese boards from Hiroyuki Ogasawara return the following data (source):

Board 1:

(4)A40020:   41 69 00 00
(4)A40024:   49 69 0c 67  0a a4 4a b6
(4)A4002C:   50 7c 13 3d  11 6d 51 a6
(4)A40034:   57 87 1a 17  18 3f 58 9e
(4)A4003C:   d8 94 ce 81
(4)A40060:   1b 01

Board 2:

(4)A40020:   01 69 00 00
(4)A40024:   13 66 13 f2  0b f6 48 91
(4)A4002C:   1a 5f 1a a3  12 dd 4f 48
(4)A40034:   21 5a 21 62  19 ce 56 0f
(4)A4003C:   b9 34 f5 28
(4)A40060:   11 01

Wii Initialisation Sequence

This is a listing of the initialisation sequence which my [drhugh's] Wii performs on the balance board, as determined by snooping the 2-wire bus of the Broadcom chip (TWI). At TWI level reads are always 16 bytes, so read length is not specified. For writes the starting address is given. The snooping was needed because my balance boards were working with the Wii, but were having one or more of the 4 weight sensors disabled with my PC interface (based on WiiUse). At PC interface level the addresses should have 0xa40000 added.

Write f0: 55           (standard extension initialisation without encryption)
Write fb: 00
Read fa:		(reads the extension identifier)
Write f0: aa           (enable encryption - following three lines are the 16 byte key)
Write 40: ab 7c b4 1e 97 8d  		(example - data bytes are highly variable)
Write 46: 9e 7e 81 1b 99 29            (example)
Write 4c: 17 07 a6 1e                  (example)
Write f1: aa           (the purpose of this byte is unknown, possibly calibration?)
Write f1: aa
Write f1: aa
Read 20:		(reading calibration data)
Read 30:               (reading calibration data)
Write f1: aa aa aa 55 aa aa aa
Write f1: aa
Write f1: aa
...			(wait)
Write f1: aa
Read 24:
Read 34:
Read 3c:
Read 60:
Read 21:
Read 20:
Read 24:
...			(wait)
Write f1: aa

Following initialisation the only activity is constant reading of address 00 (the weight sensor and battery data).

Using this sequence in the PC interface is found to correct the problem with disabled weight sensors. The problem recurs when the balance board is not used for a while, and several power and/or connect cycles may be necessary to get the sensors all working, after which they continue to work. A minor change is necessary to make the sequence work at all: the "write f0: aa" causes strange behaviour (encryption) in the balance board and must be omitted (no explanation is offered for why this happens to work).

Status Information

The Wii Balance Board presents the same status information as the Wiimote

Using the Balance Board in Homebrew

This was taken from the Balance Board Tools application

u32 devtype;
//(1) Check in which wiimotes expansion port the balance board is hiding in
for (i=0;i<WPAD_MAX_WIIMOTES;i++)
{	
	WPAD_Probe(i,&devtype);
	if (devtype==WPAD_EXP_WIIBOARD) bbport=i; //(2) Save it
}
WPAD_Expansion(bbport, &exp); //(3) Extract the balance board struct
x=exp.wb.x; // The position
y=exp.wb.y; // on the board
weight=exp.wb.tl+exp.wb.tr+exp.wb.bl+exp.wb.br; // Weight in kilograms

Acknowledgments

Much of the information here that differs from a Wiimote is based on the research of Hiroyuki Ogasawara documented in the Sports category of his blog (in Japanese), and the partial translation available at Wiili.