SOLVED: Arduino Due Issues with MPU-6050

Hello everyone!

This is my first time posting here, so please let me know if I can format this question better.

I recently decided to upgrade from an Arduino Uno to a Due in order to better meet the demands of some of my more complicated projects. I just got my Due in the mail yesterday, eagerly downloaded the associated board drives, and uploaded some preexisting code of mine to read angular rates from an MPU-6050. Although I was very excited to try my new board, I became a little disheartened and confused by the data being displayed on the serial port/display.

Before I continue, I’d like to stress that the code in question (posted below) has worked in the past and continue to produce reasonable results when uploaded to my Uno.

After uploading my code, I turned the MPU-6050 sensor by hand clockwise and got a reasonable angular rate of 20 deg/sec displayed over the serial comms window. Unfortunately, when I turned the senor counterclockwise, the serial display was spitting out a rotation rate of in excess of 400 deg/sec. I was only eyeing the motion, but I can confidently say that the clockwise and counterclockwise rates were approximately equal in magnitude.

Besides the excessively high angular rate readouts, I noticed a couple other anomalies that are fishy. First off, although I rotated the MPU-6050 both clockwise and counterclockwise, the polarity of the gyro’s rate readouts never changed; both CW and CCW motion had “positive” motion. In fact, any CCW motion results in a gyro readout of over 400 deg/sec. Additionally, my MPU-6050 is operating with default factory settings. Specifically, the gyro range is limited to +/-250 deg/sec. I’m unsure how I’m getting gyro rates in excess of the sensor’s range.

I’m pretty confident that my sensor is fine. I’ve tried running the same code and sensor on my Uno and get reasonable results. I’m pretty sure the fault lies somewhere in how I’m reading data over I2C, but have no idea what the error is nor how to fix it.

As for wiring, it a pretty simple setup:

VCC–>3.3V

GND–>GND

SCL–> Pin 21

SDA–>Pin 20

I’m operating on version 1.8.9 of the IDE and downloaded the 1.6.12 version of the Arduino SAM Board driver.

Code is below:

#include <Wire.h>
int INS = 0x68; // MPU6050 I2C address
float Gyro_X, Gyro_Y, Gyro_Z;

void setup() {
  Serial.begin(9600);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(INS);       // Start communication with MPU6050 // INS=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0);                     // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        // End the transmission

}
void loop() {  
  
  // Write to INS Requesting Gyroscope Data
  Wire.beginTransmission(INS);
  Wire.write(0x43); // 
  Wire.endTransmission();
  Wire.requestFrom(INS, 6, true); 

  // Read Gyroscope Data and Convert to Physical Units (DPS)
  Gyro_X= (Wire.read() << 8 | Wire.read())/131.0;
  Gyro_Y = (Wire.read() << 8 | Wire.read())/131.0;
  Gyro_Z = (Wire.read() << 8 | Wire.read())/131.0;

  // Print the values on the serial monitor
  Serial.print(Gyro_X);
  Serial.print("  ");
  Serial.print(Gyro_Y);
  Serial.print("  ");
  Serial.println(Gyro_Z);

  delay(100);
}

I posted over in the arduino subreddit, but to no avail. (https://www.reddit.com/r/arduino/comments/h0p0zc/help_with_arduino_due_and_mpu6050/)

If anyone has insight, it would be greatly appreciated. I’ve been scratching my head on this for the past few days.

Does your system include pullup resistors on the SDA & SCL lines?

Thanks for the quick reply!

I have not included any "external" pull-up resistors in this setup. From my understanding, the MPU-6050 has built-in pull-up resistors, nullifying the need to place additional ones in the circuit.

In the past, I have not needed to place additional resistors in the Uno-MPU6050 circuit.

I'm willing to give it a try though! Just to confirm, I should place 4.7k ohm resistors between the SDA/SCL lines to 3.3V, right?

3.3K or 2.7K would be better in a 3.3V system.
Have not used either of your components myself.

HEY, ALRIGHT!

So I think the I solved the problem with help from my fellow engineering friend.

I initialized the “Gyro_{X,Y,Z}” variables as type “int16_t” as compared to “float”. The “Gyro_{X,Y,Z}” variables were only utilized to read and combine the raw data from the MPU-6050.

I then used float variables “P,Q,R” to translate the raw data to physical units in DPS by dividing “Gyro_{X,Y,Z}” by 131.0.

This seems to be working, at least from a qualitative viewpoint. I’m not quite sure why this method provides different results; any insight?

Code below:

#include <Wire.h>
int INS = 0x68; // MPU6050 I2C address
int16_t Gyro_X, Gyro_Y, Gyro_Z;
float P, Q, R;

void setup() {
  Serial.begin(9600);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(INS);       // Start communication with MPU6050 // INS=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0);                     // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        // End the transmission

}
void loop() {  
  
  // Write to INS Requesting Gyroscope Data
  Wire.beginTransmission(INS);
  Wire.write(0x43); // 
  Wire.endTransmission();
  Wire.requestFrom(INS, 6, true); 

  // Read Gyroscope Data and Convert to Physical Units (DPS)
  Gyro_X= (Wire.read() << 8 | Wire.read());
  Gyro_Y = (Wire.read() << 8 | Wire.read());
  Gyro_Z = (Wire.read() << 8 | Wire.read());

  Q=Gyro_X/131.0;
  P=Gyro_Y/131.0;
  R=Gyro_X/131.0;

  // Print the values on the serial monitor
  Serial.print(P);
  Serial.print("  ");
  Serial.print(Q);
  Serial.print("  ");
  Serial.println(R);

  delay(100);
}