Arduino UNO - Sparkfun MPU 9150 - I2CWriteFail

Hi guys,

I've been a pretty passive member in the Arduino community so far and could solve all my problems by reading trough the forum.. till today!

For my bachelor thesis I'am building one of those balancing - segway like - robots. As I'am from a purely mechanic background I haven't had any experience with Arduino and barely any in the field of electrics and programming. So thats beeing said I'am going to explain my problem:

To get the inclination of the robot I use the Sparkfun MPU 9150 Breakoutboard (SparkFun 9DoF IMU Breakout - ICM-20948 (Qwiic) - SEN-15335 - SparkFun Electronics ) which is quite discussed in the forum as well.

I got is working with following connection:

GND <-> GND
3.3V <-> VCC
A4 <-> SDA
A5 <-> SCL

On the software side I use the Library that is given by Sparkfun (GitHub - sparkfun/MPU-9150_Breakout: Example code and PCB design files for the MPU-9105, 9DOF.) combined with a Kalmanfiter.
So far everything worked fine, i got the sensor data to print out via serial and everything worked fine... Until i decided to tidy up the wiring of the robot. After that the IMU did not react to thing anymore. Now either there is no Serial output at all or there is the message I2Cwrite failed. So I re-re-re double checked my wiring but no problems here. As I soldered the jumpers directly to the breakout board I assumed that I maybe damaged the board while soldering.
So i bought a second sensor (Very very annoying almost 50€ in france at a local store...) I got it wired up and everything went back to working until just earlier that day. Only that this time I didn't even touch the robot when the sensor suddently stopped working. The robot fell (as the balancing is not soo stable in the moment) and the sensor stopped working. The robot can't fall on the sensor due to the sensors position and all the cables are still in position. On Sparkfun they say that is shock resistant up to 10'000g so it should not break due to the robot falling over!

I already runned the I2C scanner but it couldn't find anything so I'am asking whats going on here? Any ideas? Is there way to check if the sensor is really dead of if there is another problem which i didn't think of so far?

I attached an image of the robot to get an idea of its size... but anyway to top 10'000g of acceleration it need a bit more than a 20cm high structure falling over...

As the project needs to be finished pretty soon I really appreciate every tipp or help!

Cheers Niko

Ps:

I just verified the voltage at the 3.3V of the Arduino - everythings fine here and resistances between VCC and SCL/SDA are around 10 kOmh.

How long is the cabling between the Arduino and the MPU board? 10k pull-ups to 3V3 might work with maximal 10cm (4"), if your's is more you'll need stronger pull-ups.

BTW: I couldn't find the picture you told to attach.

The cables are all very short maybe 5cm?
Sorry for the Pic, here another try:

Here the first lines of my serialport output after a fresh restart of the arduino:

i2cWcWrite failed: 2
i2cWrite failed: 2
i2cW 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cW 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWi2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2
i2cWrite failed: 2

After that it just goes on with the "i2cWrite failed: 2" message. What does the 2 mean?

I talked to the guys from Sparkfun. They are suspecting that due to the impact there could be a cold joint within the board and that i could try heating the board up with hot air to get the solder flowing... But I'am not so sure if a small impact like the robot falling over could have formed such a cold joint....

Here the first lines of my serialport output after a fresh restart of the arduino:

i2cWcWrite failed: 2
i2cWrite failed: 2
i2cW 2
i2cWrite failed: 2

Post your code. The serial output seems failing too, might be a power problem.

After that it just goes on with the "i2cWrite failed: 2" message. What does the 2 mean?

It means the the I2C device is not answering to requests. This usually is the case if the connection is broken or if a wrong address is used.

I talked to the guys from Sparkfun. They are suspecting that due to the impact there could be a cold joint within the board and that i could try heating the board up with hot air to get the solder flowing... But I'am not so sure if a small impact like the robot falling over could have formed such a cold joint....

The cold joint must have been there before but it may be that the impact broke the little connection it had before. Cold joints often show some connection in the beginning but tend to loose connectivity suddenly. I would try Sparkfun's solution, this is not improbable.

Hi thanks for the advise, I'am going to try to get the sensor under a heat-gun later today! So for the moment I will post my code!

////// --------- GYRO & ACCEL -----------//////

#define RESTRICT_PITCH // Comment out to restrict roll to ±90deg instead - please read: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf

Kalman kalmanX; // Create the Kalman instances

/* IMU Data */
int16_t accX, accY, accZ;
int16_t gyroX, gyroY, gyroZ;
int16_t tempRaw;

float accXangle;//, accYangle; // Angle calculate using the accelerometer
float gyroXangle; // Angle calculate using the gyro only
float kalAngleX; // Calculated angle using a Kalman filter

float CurrentAngle;

uint32_t timer;
uint8_t i2cData[14]; // Buffer for I2C data

////// --------- GYRO & ACCEL - SETUP -----------/////
Wire.begin();
TWBR = ((F_CPU / 400000L) - 16) / 2; // Set I2C frequency to 400kHz

i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling
i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s
i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g
while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once
while (i2cWrite(0x6B, 0x01, true)); // PLL with X axis gyroscope reference and disable sleep mode

while (i2cRead(0x75, i2cData, 1));
if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register
Serial.print(F("Error reading sensor"));
while (1);
}

delay(100); // Wait for sensor to stabilize

/* Set kalman and gyro starting angle */
while (i2cRead(0x3B, i2cData, 6));
accX = (i2cData[0] << 8) | i2cData[1];
accY = (i2cData[2] << 8) | i2cData[3];
accZ = (i2cData[4] << 8) | i2cData[5];

kalmanX.setAngle(accXangle); // Set starting angle
gyroXangle = accXangle;
timer = micros();

////// --------- GYRO & ACCEL- LOOP -----------//////

/* Update all the values */

while(i2cRead(0x3B,i2cData,14));
accX = ((i2cData[0] << 8) | i2cData[1]);
accY = ((i2cData[2] << 8) | i2cData[3]);
accZ = ((i2cData[4] << 8) | i2cData[5]);
tempRaw = ((i2cData[6] << 8) | i2cData[7]);
gyroX = ((i2cData[8] << 8) | i2cData[9]);
gyroY = ((i2cData[10] << 8) | i2cData[11]);
gyroZ = ((i2cData[12] << 8) | i2cData[13]);
accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;
double gyroXrate = (double)gyroX/131.0;
CurrentAngle = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000);
timer = micros();

I hope this could help? do you need anything else? With that I use the I2C Lib by Kristian Lauszus, TKJ Electronics. and the Kalmanfilter Lib by Kristian Lauszus, TKJ Electronics as well, thos i didn't change at all.

PS: I just got another idea:

I have an motor shield mounted on my arduino (SparkFun Monster Moto Shield - DEV-10182 - SparkFun Electronics) which is connected to a 12V power source (3A Max). The shield drives the two Pololu motors. So when the robot fell it didn't stop the motor right away and as they were being blocked there would have been a significant raise of current on the lines of the motor shield. So normally that should be isolated from all the in-and outputs of the arduino but what if that somehow cause a change in tension or current in the system that damaged the sensor?

Please edit your post and insert code tags, I don't think that smileys are usefull inside code :).