kriswiner / MPU9250

Arduino sketches for MPU9250 9DoF with AHRS sensor fusion
1.03k stars 472 forks source link

Sensitivity Adjustment #493

Open Overff opened 9 months ago

Overff commented 9 months ago

Hi. First of all I would like to say thank you for the project! Could you explain your way to calculate the sensitivity adjustment for magnetometer (AK8963)? MPU-9250 Register Map and Descriptions Revision: 1.6 says how to do it (see the attache) 1_1 It looks like you ignored to do (ASA-128). Why?

I guess it should be

uint8_t ASAX_magXAdjust, ASAY_magYAdjust, ASAZ_magZAdjust;
...
Wire.beginTransmission(0x0C);
  Wire.write(0x10);
  Wire.endTransmission();
  Wire.requestFrom(0x0C, 3); 
  /*
   * The AK8963 has a read-only Fuse ROM Access mode that allows the access to the Fuse ROM data. 
   * The Fuse ROM contains the sensitivity adjustment data for each axis.
   */
  ASAX_magXAdjust = Wire.read();  // ASAX X-axis sensitivity adjustment 
  ASAY_magYAdjust = Wire.read();  // ASAY Y-axis sensitivity adjustment 
  ASAZ_magZAdjust = Wire.read();  // ASAZ Z-axis sensitivity adjustment 
...

  magCalibration[0]= (float)rawData[0] * ((((float)**ASAX_magXAdjust** - 128)/256)+1);
  magCalibration[1] = (float)rawData[1] * ((((float)**ASAY_magYAdjust** - 128)/256)+1);
  magCalibration[2] = (float)rawData[2] * ((((float)**ASAZ_magZAdjust** - 128)/256)+1);

This is your code

void MPU9250::initAK8963(uint8_t Mscale, uint8_t Mmode, float * magCalibration)
{
  // First extract the factory calibration for each magnetometer axis
  uint8_t rawData[3];  // x/y/z gyro calibration data stored here
  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer  
  delay(10);
  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode
  delay(10);
  readBytes(AK8963_ADDRESS, AK8963_ASAX, 3, &rawData[0]);  // Read the x-, y-, and z-axis calibration values
  magCalibration[0] =  (float)(**rawData[0] - 128**)/256.0f + 1.0f;   // Return x-axis sensitivity adjustment values, etc.
  magCalibration[1] =  (float)(**rawData[1] - 128**)/256.0f + 1.0f;  
  magCalibration[2] =  (float)(**rawData[2] - 128**)/256.0f + 1.0f; 
  _magCalibration[0] = magCalibration[0];
  _magCalibration[1] = magCalibration[1];
  _magCalibration[2] = magCalibration[2];
  _Mmode = Mmode;
  writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer  
  delay(10);
  // Configure the magnetometer for continuous read and highest resolution
  // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register,
  // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates
  writeByte(AK8963_ADDRESS, AK8963_CNTL, Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR
  delay(10);
}
kriswiner commented 9 months ago

It looks like you ignored to do (ASA-128). Why?

I did not ignore it, as you can see here:

magCalibration[0] = (float)(rawData[0] - 128)/256.0f + 1.0f; // Return x-axis sensitivity adjustment values, etc. magCalibration[1] = (float)(rawData[1] - 128)/256.0f + 1.0f; magCalibration[2] = (float)(rawData[2] - 128)/256.0f + 1.0f;

So what is your question?

On Sat, Dec 23, 2023 at 12:06 PM Overff @.***> wrote:

Hi. First of all I would like to say thank you for the project! Could you explain your way to calculate the sensitivity adjustment for magnetometer (AK8963)? MPU-9250 Register Map and Descriptions Revision: 1.6 says how to do it (see the attache) 1_1.jpg (view on web) https://github.com/kriswiner/MPU9250/assets/105443564/76939e92-4fc4-440d-a7ad-87ddeae9dd06 It looks like you ignored to do (ASA-128). Why?

I guess it should be

uint8_t ASAX_magXAdjust, ASAY_magYAdjust, ASAZ_magZAdjust; ... Wire.beginTransmission(0x0C); Wire.write(0x10); Wire.endTransmission(); Wire.requestFrom(0x0C, 3); /*

  • The AK8963 has a read-only Fuse ROM Access mode that allows the access to the Fuse ROM data.
  • The Fuse ROM contains the sensitivity adjustment data for each axis. */ ASAX_magXAdjust = Wire.read(); // ASAX X-axis sensitivity adjustment ASAY_magYAdjust = Wire.read(); // ASAY Y-axis sensitivity adjustment ASAZ_magZAdjust = Wire.read(); // ASAZ Z-axis sensitivity adjustment ...

    magCalibration[0]= (float)rawData[0] ((((float)ASAX_magXAdjust - 128)/256)+1); magCalibration[1] = (float)rawData[1] ((((float)ASAY_magYAdjust - 128)/256)+1); magCalibration[2] = (float)rawData[2] * ((((float)ASAZ_magZAdjust - 128)/256)+1);

This is your code

void MPU9250::initAK8963(uint8_t Mscale, uint8_t Mmode, float * magCalibration) { // First extract the factory calibration for each magnetometer axis uint8_t rawData[3]; // x/y/z gyro calibration data stored here writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer delay(10); writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x0F); // Enter Fuse ROM access mode delay(10); readBytes(AK8963_ADDRESS, AK8963_ASAX, 3, &rawData[0]); // Read the x-, y-, and z-axis calibration values magCalibration[0] = (float)(rawData[0] - 128)/256.0f + 1.0f; // Return x-axis sensitivity adjustment values, etc. magCalibration[1] = (float)(rawData[1] - 128)/256.0f + 1.0f; magCalibration[2] = (float)(rawData[2] - 128)/256.0f + 1.0f; _magCalibration[0] = magCalibration[0]; _magCalibration[1] = magCalibration[1]; _magCalibration[2] = magCalibration[2]; _Mmode = Mmode; writeByte(AK8963_ADDRESS, AK8963_CNTL, 0x00); // Power down magnetometer delay(10); // Configure the magnetometer for continuous read and highest resolution // set Mscale bit 4 to 1 (0) to enable 16 (14) bit resolution in CNTL register, // and enable continuous mode data acquisition Mmode (bits [3:0]), 0010 for 8 Hz and 0110 for 100 Hz sample rates writeByte(AK8963_ADDRESS, AK8963_CNTL, Mscale << 4 | Mmode); // Set magnetometer data resolution and sample ODR delay(10); }

— Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/493, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKXU7CT4HXEW24GR2Y3YK42TVAVCNFSM6AAAAABBBAAWOCVHI2DSMVQWIX3LMV43ASLTON2WKOZSGA2TIOBYGUYDENY . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Overff commented 9 months ago

So what is your question?

Where in your code are ASAX, ASAY, ASAZ?

kriswiner commented 9 months ago

initAK8963 https://github.com/kriswiner/MPU9250/blob/master/MPU9250_BME280_SPIFlash_Ladybug/MPU9250.cpp (line 242), for example, to get "magCalibration (i.e., ASAX, etc) and

magcalMPU9250 (line 328) to get "magBias) offset (or hard-iron) bias..

I am correcting for factory-measured axial sensitivity (ASAX, etc) as well as offset bias in the main code.

  mx = (float)magCount[0]*mRes*magCalibration[0] - magBias[0];  // get

actual magnetometer value, this depends on scale being set my = (float)magCount[1]mResmagCalibration[1] - magBias[1]; mz = (float)magCount[2]mResmagCalibration[2] - magBias[2];

On Sat, Dec 23, 2023 at 12:43 PM Overff @.***> wrote:

So what is your question?

Where in your code are ASAX, ASAY, ASAZ?

— Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/493#issuecomment-1868367173, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKRNEMIC2HKPS7DBIULYK467TAVCNFSM6AAAAABBBAAWOCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNRYGM3DOMJXGM . You are receiving this because you commented.Message ID: @.***>