IMU - MPU9250 on Arduino Uno - Communication error

MPU9250 breakout board i am using.
sparkfun MPU9250 breakout board for reference (No idea if this is important)

I am not sure which info is relevant;

Communication failure in IMU (MPU9250). I had tried to work through the code and cut out what I thought was irrelevant am using the Sparkfun example code MPU9250BasicAHRS. I have cut the code to remove all LCD references (I still get the same result as the orignal code, so i am confident i have not messed up the code). The only change i made to allow a read of myIMU.readByte is a reference of the interrupt pin that i changed from dig pin 13 to pin 2 (as i have an SD card shield that uses pins 10-13 only). Also i have the same issue with out the SD shield present.

Differences between the sparkFun example MPU9250 (3.3V) and my MPU9250 is that mine has a 3.3V regulator on it so i can run of 5V (I think).

IMU Arduino UNO R3
SCL A5 (shown to be SCL in diagrams)
SDA A4 (shown to be SDA in diagrams)
INT unconnected or D2 it doesn’t seem to make a difference.
EDA Unconnected
ECL Unconnected
ADO Unconnected
NCS Unconnected
FSYNC Unconnected

Communication test part of code;
// Read the WHO_AM_I register, this is a good test of communication
byte c = myIMU.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);
Serial.print(F("MPU9250 ")); Serial.print("I AM “); Serial.print(c, HEX);
Serial.print(” I should be "); Serial.println(0x71, HEX);

if (c == 0x71)

I read 70 instead of 71. If i change the ‘if’ criteria to 70, the rest of the code runs correctly in as much that it outputs to the serial monitor however the values are not correct (sensible numbers but the values do not correspond with the movement of the board (the BAUD rate is correct)).

library that MPU2950BasicARHS uses: MPU9250 and quaternionFilters

So i tried to look into the MPU9250 library that is included in setup but the test communication is beyond me.


  1. Is it possible the i get a value of 70 due to a parameter setup (e.g. in the MPU9250 library i may need to change the range of g?), I am guessing not.
  2. Do i need to amplify the SDA and SCL to run in the UNO as it is 5V?/use a pull up?
  3. Is the communication issue likely to be in the MPU9250 library
  4. Any thing else to look into?

Also i wasn’t sure if it was necessary for me to post up the code, if so just let me know!

Thank you for any help!

I sounds like you have a level conversion problem, your MPU board will be pulling the lines up to 3v3 as that’s the maximum it’s pins can cope with.

DO NOT pull it up to 5v, it has the potential to blow the chip up, so don’t do that.

So you are left getting a IO level converter or changing the micro to work on 3v3.
If your using a standard Arduino board that might be harder. (You can get the 3v3 versions)

One of these boards would do the trick, though if you go hunting for others ensure they are capable of doing I2C level conversion.

Thank you! I have looked into it, and although the 3.3V signals should normally work for 5V devices due to the the Vih being low enough on the 5V to be triggered by the 3.3V signal, the ATMega 328 has a higher Vih to make the chip more robust. I will buy the logic board and give it ago (unless the Hackerspace has the BSS138 and 10K components?).
]Furthermore I guess this is why the code seems to run ok, but the values do not match the movement, as it is reading 0’s instead of 1’s, hence why the values jump around.

I am overoptimistic you have solved it!

Thanks again!

Your levels should be fine! The atmega328 has a Vih of 0.6*Vcc, which is 3.0V, and since i2c uses a pullup and open-drain signalling it should be hitting a Voh of 3.3v easily.

I actually think your board has an MPU-6500 on it, not an 9250.

Yeah, that breakout looks almost identical to mpu6050 boards I have here. I guess if the registers are different between the two that’d explain the wierdness.

Hmm. The 6500 board and the 9250 do look identical, I assumed the difference was in the chip (mag meter is included in 9250). I can just about make out the chip code MP92 W967A1 4101 (don’t bother searching nothing comes up). Also on the back of the board are tick boxes for 9250,9255,6500,6555 mine has the 9250 ticked, which could only mean mix up at the factory if it is not the right one. Also the when I cheat an output, the values for the magmeter show up ( I know it will be the code, but I thought I wouldn’t get anything to run if the chip didn’t have a mag meter). I need to read up about the logic levels as I am now confused about them.

You seem to be initialising the unit ok and are receiving data from it - I’d be surprised if it was a logic levels issue. I suspect that others are on the right track with the unit not being exactly the device that was anticipated - the device ID you’re getting back is different, not zero or random.

FWIW, I’d consider reverting to using pin13 for INT and check that - I don’t know enough to know for sure but not all pins are created equal (esp wrt interrupts and timers), and I think the INT pin is meant to indicate that the sensor has valid data ready, so it might matter (although the code shouldn’t be free-wheeling if it’s waiting for that signal, so dunno).

I’d also look for different sample code, too. I built a head tracker to use with FPV goggles and I remember having to make some sort of changes because of how my cheap modules behaved slightly differently to someone else’s pricier ones.

Sounds like a plan. I will give it a go and then post up results

(Highlights: address 70 is for 6500 chip. I did get address 73 (9255 chip) for a little bit, then it changed back to 70.)

Ok, so I have gone back to the original Sparkfun code, removed the SD shield, and put the int wire to D12 (my mistype, when i earlier stated D13).

You were right! I do not have a 9250 chip.

I received ‘I am 0x73’ (9255 address)
From earlier searching I know, this means my chip is 9255 not 9250 and my chip number matches this guys chips number whom also believes he was given a 9255 instead of a 9250;

Confused as to why i was receiving 0x73 instead of my earlier 0x70 i then disconnected the int wire… and proceeded to mess with all the wires, every time i received 70. I changed many wires (Vin, different int values even different ADO values (i dont really know why i did any of this, i got over excited i guess). and then returned all wires back to original, but now i get 0x70. 70 is the address of the 6500 chip. I believe the 9250 and 9255 both have the 6500 inside them but also have the mag meter in them. the difference between the 9250 and 9255 is the mag output data resolution is 14bit for the 9250 and 14 or 16bit for the 9255 so changing the address should still give accurate data (i think).

Final question; How can i have changed the address of the chip? is this even possible? why do i have the same chip code as a guy that has a 9255?

It might be a wiring issue, or maybe something is screwy with your i2c code. I have been sick all week, which is why I haven’t been in, but next time I catch you we can look at what’s going on with my logic analyzer.

Cheers, buddy it is driving me mad. On the plus side I feel i am learning a lot. Changed the int to 2 and the code to 2 and now the address is 20… I am bamboozled. Also it would be good to see a logic analyzer

Now it is 30… I am starting to think I fecked the solding up.

What do you have connected to the fsync?
The data sheet says you should pull this to ground.

AD0 pin is your I2C address pin, this should be pulled high or low (some chips allow floating to be a third value) depending on what address you want to give it on the I2C bus.
This usually only is read when the chip is powered on.

I would be leaving the INIT pin disconnected until you are happy talking to it.
Just by manually requesting data.

Hope this helps

You were correct! I have removed the INT wire, connected FSync to ground. it read 73 (which is 9255 instead of 9250). Then after it reset it went to 70.
I trusted hookup guides instead of working though the datasheet, It wont happen again! (But i suppose this is how you learn by making many mistakes)
I think i should check the soldering tomorrow, and see what a logic analyzer says about it. I still dont understand how the value changed from 73 to 70.

Thank you for everyones help so far!

Update: The chip is definalty a 9255 (confirmed by bus pirate). however the arduino is sill claiming it is only a 6500.

My plan of action is;

Logic level shift to 5V - the script i am using is for a 3.3v arduino (i dont think this matters as my board has a 3.3V regulator) but short of knowing what else to check this seems like a suitable coarse of action.

To create a logic level converter (i can order one but dont want to wait if i can help it) is BSS138 chips and 10Kohm resisters. I have the resisters does the space have the BSS138 chips (I dont think so i havent found any).

The other course of action is to try to figure out what is going on with the I2C using the bus pirate (but i do not have one at the moment so I am back to shifting the logic level).

Any other ideas?

Does not need to be a BSS138 “chip” most small N channel enhancement mode MOSFET should do.

There is probably something that suits in the boneyard.

Or I have IR 2402 types here if you want them.

Thank you for the offer however A logic analyzer showed that the logic level is not the issue. By pulling the ADO to 3.3V gives either 6500 chip or 9255 chip. why it changes between the two i have not discovered yet. I have lost motivation to find out why so i am just focusing on getting the Arduino to out put the IMU data and GPS data and to SD data log.

It’s sounding more like you should switch to a 3v3 Arduino, that way there will be no need for logic conversions.
SD cards also run on 3v3 logic, not sure on your GPS but some are also 3v3 logic.