MPU9150 Magnetometer. Such a big problem

I have used this code from arduino Playground.

// MPU-9150 Accelerometer + Gyro + Compass + Temperature
// -----------------------------
//
// By arduino.cc user "frtrobotik" (Tobias Hübner)
//
//
// July 2013
//      first version
//
// Open Source / Public Domain
//
// Using Arduino 1.0.1
// It will not work with an older version,
// since Wire.endTransmission() uses a parameter
// to hold or release the I2C bus.
//
// Documentation:
// - The InvenSense documents:
//   - "MPU-9150 Product Specification Revision 4.0",
//     PS-MPU-9150A.pdf
//   - "MPU-9150 Register Map and Descriptions Revision 4.0",
//     RM-MPU-9150A-00.pdf
//   - "MPU-9150 9-Axis Evaluation Board User Guide"
//     AN-MPU-9150EVB-00.pdf
//
// The accuracy is 16-bits.
//
// Some parts are copied by the MPU-6050 Playground page.
// playground.arduino.cc/Main/MPU-6050
// There are more Registervalues. Here are only the most
// nessecary ones to get started with this sensor.

#include <Wire.h>

// Register names according to the datasheet.
// According to the InvenSense document
// "MPU-9150 Register Map and Descriptions Revision 4.0",

#define MPU9150_SELF_TEST_X        0x0D   // R/W
#define MPU9150_SELF_TEST_Y        0x0E   // R/W
#define MPU9150_SELF_TEST_X        0x0F   // R/W
#define MPU9150_SELF_TEST_A        0x10   // R/W
#define MPU9150_SMPLRT_DIV         0x19   // R/W
#define MPU9150_CONFIG             0x1A   // R/W
#define MPU9150_GYRO_CONFIG        0x1B   // R/W
#define MPU9150_ACCEL_CONFIG       0x1C   // R/W
#define MPU9150_FF_THR             0x1D   // R/W
#define MPU9150_FF_DUR             0x1E   // R/W
#define MPU9150_MOT_THR            0x1F   // R/W
#define MPU9150_MOT_DUR            0x20   // R/W
#define MPU9150_ZRMOT_THR          0x21   // R/W
#define MPU9150_ZRMOT_DUR          0x22   // R/W
#define MPU9150_FIFO_EN            0x23   // R/W
#define MPU9150_I2C_MST_CTRL       0x24   // R/W
#define MPU9150_I2C_SLV0_ADDR      0x25   // R/W
#define MPU9150_I2C_SLV0_REG       0x26   // R/W
#define MPU9150_I2C_SLV0_CTRL      0x27   // R/W
#define MPU9150_I2C_SLV1_ADDR      0x28   // R/W
#define MPU9150_I2C_SLV1_REG       0x29   // R/W
#define MPU9150_I2C_SLV1_CTRL      0x2A   // R/W
#define MPU9150_I2C_SLV2_ADDR      0x2B   // R/W
#define MPU9150_I2C_SLV2_REG       0x2C   // R/W
#define MPU9150_I2C_SLV2_CTRL      0x2D   // R/W
#define MPU9150_I2C_SLV3_ADDR      0x2E   // R/W
#define MPU9150_I2C_SLV3_REG       0x2F   // R/W
#define MPU9150_I2C_SLV3_CTRL      0x30   // R/W
#define MPU9150_I2C_SLV4_ADDR      0x31   // R/W
#define MPU9150_I2C_SLV4_REG       0x32   // R/W
#define MPU9150_I2C_SLV4_DO        0x33   // R/W
#define MPU9150_I2C_SLV4_CTRL      0x34   // R/W
#define MPU9150_I2C_SLV4_DI        0x35   // R  
#define MPU9150_I2C_MST_STATUS     0x36   // R
#define MPU9150_INT_PIN_CFG        0x37   // R/W
#define MPU9150_INT_ENABLE         0x38   // R/W
#define MPU9150_INT_STATUS         0x3A   // R  
#define MPU9150_ACCEL_XOUT_H       0x3B   // R  
#define MPU9150_ACCEL_XOUT_L       0x3C   // R  
#define MPU9150_ACCEL_YOUT_H       0x3D   // R  
#define MPU9150_ACCEL_YOUT_L       0x3E   // R  
#define MPU9150_ACCEL_ZOUT_H       0x3F   // R  
#define MPU9150_ACCEL_ZOUT_L       0x40   // R  
#define MPU9150_TEMP_OUT_H         0x41   // R  
#define MPU9150_TEMP_OUT_L         0x42   // R  
#define MPU9150_GYRO_XOUT_H        0x43   // R  
#define MPU9150_GYRO_XOUT_L        0x44   // R  
#define MPU9150_GYRO_YOUT_H        0x45   // R  
#define MPU9150_GYRO_YOUT_L        0x46   // R  
#define MPU9150_GYRO_ZOUT_H        0x47   // R  
#define MPU9150_GYRO_ZOUT_L        0x48   // R  
#define MPU9150_EXT_SENS_DATA_00   0x49   // R  
#define MPU9150_EXT_SENS_DATA_01   0x4A   // R  
#define MPU9150_EXT_SENS_DATA_02   0x4B   // R  
#define MPU9150_EXT_SENS_DATA_03   0x4C   // R  
#define MPU9150_EXT_SENS_DATA_04   0x4D   // R  
#define MPU9150_EXT_SENS_DATA_05   0x4E   // R  
#define MPU9150_EXT_SENS_DATA_06   0x4F   // R  
#define MPU9150_EXT_SENS_DATA_07   0x50   // R  
#define MPU9150_EXT_SENS_DATA_08   0x51   // R  
#define MPU9150_EXT_SENS_DATA_09   0x52   // R  
#define MPU9150_EXT_SENS_DATA_10   0x53   // R  
#define MPU9150_EXT_SENS_DATA_11   0x54   // R  
#define MPU9150_EXT_SENS_DATA_12   0x55   // R  
#define MPU9150_EXT_SENS_DATA_13   0x56   // R  
#define MPU9150_EXT_SENS_DATA_14   0x57   // R  
#define MPU9150_EXT_SENS_DATA_15   0x58   // R  
#define MPU9150_EXT_SENS_DATA_16   0x59   // R  
#define MPU9150_EXT_SENS_DATA_17   0x5A   // R  
#define MPU9150_EXT_SENS_DATA_18   0x5B   // R  
#define MPU9150_EXT_SENS_DATA_19   0x5C   // R  
#define MPU9150_EXT_SENS_DATA_20   0x5D   // R  
#define MPU9150_EXT_SENS_DATA_21   0x5E   // R  
#define MPU9150_EXT_SENS_DATA_22   0x5F   // R  
#define MPU9150_EXT_SENS_DATA_23   0x60   // R  
#define MPU9150_MOT_DETECT_STATUS  0x61   // R  
#define MPU9150_I2C_SLV0_DO        0x63   // R/W
#define MPU9150_I2C_SLV1_DO        0x64   // R/W
#define MPU9150_I2C_SLV2_DO        0x65   // R/W
#define MPU9150_I2C_SLV3_DO        0x66   // R/W
#define MPU9150_I2C_MST_DELAY_CTRL 0x67   // R/W
#define MPU9150_SIGNAL_PATH_RESET  0x68   // R/W
#define MPU9150_MOT_DETECT_CTRL    0x69   // R/W
#define MPU9150_USER_CTRL          0x6A   // R/W
#define MPU9150_PWR_MGMT_1         0x6B   // R/W
#define MPU9150_PWR_MGMT_2         0x6C   // R/W
#define MPU9150_FIFO_COUNTH        0x72   // R/W
#define MPU9150_FIFO_COUNTL        0x73   // R/W
#define MPU9150_FIFO_R_W           0x74   // R/W
#define MPU9150_WHO_AM_I           0x75   // R

//MPU9150 Compass
#define MPU9150_CMPS_XOUT_L        0x4A   // R
#define MPU9150_CMPS_XOUT_H        0x4B   // R
#define MPU9150_CMPS_YOUT_L        0x4C   // R
#define MPU9150_CMPS_YOUT_H        0x4D   // R
#define MPU9150_CMPS_ZOUT_L        0x4E   // R
#define MPU9150_CMPS_ZOUT_H        0x4F   // R


// I2C address 0x69 could be 0x68 depends on your wiring. 
int MPU9150_I2C_ADDRESS = 0x68;

Here is the second part.

//Variables where our values can be stored
int cmps[3];
int accl[3];
int gyro[3];
int temp;

void setup()
{      
  // Initialize the Serial Bus for printing data.
  Serial.begin(9600);

  // Initialize the 'Wire' class for the I2C-bus.
  Wire.begin();

  // Clear the 'sleep' bit to start the sensor.
  MPU9150_writeSensor(MPU9150_PWR_MGMT_1, 0);

  MPU9150_setupCompass();
}


void loop()
{
  // Print all sensor values which the sensor provides
  // Formated all values as x, y, and z in order for
  // Compass, Gyro, Acceleration. The First value is
  // the temperature.

  double dT = ( (double) MPU9150_readSensor(MPU9150_TEMP_OUT_L,MPU9150_TEMP_OUT_H) + 12412.0) / 340.0;
  Serial.print(dT);
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_CMPS_XOUT_L,MPU9150_CMPS_XOUT_H));
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_CMPS_YOUT_L,MPU9150_CMPS_YOUT_H));
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_CMPS_ZOUT_L,MPU9150_CMPS_ZOUT_H));
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_GYRO_XOUT_L,MPU9150_GYRO_XOUT_H));
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_GYRO_YOUT_L,MPU9150_GYRO_YOUT_H));
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_GYRO_ZOUT_L,MPU9150_GYRO_ZOUT_H));
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_ACCEL_XOUT_L,MPU9150_ACCEL_XOUT_H));
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_ACCEL_YOUT_L,MPU9150_ACCEL_YOUT_H));
  Serial.print("  ");
  Serial.print(MPU9150_readSensor(MPU9150_ACCEL_ZOUT_L,MPU9150_ACCEL_ZOUT_H));
  Serial.println();
  delay(100);
}

//http://pansenti.wordpress.com/2013/03/26/pansentis-invensense-mpu-9150-software-for-arduino-is-now-on-github/
//Thank you to pansenti for setup code.
//I will documented this one later.
void MPU9150_setupCompass(){
  MPU9150_I2C_ADDRESS = 0x0C;      //change Adress to Compass

  MPU9150_writeSensor(0x0A, 0x00); //PowerDownMode
  MPU9150_writeSensor(0x0A, 0x0F); //SelfTest
  MPU9150_writeSensor(0x0A, 0x00); //PowerDownMode

  MPU9150_I2C_ADDRESS = 0x68;      //change Adress to MPU

  MPU9150_writeSensor(0x24, 0x40); //Wait for Data at Slave0
  MPU9150_writeSensor(0x25, 0x8C); //Set i2c address at slave0 at 0x0C
  MPU9150_writeSensor(0x26, 0x02); //Set where reading at slave 0 starts
  MPU9150_writeSensor(0x27, 0x88); //set offset at start reading and enable
  MPU9150_writeSensor(0x28, 0x0C); //set i2c address at slv1 at 0x0C
  MPU9150_writeSensor(0x29, 0x0A); //Set where reading at slave 1 starts
  MPU9150_writeSensor(0x2A, 0x81); //Enable at set length to 1
  MPU9150_writeSensor(0x64, 0x01); //overvride register
  MPU9150_writeSensor(0x67, 0x03); //set delay rate
  MPU9150_writeSensor(0x01, 0x80);

  MPU9150_writeSensor(0x34, 0x04); //set i2c slv4 delay
  MPU9150_writeSensor(0x64, 0x00); //override register
  MPU9150_writeSensor(0x6A, 0x00); //clear usr setting
  MPU9150_writeSensor(0x64, 0x01); //override register
  MPU9150_writeSensor(0x6A, 0x20); //enable master i2c mode
  MPU9150_writeSensor(0x34, 0x13); //disable slv4
}

////////////////////////////////////////////////////////////
///////// I2C functions to get easier all values ///////////
////////////////////////////////////////////////////////////

int MPU9150_readSensor(int addrL, int addrH){
  Wire.beginTransmission(MPU9150_I2C_ADDRESS);
  Wire.write(addrL);
  Wire.endTransmission(false);

  Wire.requestFrom(MPU9150_I2C_ADDRESS, 1, true);
  byte L = Wire.read();

  Wire.beginTransmission(MPU9150_I2C_ADDRESS);
  Wire.write(addrH);
  Wire.endTransmission(false);

  Wire.requestFrom(MPU9150_I2C_ADDRESS, 1, true);
  byte H = Wire.read();

  return (int16_t)((H<<8)+L);
}

int MPU9150_readSensor(int addr){
  Wire.beginTransmission(MPU9150_I2C_ADDRESS);
  Wire.write(addr);
  Wire.endTransmission(false);

  Wire.requestFrom(MPU9150_I2C_ADDRESS, 1, true);
  return Wire.read();
}

int MPU9150_writeSensor(int addr,int data){
  Wire.beginTransmission(MPU9150_I2C_ADDRESS);
  Wire.write(addr);
  Wire.write(data);
  Wire.endTransmission(true);

  return 1;
}

I am using an Arudino Nano to test the sensor. But all i have got are some values seem to be so weird, like they are dependent to each other.

  Temp=26.53    magx=-29  magy=-29  magz=-29  accx=-104  accy=35  accz=-40  gyrox=-32  gyroy=-11928  gyroz=-12252
  Temp=26.48    magx=-28  magy=-28  magz=-28  accx=-119  accy=46  accz=80  gyrox=-172  gyroy=-11848  gyroz=-12156
  Temp=26.48    magx=-25  magy=-25  magz=-25  accx=-111  accy=8  accz=78  gyrox=-192  gyroy=-11900  gyroz=-12200
  Temp=26.53    magx=-27  magy=-27  magz=-27  accx=-90  accy=51  accz=-147  gyrox=-160  gyroy=-11892  gyroz=-12192
  Temp=26.58    magx=-29  magy=-29  magz=-29  accx=-104  accy=47  accz=-60  gyrox=-124  gyroy=-11860  gyroz=-12364
  Temp=26.48    magx=-26  magy=-27  magz=-27  accx=-50  accy=40  accz=-30  gyrox=-236  gyroy=-11884  gyroz=-12192
  Temp=26.53    magx=-27  magy=-27  magz=-27  accx=-97  accy=28  accz=46  gyrox=-160  gyroy=-11848  gyroz=-12164
  Temp=26.58    magx=-28  magy=-28  magz=-28  accx=-88  accy=41  accz=15  gyrox=-120  gyroy=-11888  gyroz=-12192
  Temp=26.58    magx=-30  magy=-30  magz=-30  accx=-118  accy=29  accz=25  gyrox=-160  gyroy=-11876  gyroz=-12392
  Temp=26.58    magx=-27  magy=-27  magz=-26  accx=-78  accy=30  accz=59  gyrox=-216  gyroy=-11896  gyroz=-12480
  Temp=26.48    magx=-28  magy=-28  magz=-27  accx=-108  accy=55  accz=-5  gyrox=-68  gyroy=-11852  gyroz=-12048
  Temp=26.48    magx=-28  magy=-28  magz=-26  accx=-129  accy=33  accz=17  gyrox=0  gyroy=-11904  gyroz=-12276
  Temp=26.53    magx=-29  magy=-29  magz=-29  accx=-90  accy=31  accz=42  gyrox=-96  gyroy=-12004  gyroz=-12136
  Temp=26.44    magx=-28  magy=-28  magz=-28  accx=-99  accy=68  accz=17  gyrox=-36  gyroy=-11832  gyroz=-12424
  Temp=26.53    magx=-26  magy=-26  magz=-26  accx=-138  accy=52  accz=17  gyrox=-256  gyroy=-11884  gyroz=-12060
  Temp=26.53    magx=-28  magy=-28  magz=-25  accx=-100  accy=25  accz=51  gyrox=-212  gyroy=-11792  gyroz=-12148
  Temp=26.53    magx=-26  magy=-26  magz=-26  accx=-94  accy=18  accz=84  gyrox=-128  gyroy=-11932  gyroz=-12284
  Temp=26.48    magx=-27  magy=-28  magz=-28  accx=-109  accy=10  accz=402  gyrox=-56  gyroy=-11820  gyroz=-12300
  Temp=26.44    magx=-27  magy=-27  magz=-27  accx=-78  accy=33  accz=186  gyrox=-192  gyroy=-11836  gyroz=-11828
  Temp=26.53    magx=-27  magy=-27  magz=-30  accx=-98  accy=33  accz=59  gyrox=-260  gyroy=-12000  gyroz=-12176
  Temp=26.44    magx=-28  magy=-28  magz=-29  accx=-113  accy=29  accz=32  gyrox=-180  gyroy=-11824  gyroz=-12164
  Temp=26.58    magx=-30  magy=-29  magz=-29  accx=-89  accy=43  accz=54  gyrox=-68  gyroy=-11856  gyroz=-12212
  Temp=26.48    magx=-26  magy=-26  magz=-25  accx=-133  accy=96  accz=169  gyrox=-152  gyroy=-11868  gyroz=-12196
  Temp=26.53    magx=-18  magy=-18  magz=-18  accx=3791  accy=-32768  accz=18791  gyrox=-7260  gyroy=-21592  gyroz=-11584
  Temp=26.48    magx=24  magy=24  magz=21  accx=32767  accy=-27613  accz=-9148  gyrox=-10064  gyroy=-12288  gyroz=-1576
  Temp=26.67    magx=36  magy=36  magz=36  accx=14864  accy=-6207  accz=-860  gyrox=-2760  gyroy=-7624  gyroz=10064
  Temp=26.53    magx=32  magy=32  magz=33  accx=8841  accy=-1844  accz=2740  gyrox=-3736  gyroy=-7624  gyroz=14464
  Temp=27.42    magx=31  magy=31  magz=31  accx=-20281  accy=15690  accz=-14732  gyrox=2644  gyroy=6648  gyroz=15604
  Temp=25.96    magx=22  magy=19  magz=19  accx=-32768  accy=31702  accz=-9468  gyrox=-3252  gyroy=-13504  gyroz=-10592
  Temp=27.38    magx=-4  magy=-4  magz=-4  accx=-26047  accy=11335  accz=-8178  gyrox=-6024  gyroy=-17860  gyroz=-8908
  Temp=26.72    magx=-20  magy=-20  magz=-18  accx=-12947  accy=5769  accz=2542  gyrox=-1256  gyroy=-11960  gyroz=-7852
  Temp=25.96    magx=-23  magy=-23  magz=-23  accx=-78  accy=5006  accz=-1289  gyrox=-984  gyroy=-13956  gyroz=-11168
  Temp=26.81    magx=-23  magy=-23  magz=-23  accx=-359  accy=47  accz=-1164  gyrox=-980  gyroy=-12524  gyroz=-11228
  Temp=27.42    magx=-24  magy=-24  magz=-24  accx=-81  accy=64  accz=332  gyrox=-656  gyroy=-12764  gyroz=-11436
  Temp=26.72    magx=-23  magy=-23  magz=-23  accx=-151  accy=23  accz=-184  gyrox=-592  gyroy=-12664  gyroz=-11444
  Temp=26.76    magx=-24  magy=-24  magz=-24  accx=-144  accy=249  accz=-448  gyrox=-540  gyroy=-12752  gyroz=-11480
  Temp=26.72    magx=-23  magy=-24  magz=-24  accx=-101  accy=47  accz=147  gyrox=-672  gyroy=-12564  gyroz=-11300
  Temp=26.86    magx=-25  magy=-25  magz=-25  accx=-103  accy=54  accz=-6  gyrox=-476  gyroy=-12672  gyroz=-11460

So i looked into the code. And i have some trouble understanding it.

  MPU9150_writeSensor(0x26, 0x02); //Set where reading at slave 0 starts
  MPU9150_writeSensor(0x27, 0x88); //set offset at start reading and enable
  MPU9150_writeSensor(0x28, 0x0C); //set i2c address at slv1 at 0x0C
  MPU9150_writeSensor(0x29, 0x0A); //Set where reading at slave 1 starts
  MPU9150_writeSensor(0x2A, 0x81); //Enable at set length to 1
  MPU9150_writeSensor(0x64, 0x01); //overvride register
  MPU9150_writeSensor(0x67, 0x03); //set delay rate
  MPU9150_writeSensor(0x01, 0x80);

  MPU9150_writeSensor(0x34, 0x04); //set i2c slv4 delay
  MPU9150_writeSensor(0x64, 0x00); //override register
  MPU9150_writeSensor(0x6A, 0x00); //clear usr setting
  MPU9150_writeSensor(0x64, 0x01); //override register
  MPU9150_writeSensor(0x6A, 0x20); //enable master i2c mode
  MPU9150_writeSensor(0x34, 0x13); //disable slv4

I am confused about this part. "set where reading at slave 1 starts", why is the register here set to 0x0A, which is even not defined yet. Why is the slave 0 is set to length 4, and slave 1 is set to length 1? What does this part mean?

I have been thinking about it for several days but still don't get it.
Does anybody have some clue? I have also attached the Register Map for MPU9150.
Thanks a lot for your help.

Meng

RM-MPU-9150A-00v4_2.pdf (648 KB)