kriswiner / MPU9150

Arduino sketch for MPU9150 9DoF with AHRS sensor fusion
75 stars 36 forks source link

AK8975 adjustment value calculation #2

Closed ademirci closed 10 years ago

ademirci commented 10 years ago

I noticed that in row 675, 676 and 677 of MPU9150BasicAHRS.ino, calculation of adjustment values are wrong. In the datasheet it says that Hadj = H * (((asa - 128) * 0.5)/128) + 1) where H is the measurement data and Hadj is the adjusted measurement data. So, I think you do not need a calculation to output adjustment values in your initAK8975A procedure. You should do the calculation for every individual readed mesaurement data in you measurement reading procedure.

So, initAK8975A should be:

void initAK8975A(float * destination) { uint8_t rawData[3]; // x/y/z gyro register data stored here writeByte(AK8975A_ADDRESS, AK8975A_CNTL, 0x00); // Power down delay(10); writeByte(AK8975A_ADDRESS, AK8975A_CNTL, 0x0F); // Enter Fuse ROM access mode delay(10); readBytes(AK8975A_ADDRESS, AK8975A_ASAX, 3, &rawData[0]); // Read the x-, y-, and z-axis calibration values destination[0] = (float)(rawData[0]; // Return x-axis sensitivity adjustment values destination[1] = (float)(rawData[1];
destination[2] = (float)(rawData[2]; }

ademirci commented 10 years ago

I forgot to delete some paranthesis in my previous comment. Here is the corrected version

void initAK8975A(float * destination) { uint8_t rawData[3]; // x/y/z gyro register data stored here writeByte(AK8975A_ADDRESS, AK8975A_CNTL, 0x00); // Power down delay(10); writeByte(AK8975A_ADDRESS, AK8975A_CNTL, 0x0F); // Enter Fuse ROM access mode delay(10); readBytes(AK8975A_ADDRESS, AK8975A_ASAX, 3, &rawData[0]); // Read the x-, y-, and z-axis calibration values destination[0] = (float)rawData[0]; // Return x-axis sensitivity adjustment values destination[1] = (float)rawData[1]; destination[2] = (float)rawData[2]; }

kriswiner commented 10 years ago

Thanks for the feedback on the mag calibration!

I believe I am doing the adjustment correctly.

In the initAK8975 routine I am collecting the adjustment factor, which is reported to the main program as magCalibration[3],

initAK8975A(magCalibration);

Then when the mag data is calculated it is adjusted by this calibration factor:

mx = (float)magCount[0]*mRes*magCalibration[0] - magbias[0]; // get actual magnetometer value, this depends on scale being set
my = (float)magCount[1]*mRes*magCalibration[1] - magbias[1];
mz = (float)magCount[2]*mRes*magCalibration[2] - magbias[2]; 

as well as the sensitivity scale factor mRes with a correction to correct for the magnetometer hard iron biases.

This just as described in the data sheet.

The Fuse ROM data ASA, is turned into the data sensitivity factor by applying this equation:

Hadj = H * (((asa - 128) * 0.5)/128) + 1)

In the main program, magCalibration[3] == (((asa[3] - 128) * 0.5)/128) + 1) , magCount[3] == H and mx, my, mz == H.

Don't you agree?

ademirci commented 10 years ago

You are using the recommended adjusment formula in your initAK8975A routine as follows: destination[0] = (float)(rawData[0] - 128)/256. + 1.;

You are calculating a new adjusment value by using the adjustment register value as input in the formula. However in the datasheet it says " H is the measurement data read out from the measurement data register" I think "measurement data register" is the magnetometer value registers and not the Adjustment value registers. Please see part 8.3.4, Datasheet calls "masurement data registers as "HXL to HZH So, I think this formula should be used for every reading taken from measurement registers to calculate adjusted measurement.

ademirci commented 10 years ago

I am terribly sorry that I misunderstand the initAK8975A routine. You are calculating correct. Sorry for taking your time.

kriswiner commented 10 years ago

No problem. I appreciate you checking up on me. I make mistakes all the time!