MPU6050 I2c Serial crashes/freezes whenever motor turns on

Hi everybody,

I'm building myself a balancing robot using these components:

  1. MPU6050 IMU breakboard by Sparkfun (libraries provided by Jeff Rowberg)
  2. Tamiya Motor DC with differential gearbox
  3. Arduino Mega
  4. A TTL motor driver board with L298N chip

Using the MPU6050 library, I was able to get Euler angles data from the IMU with no problem whatsoever. However, whenever I connected the motor, it will freeze. And the by freezing, I mean the code just executes the last line and stays that way. I had to either press the reset button on the Arduino or plug off the power supply of the board.

The code in loop function I used to control the motor:

output= map(abs(euler[1]*180/M_PI),0,50,0,255);
    //forward direction if the tilt angle is positive
    if ((euler[1]*180/M_PI)>0) {
      digitalWrite(motor1Pin1, LOW);   
      digitalWrite(motor1Pin2, HIGH);  
      analogWrite(enablePin1,output); //PWM, the motor goes faster if the IMU is tilted more
    } 
    //reverse direction if the tilt angle is negative
    else if ((euler[1]*180/M_PI)<0) {
      digitalWrite(motor1Pin1, HIGH);   
      digitalWrite(motor1Pin2, LOW);  
      analogWrite(enablePin1,output); //PWM, the motor goes faster if the IMU is tilted more
    }
    else {
      digitalWrite(motor1Pin1, LOW);  
      digitalWrite(motor1Pin2, LOW);   
      digitalWrite(enablePin1, LOW);
    }

At first, I thought maybe there's something wrong with my code. And so, I simplified it even more by turning on the motor with constant voltage and just reading the angle data (so, no correlation between the tilt angle with the motor). The code in the loop function:

mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetEuler(euler, &q);
            Serial.print("euler\t");
            Serial.print(euler[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(euler[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(euler[2] * 180/M_PI);

           digitalWrite(motor1Pin1, HIGH);
           digitalWrite(motor1Pin2, LOW);
           digitalWrite(enablePin1, HIGH);

After just one or two seconds, it freezes.

To make sure that this really is a problem whenever the motor is connected, I used the same code but this time, I used it to control the brightness of an LED. The code:

output= abs((euler[1] * 180/M_PI));
      analogWrite(LED_PIN,(output); // the brightness of the LED will increase if the tilt angle increases

This works perfectly for hours-- no freezing, no crashes, everything was fine. And this serves as proof that my code is okay and the IMU is also okay. So I'm guessing there's a problem with the Arduino's i2c or serial?

Things I've tried that didn't solve the problem:

  1. Turning off the internal pull-up resistor activated by the Wire library and use 4k7 external pull-up resistors instead.
  2. Using a smaller external pull-up resistor (2k2 Ohms).
  3. Decoupling by putting ceramic capacitor on the VCC and GND of the IMU and motor.
  4. Using different baud rates from 115200 to 9600
  5. Tried using a different IMU: Digital combo board (ITG3200 & ADXL345) from Sparkfun
  6. I've also tried separating all the power supply (before I powered everything from the arduino).
  7. Tried not using the serial monitor, instead just executes the code once the board is powered.

Any help on this would be greatly appreciated. I've been dealing with this problem for weeks now, and I've also searched on numerous forums regarding this problem but to no avail.

If anything is not clear enough, don't hesitate to ask me.

Thank you in advance. :slight_smile:

How have you wired the power supply? I'd guess that the motor is using too much current and the voltage drops under the limit for the Arduino.

I use the same IMU and motor driver. The dc motors induce a lot of noise. Did you solve the problem? Because i can't get it working too.

I had the same problem using a motor with the MPU6050 the reason is the motor causes interference, the way to make it work is to use a level shift from the 5v I2C of the arduino to the 3.3v I2C of the mpu6050.
the level shift circuit I used is this one, it uses 4 transistors and 6 resistors.

Jon90:
I had the same problem using a motor with the MPU6050 the reason is the motor causes interference, the way to make it work is to use a level shift from the 5v I2C of the arduino to the 3.3v I2C of the mpu6050.
the level shift circuit I used is this one, it uses 4 transistors and 6 resistors.
Arduino Playground - HomePage

Hey Jon,

I have the same issue so i used the circuit in the picture. However, if i use 10k resistors from the base of the bjts the mpu6050 does not srespond at all. I had to go down all the way to 2.2k in order to get any response. Even then, i still get freezing (though it goes a bit longer before it freezes)
Would you have any more advice?

Thank you,
Denis
Denis

I was having similar issues using this setup for a two-wheeled balancing bot:

  • MPU6050 on a GY-521
  • Arduino Uno
    -R3 motorshield driving two roomba motors
    -9.6 V battery

The freezing was really intermittent, and for some reason always occurred at only extreme tilt angles (and only in one direction!). I assume this was related to the motor power and direction being proportional to angle.

Anyway, I mostly resolved the issue by pulling up the SCL and SDA with 2.2 k resistors. This was pretty surprising as I didn't think this was necessary with the GY-521. I really doubted it was a power issue, and even tried using a DC-DC converter directly from the battery to make sure:

I guess it could be related to noise from the motors. It would never hang without power to the motors...

That being said, the 2.2k pull-up seems to work up to the most extreme cases (inversion). It would be sweet if this could get completely solved though, kinda feels like a band-aid... Robot just balanced for a solid hour without freezing or falling over though!

How do you connect the 2 pull up resistors to SCL and SDA? I'm having massive problems on wiring the mpu with a dc motor.

Jon90:
I had the same problem using a motor with the MPU6050 the reason is the motor causes interference, the way to make it work is to use a level shift from the 5v I2C of the arduino to the 3.3v I2C of the mpu6050.
the level shift circuit I used is this one, it uses 4 transistors and 6 resistors.
Arduino Playground - HomePage

This is quite an old topic, but the problems is still out there....
It's worth noting that the datasheet for the mpu6050 says that max input volts on the sda and scl is vcc+0.5v. The mpu6050 is being powered from 5V thru a 3.3V regulator, so that's OK, but if you are running this from a 5V arduino using pullups on the arduino board to 5v and pullups on the mpu board up to 3.3v, there's a chance that you'll exceed these limits. It 'might' be OK, but it seems dodgy to me. So, the use of the level-shifters, though a pain in the proverbial, might be a good idea.

I'll point out that I have exactly the same issue as others on this topic with the i2c apparently freezing when the motors come on to any large degree, even though (or maybe because) I am using the MotoProto shield and it has 3.3V level shifters on its i2c header.