Read Motion Plus via I2C

21 08 2009

The Communication with the Wii Motion Plus needs ony one step to initialize and two steps to read from the Motion plus extension.

Motion Plus

I2C Adress: 0xa4/ 0xa6

I2C Motion Read Register: 0x00 (6 bytes)

I2C Enable Register 0xfe (Value 0x04)

I2C Disable Register 0xf0 (Value 0x55)

The Motion Plus extension has two basic states, the I2C repeater state and the motion sensing state.
After poweron is the motion plus in the I2C repeater state, in this state the I2C communication is forwarded to the rear port of the motion plus and it listens for commands that are written to the I2C oxa6. 

After a successfull write of 0×04 to the register 0xfe the motion plus changes to the motion sensing state and its I2C adress to 0xa4 .

To be able to read the data of the motion plus is now easy first the Register 0x00 the to be read has to be written to the I2C bus, after that the six bytes of data can be read. The data that is read is enxoded as described here.
To disable the Motion sensing, 0×55 must be written to the Register 0xf0.

edit:
The disable commands for the Motion Plus are not different to the enable commands for the Nunchuck(or the other extension controllers). That means if you want to disable the Motion Plus you tell the Motion Plus to switch on the extension controller by writing 0x55 to 0xf0. After that you have to wait 38ms to be able to the extension controller on the back of the Motion Plus it is already initialized so it is not needed to Initialise the Extensioncontroller again.

Example Code:

 
/*
 * motionplus.c
 *
 * This is a driver for the motionplus addon of the wii remote.
 * it was written on an Atmel 644 microcontroller around the
 * I2C library of Peter Fleury
 * http://homepage.hispeed.ch/peterfleury/group__pfleury__ic2master.html
 *
 *
 *  Created on: 21.08.2009
 *      Author: Paul Rosset
 *      License: BSD-License
 */
/*
 * Enables the motionplus extension
 * and initializes the motionplus structure
 * after his call the Adress of the motionplus changes to
 */
uint8_t motEnable(void)
{
	motionplus.roll=0;
	motionplus.pitch=0;
	motionplus.yaw=0;
	i2c_init();

	if (i2c_start(0xA6 + I2C_WRITE))
		return ERROR_AT_I2C_START;
	if (i2c_write(0xFE))
		return ERROR_AT_I2C_WRITE;
	if (i2c_write(0x04))
		return ERROR_AT_I2C_WRITE;
	i2c_stop();
	return 0;
}
/*
 * Disables the Motionplus Controller
 */
uint8_t motDisable(void)
{

  if (i2c_start(0xA4 + I2C_WRITE))
    return ERROR_AT_I2C_START;
  if (i2c_write(0xF0))
    return ERROR_AT_I2C_WRITE;
  if (i2c_write(0x55))
    return ERROR_AT_I2C_WRITE;
  i2c_stop();
  return 0;

}
/*
 * Requests Data to read
 * (sets the register that is read )
 */
uint8_t motRequestData(void)
{
	if (i2c_start(0xA4 + I2C_WRITE))
    return ERROR_AT_I2C_START;
  if (i2c_write(0x00))// sends zero before receiving
    return ERROR_AT_I2C_WRITE;
	i2c_stop();
	return 0;
}
/*
 * Update the Data for the Sensor
 * and parse it
 * */
uint8_t motUpdate()
{
		if(motRequestData())
			return 1;
	if(i2c_start(0xA4 + I2C_READ))
		return ERROR_AT_I2C_READ;

	for(int i = 0; i < 5; i++)
	{
		data[i]=i2c_readAck();
	}
	data[5]= i2c_readNak();
	i2c_stop();
	motionplus.yaw = data[0] | ((data[3] & 0xFC) <<6) ;
	motionplus.roll = data[1] | ((data[4] & 0xFC) <<6);
	motionplus.pitch = data[2] | ((data[5] & 0xFC) <<6);
	return 0;
}