Some MPU6050 modules have a 5V regulator and will not run on 3.3V, due to the regulator dropout voltage. If that is the case, you will need to remove the regulator and/or bypass the connection to it.
The result when I print average on Serial Monitor:
#include <Wire.h>
int samples = 2000;
int temperature=0;
// Gyro Variables
float Gyr_rawX, Gyr_rawY, Gyr_rawZ; //Here we store the raw data read
float Gyro_angle_x, Gyro_angle_y; //Here we store the angle value obtained with Gyro data
float Gyro_raw_error_x, Gyro_raw_error_y; //Here we store the initial gyro data error
//Acc Variables
float rad_to_deg = 180/3.141592654; //This value is for pasing from radians to degrees values
float Acc_rawX, Acc_rawY, Acc_rawZ; //Here we store the raw data read
float Acc_angle_x, Acc_angle_y; //Here we store the angle value obtained with Acc data
float Acc_angle_error_x, Acc_angle_error_y; //Here we store the initial Acc data error
void setup()
{
Serial.begin(115200); // baudrate 115200 bits per second
Serial.println("Init");
Wire.setClock(400000l); //increases I2C frequency to 400kHz
Wire.begin(); //begin the wire comunication
Wire.beginTransmission(0x68); //begin, Send the slave adress (in this case 68)
Wire.write(0x6B); //make the reset (place a 0 into the 6B register)
Wire.write(0x00);
Wire.endTransmission(true); //end the transmission
//Gyro config
Wire.beginTransmission(0x68); //begin, Send the slave adress (in this case 68)
Wire.write(0x1B); //We want to write to the GYRO_CONFIG register (1B hex)
Wire.write(0x10); //Set the register bits as 00010000 (1000dps full scale)
Wire.endTransmission(true); //End the transmission with the gyro
//Acc config
Wire.beginTransmission(0x68); //Start communication with the address found during search.
Wire.write(0x1C); //We want to write to the ACCEL_CONFIG register
Wire.write(0x10); //Set the register bits as 00010000 (+/- 8g full scale range)
Wire.endTransmission(true);
Wire.beginTransmission(0x68);
Wire.write(0x1A); // the config address
Wire.write(0x06); // the config value
Wire.endTransmission(true);
for(int j=0; j<=samples; j++)
{
Wire.beginTransmission(0x68);
Wire.write(0x3B); //Ask for the 0x3B register- correspond to AcX
Wire.endTransmission(false);
Wire.requestFrom(0x68,12,1);
Acc_rawX=(Wire.read()<<8|Wire.read())/4096.0 ; //each value needs two registres
Acc_rawY=(Wire.read()<<8|Wire.read())/4096.0 ;
Acc_rawZ=(Wire.read()<<8|Wire.read())/4096.0 ;
temperature=Wire.read()<<8|Wire.read();
Gyr_rawX=Wire.read()<<8|Wire.read(); //Once again we shif and sum
Gyr_rawY=Wire.read()<<8|Wire.read();
// Sum
Acc_angle_error_x = Acc_angle_error_x + ((atan((Acc_rawY)/sqrt(pow((Acc_rawX),2) + pow((Acc_rawZ),2)))*rad_to_deg));
Acc_angle_error_y = Acc_angle_error_y + ((atan(-1*(Acc_rawX)/sqrt(pow((Acc_rawY),2) + pow((Acc_rawZ),2)))*rad_to_deg));
Gyro_raw_error_x = Gyro_raw_error_x + (Gyr_rawX/32.8);
Gyro_raw_error_y = Gyro_raw_error_y + (Gyr_rawY/32.8);
}
// Average
Acc_angle_error_x = Acc_angle_error_x/samples;
Acc_angle_error_y = Acc_angle_error_y/samples;
Gyro_raw_error_x = Gyro_raw_error_x/samples;
Gyro_raw_error_y = Gyro_raw_error_y/samples;
// Debugger
Serial.print("Acc_angle_error_x: ");
Serial.println(Acc_angle_error_x);
Serial.print("Acc_angle_error_y: ");
Serial.println(Acc_angle_error_y);
Serial.print("Gyro_raw_error_x: ");
Serial.println(Gyro_raw_error_x);
Serial.print("Gyro_raw_error_y: ");
Serial.println(Gyro_raw_error_y);
}//end of setup void
void loop()
{
}
I personally think it is a bad idea to leave the initialization of variables up to the compiler and linker. Try setting all these to zero before using them as accumulators.
float Gyro_raw_error_x, Gyro_raw_error_y; //Here we store the initial gyro data error
Makes sense. I initialized the variables…but not sucess yet.
I tried double type instead float, but also not sucess.
#include <Wire.h>
int samples = 2000;
int temperature=0;
// Gyro Variables
float Gyr_rawX=0;
float Gyr_rawY=0;
float Gyr_rawZ=0; //Here we store the raw data read
float Gyro_angle_x=0;
float Gyro_angle_y=0; //Here we store the angle value obtained with Gyro data
float Gyro_raw_error_x=0;
float Gyro_raw_error_y=0; //Here we store the initial gyro data error
//Acc Variables
float rad_to_deg = 180/3.141592654; //This value is for pasing from radians to degrees values
float Acc_rawX=0;
float Acc_rawY=0;
float Acc_rawZ=0; //Here we store the raw data read
float Acc_angle_x=0;
float Acc_angle_y=0; //Here we store the angle value obtained with Acc data
float Acc_angle_error_x=0;
float Acc_angle_error_y=0; //Here we store the initial Acc data error
void setup()
{
Serial.begin(115200); // baudrate 115200 bits per second
Serial.println("Init");
Wire.setClock(400000l); //increases I2C frequency to 400kHz
Wire.begin(); //begin the wire comunication
Wire.beginTransmission(0x68); //begin, Send the slave adress (in this case 68)
Wire.write(0x6B); //make the reset (place a 0 into the 6B register)
Wire.write(0x00);
Wire.endTransmission(true); //end the transmission
//Gyro config
Wire.beginTransmission(0x68); //begin, Send the slave adress (in this case 68)
Wire.write(0x1B); //We want to write to the GYRO_CONFIG register (1B hex)
Wire.write(0x10); //Set the register bits as 00010000 (1000dps full scale)
Wire.endTransmission(true); //End the transmission with the gyro
//Acc config
Wire.beginTransmission(0x68); //Start communication with the address found during search.
Wire.write(0x1C); //We want to write to the ACCEL_CONFIG register
Wire.write(0x10); //Set the register bits as 00010000 (+/- 8g full scale range)
Wire.endTransmission(true);
Wire.beginTransmission(0x68);
Wire.write(0x1A); // the config address
Wire.write(0x06); // the config value
Wire.endTransmission(true);
for(int j=0; j<=samples; j++)
{
Wire.beginTransmission(0x68);
Wire.write(0x3B); //Ask for the 0x3B register- correspond to AcX
Wire.endTransmission(false);
Wire.requestFrom(0x68,12,1);
Acc_rawX=(Wire.read()<<8|Wire.read())/4096.0 ; //each value needs two registres
Acc_rawY=(Wire.read()<<8|Wire.read())/4096.0 ;
Acc_rawZ=(Wire.read()<<8|Wire.read())/4096.0 ;
temperature=Wire.read()<<8|Wire.read();
Gyr_rawX=Wire.read()<<8|Wire.read(); //Once again we shif and sum
Gyr_rawY=Wire.read()<<8|Wire.read();
// Sum
Acc_angle_error_x = Acc_angle_error_x + ((atan((Acc_rawY)/sqrt(pow((Acc_rawX),2) + pow((Acc_rawZ),2)))*rad_to_deg));
Acc_angle_error_y = Acc_angle_error_y + ((atan(-1*(Acc_rawX)/sqrt(pow((Acc_rawY),2) + pow((Acc_rawZ),2)))*rad_to_deg));
Gyro_raw_error_x = Gyro_raw_error_x + (Gyr_rawX/32.8);
Gyro_raw_error_y = Gyro_raw_error_y + (Gyr_rawY/32.8);
}
// Average
Acc_angle_error_x = Acc_angle_error_x/samples;
Acc_angle_error_y = Acc_angle_error_y/samples;
Gyro_raw_error_x = Gyro_raw_error_x/samples;
Gyro_raw_error_y = Gyro_raw_error_y/samples;
// Debugger
Serial.print("Acc_angle_error_x: ");
Serial.println(Acc_angle_error_x);
Serial.print("Acc_angle_error_y: ");
Serial.println(Acc_angle_error_y);
Serial.print("Gyro_raw_error_x: ");
Serial.println(Gyro_raw_error_x);
Serial.print("Gyro_raw_error_y: ");
Serial.println(Gyro_raw_error_y);
}//end of setup void
void loop()
{
}
Except to suggest that you compare the raw data coming out of the X and Y gyro axes during calibration, for each host processor, I’m out of ideas. Strange problem, that it seems to affect only one axis!
Coming back to this, though, if the 3.3V voltage on the Due is even slightly lower than on the Mega, that could make a critical difference. If the module has a regulator, try powering it with 5V while connected to the Due (separate power supply, grounds connected of course).
So I think the problem is not voltage because I used 3V3 and Arduino Mega it works, but on Due The result is different.
if I powering module 5V it can damage I2C pins of Due, or not
It should not. The regulator functions to supply 3.3V power to the MPU6050.
As I indicated before, if the regulator is powered by 3.3V input, the voltage applied to the MPU6050 will be too low for for proper operation.
It is best to remove the regulator if you are using the module with the Due. I use a solder pencil to "swipe" them off.
If you really want to solve this problem, use a MUCH better IMU module, like this one, which is designed to operate properly on any voltage between 2.5 and 5.0.
Print the raw values, that way you can be certain whether the problem is with the data you're getting from the MPU6050.
If they are the same, then the math would be behaving differently, and you could write a sketch with constant values, and get different results - then pull intermediate calculations out and print the results until you found which operation was giving different results.
This is weird - if the MPU6050 is not giving the same values for the X axis, it is strange indeed that it is giving the same values for the other axes, this seems unlikely. But so does getting different results for mathematical operations, even all those trig functions - floats are different size on the due vs mega, but that alone doesn't explain this, and I think we would know if one of the math functions was straight up broken. Neither possible explanation seems particularly plausible - but instead of trying to fix problems with the the voltage supplied to the MPU6050, we should perform the simple test of confirming that we are indeed getting a different value back from it, and see what exactly that different value is!
Makes sense. I did as you said using bitwise operator.
You rock, you’re a master of the bit. It works very well !!! Thank you so much.
Final code below.
#include <Wire.h>
int samples = 2000;
long temperature=0;
// Gyro Variables
float Gyr_rawX=0;
int16_t Gyr_rawX_L=0;
int16_t Gyr_rawX_H=0;
float Gyr_rawY=0;
int16_t Gyr_rawY_L=0;
int16_t Gyr_rawY_H=0;
int16_t Gyr_rawZ=0; //Here we store the raw data read
float Gyro_angle_x=0;
float Gyro_angle_y=0; //Here we store the angle value obtained with Gyro data
float Gyro_raw_error_x=0;
float Gyro_raw_error_y=0; //Here we store the initial gyro data error
//Acc Variables
float rad_to_deg = 180/3.141592654; //This value is for pasing from radians to degrees values
float Acc_rawX=0;
float Acc_rawY=0;
float Acc_rawZ=0; //Here we store the raw data read
float Acc_angle_x=0;
float Acc_angle_y=0; //Here we store the angle value obtained with Acc data
float Acc_angle_error_x=0;
float Acc_angle_error_y=0; //Here we store the initial Acc data error
void setup()
{
Serial.begin(115200); // baudrate 115200 bits per second
Serial.println("Init");
Wire.setClock(400000l); //increases I2C frequency to 400kHz
Wire.begin(); //begin the wire comunication
Wire.beginTransmission(0x68); //begin, Send the slave adress (in this case 68)
Wire.write(0x6B); //make the reset (place a 0 into the 6B register)
Wire.write(0x00);
Wire.endTransmission(true); //end the transmission
//Gyro config
Wire.beginTransmission(0x68); //begin, Send the slave adress (in this case 68)
Wire.write(0x1B); //We want to write to the GYRO_CONFIG register (1B hex)
Wire.write(0x10); //Set the register bits as 00010000 (1000dps full scale)
Wire.endTransmission(true); //End the transmission with the gyro
//Acc config
Wire.beginTransmission(0x68); //Start communication with the address found during search.
Wire.write(0x1C); //We want to write to the ACCEL_CONFIG register
Wire.write(0x10); //Set the register bits as 00010000 (+/- 8g full scale range)
Wire.endTransmission(true);
Wire.beginTransmission(0x68);
Wire.write(0x1A); // the config address
Wire.write(0x06); // the config value
Wire.endTransmission(true);
for(int j=0; j<=samples; j++)
{
Wire.beginTransmission(0x68);
Wire.write(0x3B); //Ask for the 0x3B register- correspond to AcX
Wire.endTransmission(false);
Wire.requestFrom(0x68,12,1);
Acc_rawX=(Wire.read()<<8|Wire.read())/4096.0 ;
Acc_rawY=(Wire.read()<<8|Wire.read())/4096.0 ;
Acc_rawZ=(Wire.read()<<8|Wire.read())/4096.0 ;
temperature=Wire.read()<<8|Wire.read();
Gyr_rawX_L=Wire.read()<<8; //Once again we shif and sum
Gyr_rawX_H=Wire.read();
Gyr_rawX = Gyr_rawX_H | Gyr_rawX_L;
Gyr_rawY_L=Wire.read()<<8;
Gyr_rawY_H=Wire.read();
Gyr_rawY = Gyr_rawY_H | Gyr_rawY_L;
// Sum
Acc_angle_error_x = (double) Acc_angle_error_x + ((atan((Acc_rawY)/sqrt(pow((Acc_rawX),2) + pow((Acc_rawZ),2)))*rad_to_deg));
Acc_angle_error_y = (double) Acc_angle_error_y + ((atan(-1*(Acc_rawX)/sqrt(pow((Acc_rawY),2) + pow((Acc_rawZ),2)))*rad_to_deg));
Gyro_raw_error_x = (double) Gyro_raw_error_x + (Gyr_rawX/32.8);
Gyro_raw_error_y = (double) Gyro_raw_error_y + (Gyr_rawY/32.8);
}
// Average
Acc_angle_error_x = (double) Acc_angle_error_x/samples;
Acc_angle_error_y = (double) Acc_angle_error_y/samples;
Gyro_raw_error_x = (double) Gyro_raw_error_x/samples;
Gyro_raw_error_y = (double) Gyro_raw_error_y/samples;
// Debugger
Serial.print("Acc_angle_error_x: ");
Serial.println(Acc_angle_error_x);
Serial.print("Acc_angle_error_y: ");
Serial.println(Acc_angle_error_y);
Serial.print("Gyro_raw_error_x: ");
Serial.println(Gyro_raw_error_x);
Serial.print("Gyro_raw_error_y: ");
Serial.println(Gyro_raw_error_y);
}//end of setup void
void loop()
{
}