Suresh's Site

Don't Panic...

  • Home
  • Code
  • Projects
  • Consulting

Invensense IMUs – What to Know

December 1, 2014 SJ 49 Comments

I’ve previously written about the MPU6050 here, and I have worked with a few of the Invensense offerings over the past while. The Invensense documentation is pretty good, however I’ve found and reported several errata to Invensense over the past couple of years. Some of the fixes have made it into their new SDK – others have not yet. I thought it might be handy to go over some of these errata I ran into, in case other people are struggling with them too like I did.

MPU6000, MPU6050, MPU6500, MPU6055, etc…

There are a lot of different products Invensense has for sale, and I ran into a lot of problems understanding the differences, as from the non-marketing material (e.g. datasheets), they’re very similar devices. At a high-level, the 6000 and 6050 are the same chip – with different communication protocols (SPI/I2C vs I2C). The MPU6055 (or MPU9255) is the one designed for use alongside the Automatic Activity Recognition (AAR) library. But what about the 6050 and 6500? Or the 9150 and 9250?

I emailed support at Invensense and received this response.

My email

I’m very familiar with the MPU6050, but I see the MPU6500 – and it appears to have the same cost as the 6050, and a smaller footprint. Is there anything else different about these two? We spoke a while ago, and I recall you said the 6500 had worse sensitivity. Will the code I wrote for a 6050 be directly portable to the 6500? Is this just a v2 of the 6050?

Similar question with the 9150 and 9250. Prices are same, form factors are different. Is there any appreciable difference in the chip outputs?”

Invensense reply

The MPU-6050 is higher power, lower noise, and larger package versus the MPU-6500. Most of your code should port over, but some low power features are different and will need to be recoded in. Basic data acquisitions shouldn’t have changed.

The MPU-9150 contains the MPU-6050 and an AK8975 magnetometer from AKM. The MPU-9250 contains a MPU-6500 and AK8963. The same differences between gyro/accel are the same you see with 6050 v. 6500. The magnetometer on the MPU-9250 is a little better across the board.

For the remainder of this post, I’ll focus on my experiences with the 6-axis series, but some of the same issues were/are likely in the 9-axis series as well.

Keep up to date

I can’t stress this one enough. Invensense support is really good at staying in communication while they are looking over issues, and I would usually have my answers or a workaround within a week. However, there are some bugs that require lower-level changes, and they get rolled into the new SDKs. So, as much as it sucks to upgrade SDKs and have to deal with the re-tests, odds are you’re getting more than you’re losing.

A perfect example is the Calibration issue that I’ll dig into in an email below. It’s a pretty critical bug that was fixed between MotionDriver 5.1.1 and 5.1.2… However, there were two small multiplier issues which weren’t corrected in that revision, so it’s not quite perfect.

Sensitivity problems

As I was using the IMU in a device that required a bit more precision than most, I spent a lot of time digging into the code whenever I found anomalies. A lot of these anomalies were discovered around calibration. Here is one that is STILL in the latest version of the MotionDriver SDK (5.1.2 at time of writing):

Incorrect SDK code
C++
1
2
3
4
5
6
int mpu_get_accel_sens(unsigned short *sens)
...
  case INV_FSR_4G:
    sens[0] = 8092;
    break;
...

I verified this with their support, and that value should actually return 8192 to stay in line with the rest of the SDK, as below:

Corrected SDK code
C++
1
2
3
4
5
6
int mpu_get_accel_sens(unsigned short *sens)
...
  case INV_FSR_4G:
    sens[0] = 8192;
    break;
...

This only adds slightly more than 1% of error to a system, but when you’re directly comparing with external references, that 1% goes a surprisingly long way!

Calibration problems

Bar none, the biggest source of grief (frankly, almost the only source of grief) with the IMU was around calibration. Again, given that I was comparing with an external reference, the calibration had to be as close as possible and I spent a LOT of time tweaking to get this running. As it turned out, in a previous version of the MotionDriver, calibration was only applied to the fused output quaternion and had NO effect on the returned discrete accelerometer values!

This proved to be the source of about 5-10% error in my system, and all-around a sloppy mistake…

Here was my code, basically copied from the Invensense sample code:

Original calibration code
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
long gyrBias[3];
long accBias[3];
int result;
 
result = mpu_run_self_test(gyrBias, accBias);
 
// Check for passing accelerometer
if ((result & 0x02) == 0x02)
{
  unsigned short accel_sens = 0;
 
  mpu_get_accel_sens(&accel_sens);
  accBias[0] *= accel_sens;
  accBias[1] *= accel_sens;
  accBias[2] *= accel_sens;
 
  dmp_set_accel_bias(accBias);
}

The problem was, this still returned steady-state accelerometer values that were way off (as though they’d never been calibrated). I verified with Invensense that this was, in fact, a bug.

It was fixed and detailed in an app note for MotionDriver 5.1.2, however there was still a bug with the multiplier they recommended to use. They recommended that we use 4096 as the base multiplier when we pass in sensitivities, however I noticed that when I calibrated multiple times in a row, my calibration numbers would diverge.

Instead, again talking to support, we figured out that the scale factor required for each product may be different. For the 6050 and 9150, the scale factor was 2048, but for the 9250, it was 4096.

I haven’t seen this reflected in documentation yet, but I haven’t really looked lately either. In any case, what I have below is what actually works for calibration. I had the MPU setup as +/-4g, and ended up not even using the mpu_get_accel_sens call. Please note that you’ll need to cache the calibration values and send them back to the MPU after every reset, as the MPU only has volatile memory.

Corrected calibration code
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
long gyrBias[3];
long accBias[3];
int result;
int i;
 
result = mpu_run_self_test(gyrBias, accBias);
 
// Check for passing accelerometer
if ((result & 0x02) == 0x02)
{
  for (i=0; i<3; ++i) {
    // The accBias values are stored in +/-8g format
    accBias[i] *= 2048;
    accBias[i] = accBias[i] >> 16;
  }
 
  // Cache these bias values, as they're not persisted to MPU memory
  // Update the MPU bias registers (needs to be done on every reset)
  mpu_set_accel_bias_6050_reg(accBias);
}

Anything else?

Those were the main issues I have run into so far. If anyone else has come across something new, please let me know!

Feature Photo credit: SparkFunElectronics / Foter / CC BY

Related

Embedded IMU, Invensense, MPU6000, MPU6050, MPU6500, MPU9150, MPU9250

Comments

  1. dajiang says

    January 11, 2015 at 8:36 pm

    hi,
    have you tried their new driver 6.1?

    Reply
    • SJ says

      January 11, 2015 at 10:36 pm

      Hi, I believe their 6.1 is for the 91xx and 92xx series, so no, I have not yet tried it. Have you run into any problems?

      Reply
      • dajiang says

        January 12, 2015 at 12:46 am

        The biggest problem is that obtained quaternion values are very bad.
        in 6.1, they added more complex Quaternion calculation in micro-processor (MCU), which resulted in more complex code for MCU. However, for some critical calculations, they only give library functions, which makes it almost impossible to debug.
        My experience with their tech support is also very bad. It took them weeks to reply my email, if they replied.

        Reply
        • SJ says

          January 12, 2015 at 12:49 am

          Really? I’m surprised by both of those! Interesting to know!

          What issues have you been running into with their quaternions? How have you compared the results?

          Reply
  2. fre says

    January 28, 2015 at 3:15 pm

    hey Suresh, maybe you can help me? I’d like to read the raw 16 bit gyro data from the mpu6500, but how can I be shure that that the lower 8 bits match the higher 8 bits? kind regards, Fré

    Reply
    • SJ says

      January 28, 2015 at 3:49 pm

      Hey Fré, I’m not entirely sure what you mean… What do you mean by matching the lower and higher bits?

      Reply
      • fre says

        January 28, 2015 at 4:38 pm

        if I read out GYRO_YOUT_H first with spi and after that read out GYRO_YOUT_L with spi
        how can I know that both bytes correspond to the same measurement? because in mean time the sensor could already have taken a new measurement. and then the GYRO_YOUT_H would be of the first measurement while the GYRO_YOUT_L could be of a following measurement.

        Reply
        • SJ says

          January 28, 2015 at 5:37 pm

          Hmm, so at a high-level, the registers only refresh every X milliseconds, so if you know you’re in that timeline, that might be an option. However, the far better option is to just make sure you’re bulk reading both bytes of a register at the same time (actually, you should try to read all 12-14 bytes in all the registers at the same time (e.g. 1 I2C call).

          There is a raw-data-ready interrupt either by default, or requiring some setup. That could provide some assurance.

          Lastly, what about setting up to use the FIFO?

          Reply
          • fre says

            January 28, 2015 at 5:42 pm

            hey thanks but, what do you mean with bulk reading? The registers are only 1 byte in size right? so to get the 16bit data size i have to read two different registers.

            Reply
            • SJ says

              January 28, 2015 at 5:44 pm

              Yep, but you can instead setup the I2C to start at the first register (I can’t recall which it is) and tell it to read, let’s say, 12 bytes of data (which would be about 6 registers). The MPU will serve up the data appropriately (at least, it should).

              Now, in 1 I2C call, you’ve read in all your gyro and accelerometer data.

              Reply
              • fre says

                January 28, 2015 at 6:40 pm

                I don’t get it. One register in the MPU6500 is 1 byte in size right? so why would 12 bytes of data be 6 registers?

              • SJ says

                January 28, 2015 at 7:10 pm

                Have you read my post on talking to the MPU6050 from the BLE112? http://www.sureshjoshi.com/embedded/ble112-communicating-with-mpu6050/

                In it, I show demo code where I need to call read 12 times (call hardware_i2c_write(208,0,1,”\x3b”)… I need to call it 12 times because something was wrong with the I2C in the BLE112. I think this is similar to what you’re doing. Calling 12 reads to get 3 gyro values, 3 accelerometer values (e.g. 6 measurements) and each measurement is 2 bytes (each measurement has a high and low byte).

                If the I2C worked better, the correct call would have been call hardware_i2c_write(208,0,14,”\x3b”) – which would return 3 gyro measurements, 1 temperature measurement, and 3 accelerometer measurement – by reading 14 consecutive bytes (or 14 consecutive registers) from the MPU6050. I only included the temperature measurement because its registers are between the gyro and accelerometer.

              • fre says

                January 28, 2015 at 7:18 pm

                I’m reading out with spi, but that doesn’t change a thing I believe. So if I understand wel, if you want to read 6 consecutive registers from the MPU6500. you can do that by reading the first (for which you sent the adres of the register) and then keep reading(and you don’t have to send the adresses for the following 5 registers

              • SJ says

                January 28, 2015 at 7:20 pm

                Exactly, that’s a better way to explain it 🙂

                Essentially, you just tell it the length you want to read back, and it will continue reading. It’s unlikely that you’ll get a gyroscope measurement change between reading those two consecutive registers in ‘bulk read’ mode.

              • fre says

                January 28, 2015 at 7:21 pm

                that’s amazing, thanks a lot! how did you discover this (can you find this in the datasheet?)

              • SJ says

                January 28, 2015 at 7:22 pm

                I’ll be honest, I don’t remember where it was exactly for this chip. It’s how I would expect any embedded system to function within reason. Maybe it was mentioned in an example application, or in the register map/datasheet – however, I first looked at this chip in 2012, so it’s hard to recall 🙂

  3. Alex says

    May 5, 2015 at 5:32 pm

    Hi Suresh. I have a question. The quaternions that are outputted through InvenSense’s MPL are immune to linear accelerations?
    Say.. I rotate the sensor while making sure gravity is the only acceleration that impacts the device. Will I get the same quaternion if I do the same rotation but while applying linear acceleration as well (like suddenly translating the system on the x axis, for example)?

    Sorry if my question is ambiguous.

    Reply
    • SJ says

      May 8, 2015 at 11:43 am

      Ooh, that’s a good question, that I can’t really recall the answer to. When I was doing something like this, I resolved everything into linear accelerations, world accelerations, and yaw/pitch/roll. It -seemed- that linear accelerations largely left the yaw/pitch/roll unaffected (after the math which resolved quaternions to YPR were applied). There could have been some coupling, but it seemed transient.

      Reply
      • Surya Prakash Sharma says

        September 23, 2015 at 2:43 pm

        Hey Suresh,

        I’ve been working with the Invensense chips for a while now (~1.5 years), and I was reading through your post because my linear acceleration calculations show a small amount of bias / offset (0.01 – 0.02g’s). When placed on a surface, gravity is reported as 1.02 or 0.98g’s.

        This is causing issues in our application / research. Did you notice anything like this? I’ve changed my code to adjust for the first issue in this post, but I’m not sure if I should be changing the second one. You mention you hard coded the multiplier to 2048, and I’m not sure how that will change the data, but I guess the only way to find out is to try the change and experiment.

        Reply
      • Surya Prakash Sharma says

        September 30, 2015 at 2:10 pm

        Hi Suresh,

        I posted twice but my comments don’t seem to be posting.

        Could you share your code to find linear accelerations? I’m seeing an error of ~0.01 or 0.02g in my linear acceleration calculations.

        Reply
      • Surya Prakash Sharma says

        September 30, 2015 at 2:12 pm

        Hi Suresh,

        Could you share your code for finding linear accelerations? I’m using the Quaternion data and Raw acceleration to find linear accelerations, but I have an error of ~0.01 or ~0.02 g on each axis.

        Reply
        • Surya Prakash Sharma says

          September 30, 2015 at 2:13 pm

          ps: Commenting using Facebook isn’t working.

          Reply
        • SJ says

          September 30, 2015 at 6:14 pm

          I don’t have my code handy at the moment, but take a look at what Jeff Rowberg did here: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

          Reply
  4. James Tang says

    May 17, 2015 at 11:42 pm

    Hi Suresh. I just bought a 10 DOF IMU board with MPU9255. Do you think code for running MPU9150 (data acquisition like read quaternion from FIFO) is OK for the new MPU9255 without re-coding? I tried to find the InvenSense AAR library, it mentions that page does not exist. Please let me know if you have any idea about the new MPU9255. Thanks

    Reply
    • SJ says

      May 20, 2015 at 12:02 am

      The code -should- be compatible, but worse is that the Invensense dev website seems to be down. I would send in a support call for that, because that should be up and you should be using the correct library. Which IMU board did you purchase?

      Reply
      • James Tang says

        May 20, 2015 at 9:47 am

        SJ,

        Thank you for your reply. Here is the one I bought from Amazon:
        https://www.amazon.com/Inertial-Measurement-Position-Temperature-Consumption/dp/B00VUHIDLA/ref=as_li_ss_tl?ie=UTF8&qid=1432129419&sr=8-1&keywords=10+dof+imu&&linkCode=ll1&tag=sj033-20&linkId=f2f4f7e4eb4f2274bc416d40d38f2498

        Reply
  5. Surya Prakash Sharma says

    September 23, 2015 at 2:55 pm

    Would the scale factor for the MPU9150 at +-2g also be 2048?

    Reply
  6. Barak Manos says

    January 23, 2016 at 2:46 am

    Hi Suresh.

    Great website, thank you very much!!!

    I am using the same code (register read/write operations) for both MPU9150 and MPU9250.

    I am able to access the accelerometer and the gyroscope on both devices.
    But I am unable to access the magnetometer (compass) on MPU9250.

    My initialization code is very simple:
    1. Register PWR_MGMT_1:
    // Reset all the internal registers of the MPU to their default values
    WriteReg(0x68, 0x6B, 0x80); Delay_ms(100);
    2. Register INT_PIN_CFG:
    // Allow the host application processor to directly access the auxiliary I2C bus of the MPU
    WriteReg(0x68, 0x37, 0x02); Delay_ms(100);
    3. Register PWR_MGMT_1:
    // Set the MPU clock source to one of the gyroscope clocks, and disable the temperature sensor
    WriteReg(0x68, 0x6B, 0x09); Delay_ms(100);

    After that, on MPU9150, my initial attempt to access the compass completes successfully:
    1. Register CNTL1:
    // Power-down mode:
    WriteReg(0x0C, 0x0A, 0x00);

    But the same code fails on MPU9250 (the I2C-Write operation never completes).

    I have compared the register contents of each device after the initialization procedure:

    MPU9150 Register Contents | MPU9250 Register Contents
    ————————————————————|————————————————————
    837F04CD E4CE01D8 F63D02B8 E96F6F94 | C5CEDDED 9813DD4F E5F1FFFC 005F5A87
    37000000 00000000 00000000 00000000 | B0AAB900 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000
    00000000 00000002 00000501 A0FBDC3F | 00000000 00000002 0000057F FF0508B7
    B0000000 DFFF1900 8C000000 00000000 | 4412F0FF FC006300 74000000 00000000
    00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000
    00000000 00000000 00000009 00000000 | 00000100 00000000 00000009 00000000
    B4B5F3FB 4DD9ED7F 7B7D0F3F 3EE9EB6F | 319A5AF4 0D009206 00009BC9 4D20558A

    The only differences in writable registers are given below:

    Address | Value on MPU9150 | Value on MPU9250 | Description for MPU9150 | Description for MPU9250
    ————|————————–|————————-|———————————|———————————
    0x00 | 0x83 | 0xC5 | | SELF_TEST_X_GYRO
    0x01 | 0x7F | 0xCE | | SELF_TEST_Y_GYRO
    0x02 | 0x04 | 0xDD | | SELF_TEST_Z_GYRO
    0x03 | 0xCD | 0xED | |
    0x04 | 0xE4 | 0x98 | |
    0x05 | 0xCE | 0x13 | |
    0x06 | 0x01 | 0xDD | |
    0x07 | 0xD8 | 0x4F | |
    0x08 | 0xF6 | 0xE5 | |
    0x09 | 0x3D | 0xF1 | |
    0x0A | 0x02 | 0xFF | |
    0x0B | 0xB8 | 0xFC | |
    0x0C | 0xE9 | 0x00 | |
    0x0D | 0x6F | 0x5F | SELF_TEST_X | SELF_TEST_X_ACCEL
    0x0E | 0x6F | 0x5A | SELF_TEST_Y | SELF_TEST_Y_ACCEL
    0x0F | 0x94 | 0x87 | SELF_TEST_Z | SELF_TEST_Z_ACCEL
    0x10 | 0x37 | 0xB0 | SELF_TEST_A |
    0x11 | 0x00 | 0xAA | |
    0x12 | 0x00 | 0xB9 | |
    ————|————————–|————————-|———————————|———————————
    0x62 | 0x00 | 0x01 | |
    ————|————————–|————————-|———————————|———————————
    0x70 | 0xB4 | 0x31 | |
    0x71 | 0xB5 | 0x9A | |
    0x72 | 0xF3 | 0x5A | FIFO_COUNTH | FIFO_COUNTH
    0x73 | 0xFB | 0xF4 | FIFO_COUNTL | FIFO_COUNTL
    0x74 | 0x4D | 0x0D | FIFO_R_W | FIFO_R_W
    0x75 | 0xD9 | 0x00 | WHO_AM_I | WHO_AM_I
    0x76 | 0xED | 0x92 | |
    0x77 | 0x7F | 0x06 | | XA_OFFSET_H
    0x78 | 0x7B | 0x00 | | XA_OFFSET_L
    0x79 | 0x7D | 0x00 | |
    0x7A | 0x0F | 0x9B | | YA_OFFSET_H
    0x7B | 0x3F | 0xC9 | | YA_OFFSET_L
    0x7C | 0x3E | 0x4D | |
    0x7D | 0xE9 | 0x20 | | ZA_OFFSET_H
    0x7E | 0xEB | 0x55 | | ZA_OFFSET_L
    0x7F | 0x6F | 0x8A | |

    Please note that I also included the read-only WHO_AM_I register, because:
    1. It is within that segment of different registers (between 0x70 and 0x7F)
    2. It shows a value different from what the data-sheet specifies (0x68 on MPU9150 and 0x71 on MPU9250)

    I have taken each one of the following actions in an attempt to resolve the problem, but none of them seemed to show any positive results:
    1. Before accessing the compass on MPU9250, I wrote the entire register contents that I had previously read from MPU9150 into MPU9250.
    2. When accessing the compass on MPU9250, instead of using 0x0C as the address of the AKM device on the I2C bus, I tried addresses 0x0D, 0x0E and 0x0F. I found a driver which was using 0x0C<<1 instead of 0x0C, so I tried addresses 0x0C<<1, 0x0D<<1, 0x0E<<1 and 0x0F<<1 (0x18, 0x19, 0x1A and 0x1B) as well.

    I admit that I have not tried to combine both of the actions above, because at that point, I was pretty sure that something else was fundamentally wrong.

    Again – the general question is:
    Are there any differences between MPU9150 and MPU9250 for accessing the compass, that I am missing?
    Or is my initialization code wrong (or partially incomplete), in a manner that somehow allows me to access the compass on MPU9150 but not on MPU9250?

    Thank you very much 🙂

    Reply
    • SJ says

      January 24, 2016 at 4:03 am

      Hi! As a quick question, are you using the latest Invensense SDK? Or a secondary question, have you looked at this? http://www.i2cdevlib.com/devices/mpu9150#source -> There are examples of reading the compass in the source code, which might help out.

      Reply
      • Barak Manos says

        January 24, 2016 at 4:14 am

        I have definitely looked at this before, while trying to figure out differences in the driver implementation, since this appears to be where the problem is.

        Our driver is very simple, as I have specified in the (ill-form) question above:
        1. Reset all MPU registers to their default values.
        2. Configure it to bypass mode, so that we can access the compass as if it was on the primary I2C and not on the auxiliary I2C.
        3. Set the MPU clock source to one of the gyroscope clocks. After that

        After that, any attempt to access the compass fails (i.e., never returns).
        I have compared this with the “official” driver (similar to what’s in the link that you’ve suggested).
        At the bottom line, it uses the same 3 operations in order to initialize the MPU.
        And the whole thing seems to be working well on MPU9150.

        But to answer your initial question – no, we are not using the Invensense SDK. I shall have a look and see if it is different than previous stuff that I found on the net (GitHub, Invensense website, etc).

        Thank you very much!!!

        Reply
  7. Barak Manos says

    March 1, 2016 at 9:07 am

    Hi.

    For anyone who ever comes across this problem…

    I have found a description of the problem in several places, stating that if PIN1 is not connected to VDDIO, then the magnetometer does not output anything.

    I asked our HW guy to give it a try (connect PIN1 to VDDIO), and I was able to read from the magnetometer afterwards.

    On MPU9150, we have it connected to ground, so I’m not sure what has changed in MPU9250 on that aspect.
    The data-sheet isn’t really clear about this anyway (stating both “PIN1 reserved” and “PIN1 connect to VDDIO”).

    Thank you for your previous help and support 🙂

    Reply
    • SJ says

      March 1, 2016 at 9:54 am

      Thanks for the info Barak! Strange issue!

      Reply
    • Nitin Harish says

      June 25, 2016 at 11:33 pm

      Thank you so very much, I wasted 8 hours on this issue.

      Reply
      • Nitin Harish says

        July 1, 2016 at 6:59 pm

        I still have no luck. Still MAG does not output any data at all because it is NOT discovered on I2C even though I set bypass mode on 9250.

        Can anyone help ?

        Reply
        • Barak Manos says

          July 2, 2016 at 5:15 am

          Try this:

          uint8_t Invensense_On = 0;
          uint8_t Invensense_AsaX = 0;
          uint8_t Invensense_AsaY = 0;
          uint8_t Invensense_AsaZ = 0;

          void Init(void)
          {
          WriteReg(MPU_ADDR, MPU_PWR_MGMT_1 , 0x80); Delay_ms(100); // Reset all the internal registers of the MPU to their default values
          WriteReg(MPU_ADDR, MPU_INT_PIN_CFG, 0x02); Delay_ms(100); // Allow the host application processor to directly access the auxiliary I2C bus of the MPU
          WriteReg(MPU_ADDR, MPU_PWR_MGMT_1 , 0x09); Delay_ms(100); // Set the MPU clock source to one of the gyroscope clocks (more accurate), and disable the temperature sensor
          WriteReg(AKM_ADDR, AKM_REG_CNTL , 0x00); Delay_ms( 10); // Power-down mode
          WriteReg(AKM_ADDR, AKM_REG_CNTL , 0x0F); Delay_ms( 10); // Fuse ROM access mode
          ReadReg (AKM_ADDR, AKM_FUSE_ASAX , &Invensense_AsaX); // X-axis sensitivity adjustment value
          ReadReg (AKM_ADDR, AKM_FUSE_ASAY , &Invensense_AsaY); // Y-axis sensitivity adjustment value
          ReadReg (AKM_ADDR, AKM_FUSE_ASAZ , &Invensense_AsaZ); // Z-axis sensitivity adjustment value
          WriteReg(AKM_ADDR, AKM_REG_CNTL , 0x01); // Single measurement mode
          }

          Reply
          • Nitin Harish says

            July 8, 2016 at 11:30 am

            Barak Manos, it did NOT work.

            I think your code line here:
            WriteReg(AKM_ADDR, AKM_REG_CNTL , 0x00); Delay_ms( 10); // Power-down mode

            Assumes that I know MAG’s address and it is talking to my host processor but as I said in my post above,

            My code below does NOT find the MAG (WHOAMI), I have seen it with scope on the I2C bus that my I2C reads are NOT replied by the MAG.

            /* Find compass. Possible addresses range from 0x0C to 0x0F. */
            for (akm_addr = 0x0C; akm_addr <= 0x0F; akm_addr++)
            {
            int result;

            result = i2c_read(i2c_device_fd, AKM_REG_WHOAMI, data, 1, (I2C_DEST_CHIP_TYPE)akm_addr);
            if (!result && (data[0] == AKM_WHOAMI))
            break;
            }

            Reply
            • Barak Manos says

              July 8, 2016 at 12:35 pm

              Well, we’ve had this problem for as long as PIN1 was not connected to VDDIO (on MPU9250 only). Once we sorted this out, the magnetometer became accessible. If that does not work for you, then I’m afraid I cannot help from remote distance (i.e., I’d need your SW + HW).

              Reply
              • Christ says

                March 14, 2017 at 7:34 am

                Hi Barak. just wanted to find out if the connection of PIN1 to VDDIO was the only change you made to make it work.

                Thanks

    • Goutam bhat says

      April 13, 2017 at 1:23 pm

      can you please say which is pin 1 and VDDIO? i think its has no external legs. then how to connect them?

      Reply
  8. Raghavan K says

    May 24, 2016 at 12:20 am

    Interfaced MPU 9250 using SPI.
    The readings from accelerometer seem to be incorrect.
    Can you provide some support reg. calibration?

    Reply
    • SJ says

      May 24, 2016 at 12:11 pm

      Hey, I think regarding actual support – you need to talk to Invensense. I don’t work for them, I just posted some of the stuff I’ve noticed over the years.

      Reply
      • Raghavan K says

        May 24, 2016 at 9:56 pm

        There was no response from Invensense

        Reply
  9. yangcheng says

    June 14, 2016 at 11:35 pm

    Hi,Suresh
    What is the calibration part,is this calculating the offset or what?

    I only know that the raw data have offset if the chip put in stationary state.

    Reply
  10. embeddedstuffcom says

    January 18, 2017 at 1:07 am

    Hi Suresh,
    So which IMU sensor you think better if we compare MPU 6050,9150,9250.

    Thanks

    Reply
    • SJ says

      January 24, 2017 at 9:04 pm

      What metrics are you comparing across? Power? Noise? Functionality? What’s the application?

      Reply
      • RG says

        February 20, 2017 at 7:23 am

        I too have the same question. I am looking for good functionality (low error) and for automotive application ? can you suggest.

        Reply
  11. RG says

    February 20, 2017 at 7:26 am

    Hi SJ,
    How do you validate acc, gyro and magneto output values of MPU9150. Do you compare it with a standard equipment or is there any test program available from InvenSense ? I want to find out how much the output deviates over time.

    Reply
    • SJ says

      February 21, 2017 at 11:45 am

      If you need to do a ‘serious’ calculation, then you’ll need professional grade equipment and rigs.
      For ‘light’ calculations, you can probably get away with a known level platform to test post-calibration drift, and a sensitive servo to work on rotations.

      For rotations, eg. You put in a known rotation profile to your ‘rig’ and read the output values to make sure they match. If you can build a rig to perform known accelerations, all the better.

      For rotations, a turntable or something might do in a pinch.

      Reply
  12. Alin-Constantin Paun says

    July 26, 2017 at 5:11 am

    Hi SJ,
    First thanks for the post, I found out some great things I didn’t know about regarding Invensense IMUs!
    Have you ever tried tracking an object in 3D space using one of these IMUs?
    I’ve recently bought a MPU 9250 unit trying to do so. The only good implementation I’ve found online is this one: https://github.com/xioTechnologies/Gait-Tracking-With-x-IMU.
    I’ve been trying to use the code from above, by exporting gyro, acc and mag data into CSV format and feeding them to the MATLAB script, but all I get is nonsense, although the data provided is valid. Do you have any idea what would be wrong by using this approach? I guess one of the problems could be related to improper choosing of samplePeriod inside MATLAB’s Script.m.

    Reply

Leave a Reply Cancel reply

Top Posts & Pages

  • Android Kiosk Mode Without Root
    Android Kiosk Mode Without Root
  • SSIS String Variables in Derived Columns
    SSIS String Variables in Derived Columns
  • Invensense IMUs - What to Know
    Invensense IMUs - What to Know
  • Changing Android's Locale Programmatically
    Changing Android's Locale Programmatically
  • You Stream, I Stream, We All Stream For Protocol Buffers
    You Stream, I Stream, We All Stream For Protocol Buffers

Follow me on Twitter

My Tweets

Categories

  • CB (3)
  • Development (28)
  • Embedded (16)
  • Mobile (30)
  • Productivity (13)
  • Thoughts (15)

Copyright © 2018 · Daily Dish Pro Theme on Genesis Framework · WordPress · Log in