Open phase1 opened 10 years ago
Did you calibrate the magnetometer? The sketch has my calibrations in it; you need to at the least measure the min/max of the mag values in your environment and then apply an offset to each mag axis that is the average of the two. Poor man's calibration. More elaborate calibration can keep track on min/max on the fly and continuously update the mag calibration. For my testing to date, the simple method works well. For in-the-field applications, something better needs to be done. I suspect this is your problem.
Hi Kris,
I will try that next. Thanks for your help, i'll update you with my status.
Thanks,
Richard
On Mon, Jun 16, 2014 at 3:44 PM, Kris Winer notifications@github.com wrote:
Did you calibrate the magnetometer? The sketch has my calibrations in it; you need to at the least measure the min/max of the mag values in your environment and then apply an offset to each mag axis that is the average of the two. Poor man's calibration. More elaborate calibration can keep track on min/max on the fly and continuously update the mag calibration. For my testing to date, the simple method works well. For in-the-field applications, something better needs to be done. I suspect this is your problem.
— Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/2#issuecomment-46225402.
Hi Kris,
The mag calibration has helped with the accuracy of the IMU, however, now i'm getting lots of drift associated with the yaw.
On start, the system is stable, once a rotation in the yaw axis is performed, the system takes a long time to settle. It looks like the system is critically damped and its settling time is about 1.5 minutes. It oscillates about ~0.2 degrees at the settling point.
Would you know how i would go about fixing this?
Thanks, Richard
On Mon, Jun 16, 2014 at 3:52 PM, Richard Chao rchao.4@gmail.com wrote:
Hi Kris,
I will try that next. Thanks for your help, i'll update you with my status.
Thanks,
Richard
On Mon, Jun 16, 2014 at 3:44 PM, Kris Winer notifications@github.com wrote:
Did you calibrate the magnetometer? The sketch has my calibrations in it; you need to at the least measure the min/max of the mag values in your environment and then apply an offset to each mag axis that is the average of the two. Poor man's calibration. More elaborate calibration can keep track on min/max on the fly and continuously update the mag calibration. For my testing to date, the simple method works well. For in-the-field applications, something better needs to be done. I suspect this is your problem.
— Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/2#issuecomment-46225402.
Can you verify that when the sensor is at rest the accelerometer and gyro values are 0,0,1, and 0,0,0 respectively? If the device is at rest there should be no yaw drift. Assuming the accel and gyro are properly calibrated, how much is the yaw drifting at rest? Is the mag varying at rest?
Richard,
One thing you could check is the value of beta if you are using the Madgwick sensor fusion algorithm. I found that larger values of beta (~3) would produce a more rapid convergence than the value recommended by Madgwick (beta ~0.04) in his paper. A +/- 0.2 degree swing or jitter is not too bad considering that the inherent accuracy of the MPU-9250 (or any) motion sensor is at best a few degrees absolute and maybe a degree at best on a relative basis. The other things you could try is to adjust the data sample rates, especially the magnetometer. Try the 8 Hz setting, which should be less jittery. You could adjust the accelerometer and gyro bandwidths lower to get smoother behavior from these devices. Usually one should keep the bandwidth about one-tenth the data sampling rate. So if you are sampling at 200 Hz, you should reduce the bandwidth to 20 - 40 Hz to get less jitter. Lastly, you could write your own smoothing or averaging algorithm to reduce jitter. Invensense suggests using the FIFO to reduce errors to to time misalignment between data register reads. The sketch I wrote does not do this yet but I think this is the right way to go to eliminate this source of potential error. All in all I would say that if you are getting +/- 0.2 degree repeatability in your yaw, the sensor and the sensor fusion algorithms are working properly.
Kris
-----Original Message----- From: phase1 [mailto:notifications@github.com] Sent: June 16, 2014 3:50 PM To: kriswiner/MPU-9250 Cc: Kris Winer Subject: Re: [MPU-9250] Doesn't seem to be working (#2)
Hi Kris,
The mag calibration has helped with the accuracy of the IMU, however, now i'm getting lots of drift associated with the yaw.
On start, the system is stable, once a rotation in the yaw axis is performed, the system takes a long time to settle. It looks like the system is critically damped and its settling time is about 1.5 minutes. It oscillates about ~0.2 degrees at the settling point.
Would you know how i would go about fixing this?
Thanks, Richard
On Mon, Jun 16, 2014 at 3:52 PM, Richard Chao rchao.4@gmail.com wrote:
Hi Kris,
I will try that next. Thanks for your help, i'll update you with my status.
Thanks,
Richard
On Mon, Jun 16, 2014 at 3:44 PM, Kris Winer notifications@github.com wrote:
Did you calibrate the magnetometer? The sketch has my calibrations in it;
you need to at the least measure the min/max of the mag values in your environment and then apply an offset to each mag axis that is the average
of the two. Poor man's calibration. More elaborate calibration can keep track on min/max on the fly and continuously update the mag calibration. For my testing to date, the simple method works well. For in-the-field applications, something better needs to be done. I suspect this is your problem.
Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/2#issuecomment-46225402.
Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/2#issuecomment-46247952 . https://github.com/notifications/beacon/6698410__eyJzY29wZSI6Ik5ld3NpZXM6Qm VhY29uIiwiZXhwaXJlcyI6MTcxODU3ODE3OCwiZGF0YSI6eyJpZCI6MzQ3NTc5Mjh9fQ==--3651 ba1cc50346bb524dbb650195f0cc39eb937a.gif
Hey Kris, I´m working with your arduino basic code for MPU 9250, its working well but I dont use the ahrs fusion. I only use the raw data. Unfortunately the the raw data of the accelrometer are randomly differ from the theoretical calibratet value. I used the following formulars for getting the angle between normal plane of g-vector and z-axis: accRes=sqrt(accx^2+accy^2+accz^2), angle=arccos(accz/accRes)-90 So if I put the ensor plane one the ground in that way, that the z-ais shows up the angle should be near 90 degrees. Sometimes its the case but often if I press reset butten to restart programm, it shows randomly something between 70 or 80 degrees.You have included some calibration functions in your code. Is there anything what I have to consider if I start the programm. If I run the MPU 9150 accelerometer with your code, I dont have that problem. I´m glad if you can help me!
Yes, the current code is set up to push the accelerometer calibration into the hardware acceleration offset registers. Unfortunately, this sometimes results in a 5 - 10 degree error, I think due to the temperature compensation bit in the offset-storing registers not being handled properly. I have asked Invensense about this but haven't received a satisfactory answer. So, what I usually do is NOT write the acceleration calibration bias into the hardware offset registers and instead, just subtract the properly scaled acceleration bias from the calculated result in the main program. You can see here where this approach is commented out in the main code:
// Now we'll calculate the accleration value into actual g's
ax = (float)accelCount[0]*aRes; // - accelBias[0]; // get actual g value, this depends on scale being set
ay = (float)accelCount[1]*aRes; // - accelBias[1];
az = (float)accelCount[2]*aRes; // - accelBias[2];
This is how I recommend you fix your problem. You have to comment out the appropriate write to the accel offset registers in the calibration routine. Should fix your problem. The gyro bias does not suffer from this problem and is handled well by writing the offset bias to the gyro offset register. It has no temperature compensation bit!
Hi Kris
How can I contact you? Would like to discuss some commercial assistance with a project involving MPU9250.
I'm at bruce.bushby@gmail.com
Thanks Bruce
Hi Bruce,
I sent you an e-mail where we can discuss your project.
Kris
I am working on a project where i need yaw pitch and roll using MPU 9250 for establishing the orientation of the robot with respect to obstacles. I am using your basic MPU 9250 code. I am getting the readings from accelerometer and gyro sensors properly but the magnetometer readings are varying by 10 units. Also I am getting the ypr reading. They are fluctuating by 10 degrees. This is my mailing address:- pratiksolanke@yahoo.co.in It would be really helpful if you could take the the time to help me.
I'm not sure what 10 unit mag variation is: if it is +/- 10 mG, this is pretty good. If it is +/- 10 degrees in heading, this is pretty bad!
Firstly, the magnetometer requires calibration (as do the accel and gyro) to remove any bias. For the magnetometer, this means re-centering the response sphere back to the origin by subtracting the average of the min and max for each axis. I think there is a mag calibration routine in one of the MPU9250 sketches at my github repository.
Secondly, the magnetometer is sensitive to any currents nearby, and your mag readings will reflect this as jitter in the readings. You should use a well-designed board that minimizes this interference, make sure to use the device away from external currents, if possible, or shield the sensor if not. Lastly, you can filter the mag output via any number of low-pass/averaging schemes to lower the frequency response of the mag to affect the heading less. In fact, it makes sense for most applications to use a 10 Hz mag sample rate and take a running average to smooth the mag readings for applications where the motion is rather slow like for robots.
What kind of sensor breakout board are you using? The cheap boards from China (especially the purple boards) are junk and will cause you nothing but problems.
I'll send you a private e-mail in a few hours...
I just looked an I guess I haven't gotten around to updating the MPU9250 sketch with a mag calibration routine. Here is one I wrote for the LSM9DS1 that shows the basic idea. When I get some time, I will create a similar function for the MPU9250:
void magcalLSM9DS1(float * dest1) { uint8_t data[6]; // data array to hold mag x, y, z, data uint16_t ii = 0, sample_count = 0; int32_t mag_bias[3] = {0, 0, 0}; int16_t mag_max[3] = {0, 0, 0}, mag_min[3] = {0, 0, 0}; // configure the magnetometer-enable temperature compensation of mag data writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_CTRL_REG1_M, 0x80 | Mmode << 5 | Modr << 2); // select x,y-axis mode writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_CTRL_REG2_M, Mscale << 5 ); // select mag full scale writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_CTRL_REG3_M, 0x00 ); // continuous conversion mode writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_CTRL_REG4_M, Mmode << 2 ); // select z-axis mode writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_CTRL_REG5_M, 0x40 ); // select block update mode Serial.println("Mag Calibration: Wave device in a figure eight until done!"); delay(4000); sample_count = 128; for(ii = 0; ii < sample_count; ii++) { int16_t mag_temp[3] = {0, 0, 0}; readBytes(LSM9DS1M_ADDRESS, LSM9DS1M_OUT_X_L_M, 6, &data[0]); // Read the six raw data registers into data array mag_temp[0] = (int16_t) (((int16_t)data[1] << 8) | data[0]) ; // Form signed 16-bit integer for each sample in FIFO mag_temp[1] = (int16_t) (((int16_t)data[3] << 8) | data[2]) ; mag_temp[2] = (int16_t) (((int16_t)data[5] << 8) | data[4]) ; for (int jj = 0; jj < 3; jj++) { if(mag_temp[jj] > mag_max[jj]) mag_max[jj] = mag_temp[jj]; if(mag_temp[jj] < mag_min[jj]) mag_min[jj] = mag_temp[jj]; } delay(105); // at 10 Hz ODR, new mag data is available every 100 ms } // Serial.println("mag x min/max:"); Serial.println(mag_max[0]); Serial.println(mag_min[0]); // Serial.println("mag y min/max:"); Serial.println(mag_max[1]); Serial.println(mag_min[1]); // Serial.println("mag z min/max:"); Serial.println(mag_max[2]); Serial.println(mag_min[2]); mag_bias[0] = (mag_max[0] + mag_min[0])/2; // get average x mag bias in counts mag_bias[1] = (mag_max[1] + mag_min[1])/2; // get average y mag bias in counts mag_bias[2] = (mag_max[2] + mag_min[2])/2; // get average z mag bias in counts dest1[0] = (float) mag_bias[0]_mRes; // save mag biases in G for main program dest1[1] = (float) mag_bias[1]_mRes; dest1[2] = (float) mag_bias[2]*mRes; //write biases to magnetometer offset registers as counts); writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_OFFSET_X_REG_L_M, (int16_t) mag_bias[0] & 0xFF); writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_OFFSET_X_REG_H_M, ((int16_t)mag_bias[0] >> 8) & 0xFF); writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_OFFSET_Y_REG_L_M, (int16_t) mag_bias[1] & 0xFF); writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_OFFSET_Y_REG_H_M, ((int16_t)mag_bias[1] >> 8) & 0xFF); writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_OFFSET_Z_REG_L_M, (int16_t) mag_bias[2] & 0xFF); writeByte(LSM9DS1M_ADDRESS, LSM9DS1M_OFFSET_Z_REG_H_M, ((int16_t)mag_bias[2] >> 8) & 0xFF); Serial.println("Mag Calibration done!"); }
Thank you for your input, the code now works perfectly with 1 degree of variation in the ypr readings. I was trying to use your code with teensy 3.1. MPU 9250 initialises perfectly but magnetometer does not, it says "AK8963 I AM FF I should be 48", what could the problem be? I had the same problem with the MPU but changing the print statements to write got it working. The readings from accelerometer and gyro are proper only error is with the magnetometer. Thanks once again for your help
I thought you had the magnetometer working before? Is the magnetometer address 0x48 on your board?
That was with arduino mega, it worked flawlessly. Now I am trying to do the same thing teensy 3.1, in the hope of getting even better ypr readings. The magnetometer is not on my board, it is the same one that is there in MPU 9250.
If you are using my code, it should work. In my code I set the MPU9250 to bypass mode by setting register 0x37 to 0x22. This puts the MPU into bypass mode and should allot access to the magnetometer. Can you use an I2C scanner to verify if the mag is accessible?
// simple function to scan for I2C devices on the bus
void I2Cscan()
{
// scan for i2c devices
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknow error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
}
I used the above code and it is only showing only one device at 0x68. With the above logic I tried to directly read 0x0C but it still isn't showing up. Do I have to set MPU 9250 to bypass mode. The same IMU board is working fine with arduino mega.
I also tried to access the magnetometer after the MPU initialisation function, but still nothing. The register 0x37 is being written with 0x22.
If you have set the MPU9250 to bypass mode you should be seeing the magnetometer. Which board are you using?
The cheap blue ones, GY-9250/GY-6500.
Kris,
We are running into a mag calibration issue with an MPU9250 on a custom board. Are you interested in a working with us on a commercial basis to get us past this hurdle? Thank you, satish dot movva at gmail dot com
Satish
Hi Satish,
Can you say a bit more about the issue?
Kris
Hi Kris, we are trying to figure out how to auto calibrate the mag on MPU9250. Right now after startup we have to move the board in a certain manner to get it to calibrate. We are trying to see how we can bypass that. In general we also want to have a consulting resource on hand as we come across and address issues that pop up so was interested in reaching out to see if there was interest.
Satish
Hi Satish,
Auto calibration works the same way as static calibration but is done periodically in the background. Most hardware sensor fusion platforms use this kind of method although the algorithms differ. They also include magnetic anomaly detection and thermal compensation, neither of which basic open-source algorithms include.
As far as consulting is concerned, I am open to answering questions when I have something to offer. Do you have something more formal in mind?
Kris
Hi Kris,
Yes, we are looking for something formal if that is of interest to you.
Satish
Satish,
I'd like to find out more about what you have in mind...
Kris
Sure can we take it offline to email?
onehorse@earthlink.net
Hi all, I ve come across some issues with the MPU9250 I just received.... the magnetometer doesn t power up properly apparently, and although I apply a ramp which is in the spec sheet, I can see the magnetometer either OK or completely unaccessible (tried on few devices). The bypass mode is of course enabled and all checked out with dedicated routines, I believe their IC has an issue at power up, the POR of the magnetometer is simply not working. I've spent 30 hours on that issue, I was quite happy to have everything on a single chip, but looking at the spec of the latest freescale gyro I may have to go back to my previous solution. Last the ecosystem is quite disappointing, their 60Kb flash demo footprint is 5-10 times what is needed for a fusion algo, and the support is simply not existent. Anyone had power on reset issues with the MPU9250? (the reset pin of the magnetomer is not accessible...)
Which MPU9250 breakout are you using? I've had trouble with the purple boards from China. If that's what you have, throw them away now!
I am using ICs ordered from their web shop, received 2 weeks ago. it's a pity the reset pin of the magnetometer is not accessible on this chip...
Who are they?
Do you mean embeddedmasters MPU9250 breakout boards. These are fine and if you are having trouble it is likely a micrcontroller or software issue.
http://store.invensense.com/ProductDetail/MPU-9250-InvenSense-Inc/487537/pid=1135
This is invensense web site where you can order directly the ICs
freescale FXOS8700 + FXAS21002 will do the job...
OK, so you designed and assembled your own boards. Did you tie pin 1 to VDDIO?
NO!!!!!!!!!!!!!!!! is that the rst pin of the magnetometer?!?! I will give a try right now!!
Their datasheet mentions that in the table 9 but it is nowhere shown in their application schematics...
The Chinese purple boards forgot to do this and as a result sometimes the mag works and sometimes it don't, mostly the latter. Absolutely must do.
And I hope you didn't solder the thermal pad to the pc board. Another no no.
no the thermal is no copper zone no worries...I m trying to connect the pin 1, difficullt!
their support and documentations is really bad
They have been more supportive of my efforts, but perhaps I am a special case; their CEO likes our startup!
they dont reply...am on a startup too, maybe i should tell them!
Yes, post reflow soldering is a pain, especially if you have to greenwire it!
Well, you can ask me, I know a lot about the MPU9250.
I will let you know the test result asap, thanks!
Seems all good...wasted so much time on that pfhhhhhhh....Now I hope the sensor is working fine, I was using honeywell and freescale before, all very stable with temperature and degauss. I hope no surprise on the way again...Thanks!
Hi, all good with pin 1 tied to VCC... seems like the bandwidth limitation programmable in the accelerometer config 2 a bit confusing... lets say I need 10 Hz limitation, is that correct that I must write (0<<3) | 5 in this register? (accel_fchoice_b is inverted). Indeed it looks like the bandwidth is still quite high on my side and I am wondering if the digital filter is bypassed or not.
Yes, it's confusing. I went through all the logic once and now all I can do is quote the initiation routine I use:
// Configure Gyro and Thermometer // Disable FSYNC and set thermometer and gyro bandwidth to 41 and 42 Hz, respectively; // minimum delay time for this setting is 5.9 ms, which means sensor fusion update rates cannot // be higher than 1 / 0.0059 = 170 Hz // DLPF_CFG = bits 2:0 = 011; this limits the sample rate to 1000 Hz for both // With the MPU9250, it is possible to get gyro sample rates of 32 kHz (!), 8 kHz, or 1 kHz writeByte(MPU9250_ADDRESS, CONFIG, 0x03);
// Set sample rate = gyroscope output rate/(1 + SMPLRT_DIV) writeByte(MPU9250_ADDRESS, SMPLRT_DIV, 0x04); // Use a 200 Hz rate; a rate consistent with the filter update rate // determined inset in CONFIG above
// Set gyroscope full scale range // Range selects FS_SEL and AFS_SEL are 0 - 3, so 2-bit values are left-shifted into positions 4:3 uint8_t c = readByte(MPU9250_ADDRESS, GYRO_CONFIG); // writeRegister(GYRO_CONFIG, c & ~0xE0); // Clear self-test bits [7:5] writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c & ~0x02); // Clear Fchoice bits [1:0] writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c & ~0x18); // Clear AFS bits [4:3] writeByte(MPU9250_ADDRESS, GYRO_CONFIG, c | Gscale << 3); // Set full scale range for the gyro // writeRegister(GYRO_CONFIG, c | 0x00); // Set Fchoice for the gyro to 11 by writing its inverse to bits 1:0 of GYRO_CONFIG
// Set accelerometer full-scale range configuration c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG); // writeRegister(ACCEL_CONFIG, c & ~0xE0); // Clear self-test bits [7:5] writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, c & ~0x18); // Clear AFS bits [4:3] writeByte(MPU9250_ADDRESS, ACCEL_CONFIG, c | Ascale << 3); // Set full scale range for the accelerometer
// Set accelerometer sample rate configuration
// It is possible to get a 4 kHz sample rate from the accelerometer by choosing 1 for
// accel_fchoice_b bit [3]; in this case the bandwidth is 1.13 kHz
c = readByte(MPU9250_ADDRESS, ACCEL_CONFIG2);
writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c & ~0x0F); // Clear accel_fchoice_b (bit 3) and A_DLPFG (bits [2:0])
writeByte(MPU9250_ADDRESS, ACCEL_CONFIG2, c | 0x03); // Set accelerometer rate to 1 kHz and bandwidth to 41 Hz
// The accelerometer, gyro, and thermometer are set to 1 kHz sample rates, // but all these rates are further reduced by a factor of 5 to 200 Hz because of the SMPLRT_DIV setting
Looks like if you want to run at 10 Hz bandwidth you have to consult the table in the datasheet and see how close you can get it. Above is set for 200 Hz sample data rates and ~40 Hz bandwidth. You could confirm the above via the data sheet and use as a guide to set it up as you want.
Hello Kris,
I have downloaded the source to the 9250 AHRS, but the system dones't seem to be functioning well at all.
The problems i'm experiencing are that the sensor fusion will settle on a value yaw value and whenever the IMU is rotated on the yaw axis, the yaw ill move slightly, and then return to the settled value it initialized to. The roll and the pitch axis are fine and working.
I'm not sure what I should be doing to help correct the problem.
Thanks