MPU6050 setting offsets.. Help..

The Rocketry Forum

Help Support The Rocketry Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

deepfreeze

Well-Known Member
TRF Supporter
Joined
Dec 3, 2022
Messages
55
Reaction score
1
Location
New Jersey, US
Hello guys,
I am trying to use MPU6050 but after all code i did for all the parts, i learned that DMP is not good for rocketry. They say it is maxed out.. I dont know why. Please explain what that means.
Also i saw a simple coding it gives me good values. But some poeple talk about setting gyro offsets and etc.. Could you please explain me why i have to set offsets and what does these mean?

In my code When i get AcX, AcY and AcZ. these doesnt make sense. Isn't it the accelerometer values? Shouldn't those be close to 0 because it is just sitting on the desk?

I am sorry for my stupid questions but everyone is talking middle of the book. Terms are flying around. I dont think it is that hard. But people overcomplicate things a lot for a small sensor.


C:
#include<Wire.h>
 
const int MPU_addr=0x68;
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
 
int minVal=265;
int maxVal=402;
 
double x;
double y;
double z;
 
void setup(){
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(9600);
}
void loop(){
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14,true);
AcX=Wire.read()<<8|Wire.read();
AcY=Wire.read()<<8|Wire.read();
AcZ=Wire.read()<<8|Wire.read();
int xAng = map(AcX,minVal,maxVal,-90,90);
int yAng = map(AcY,minVal,maxVal,-90,90);
int zAng = map(AcZ,minVal,maxVal,-90,90);
 
x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);
 
Serial.print("AngleX= ");
Serial.println(x);
 
Serial.print("AngleY= ");
Serial.println(y);
 
Serial.print("AngleZ= ");
Serial.println(z);
Serial.println("-----------------------------------------");
delay(400);
}
 

Attachments

  • Screenshot from 2022-12-03 01-51-54.png
    Screenshot from 2022-12-03 01-51-54.png
    65.7 KB · Views: 0
Rocketry forum may not be your best source of truth for this specific type of problem, but from the manufacturers product page
"
the parts feature a user-programmable gyro full-scale range of ±250, ±500, ±1000, and ±2000 °/sec (dps), and a user-programmable accelerometer full-scale range of ±2g, ±4g, ±8g, and ±16g
"
so presumably you must initialize the device according to your desired range. And 16G isn't a whole lot.
 
Accelerometers and gyro chips do not read 0 when motionless because there are slight errors due to manufacturing variation, stresses induced during pcb board assembly and temperature drifts. These are all explained in the datasheets. These offsets from 0 are measured in a calibration phase of your program and then substracted from the sensor readings to give the calibrated value.

Your accelerometer should not read zero in the vertical axis when sitting still because the accelerometer in not measuring acceleration in the earth frame (your frame) of reference. It is measuring acceleration in its frame of reference. In that frame the accelerometer would read zero when it is falling.

16g would probably not be enough range for a commercial flight computer but may be perfectly adequate for your projects. Many, many flights do not exceed 16g during boost. You will have to do some sims to determine if this would work for your projects.
 
Last edited:
All good questions but who are "they"?

I use the MPU6050 in a rocket data logger. This is an oldish chip but does work reasonably well and good values can be obtained.

Accelerometer:
When sitting on your desk it does sense the Earth's Gravity so if is flat then the measurement from one axis will equal 1 G or 9.8 m/s/s. The Earth;s Gravity is great for calibration of the accelerometer.

Gyro:
Most chip gyros have an offset that drifts over longish times. So the Offset calibration needs to be done just before the gyro data is needed. For a Quadcopter, the code does this just after power up, for a rocket do this on the pad before launch.
A Gyro output is the Angular Rate of change not any absolute angle. For example, to get how much your rocket spins during the flight the Gyro data must be integrated from degrees/second to degrees. The simple equation is:
New angle = Gyro Rate times the time period from last reading plus old angle.


Instead of me going through all the details read the sensor tutorials on Addfruit's web sire here:
https://www.adafruit.com/category/521
They have great info for the beginner. Dig around there and read.
They also have Good code libraries for many sensors, including the MPU6050, for the Arduino IDE. The libraries are on Github so also good to download and look to see how they handle the sensor setup and reading.

Then don't hesitate to post back here with questions on using the MPU6050 in a rocket.
 
I have used the MPU6050 in my vertical orientation system and I believe Altus Metrum uses them in their products. In these applications, the purpose of the systems is to determine tilt. The accelerometers are used to determine orientation on the pad, but are not used after launch since the rocket is accelerating or decelerating. So, the MPU6050 is not what I would use for the purpose of measuring acceleration, it works pretty well for the pupose of determining orientation during flight.

Jim
 
Hello guys,
I am trying to use MPU6050 but after all code i did for all the parts, i learned that DMP is not good for rocketry. They say it is maxed out.. I dont know why. Please explain what that means.
Also i saw a simple coding it gives me good values. But some poeple talk about setting gyro offsets and etc.. Could you please explain me why i have to set offsets and what does these mean?

In my code When i get AcX, AcY and AcZ. these doesnt make sense. Isn't it the accelerometer values? Shouldn't those be close to 0 because it is just sitting on the desk?

I am sorry for my stupid questions but everyone is talking middle of the book. Terms are flying around. I dont think it is that hard. But people overcomplicate things a lot for a small sensor.


C:
#include<Wire.h>
 
const int MPU_addr=0x68;
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
 
int minVal=265;
int maxVal=402;
 
double x;
double y;
double z;
 
void setup(){
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(9600);
}
void loop(){
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14,true);
AcX=Wire.read()<<8|Wire.read();
AcY=Wire.read()<<8|Wire.read();
AcZ=Wire.read()<<8|Wire.read();
int xAng = map(AcX,minVal,maxVal,-90,90);
int yAng = map(AcY,minVal,maxVal,-90,90);
int zAng = map(AcZ,minVal,maxVal,-90,90);
 
x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);
 
Serial.print("AngleX= ");
Serial.println(x);
 
Serial.print("AngleY= ");
Serial.println(y);
 
Serial.print("AngleZ= ");
Serial.println(z);
Serial.println("-----------------------------------------");
delay(400);
}

Here is the Arduino code I use for my home built Arduino (XIAO MCU) with MPU6050. The acc_x etc. are all int16_t as yours.
I call setup_mpu_6050_registers first and then in the loop I call read_mpu_6050_data. Then I use
accX = ( acc_x - accelBiasX ) / 2048 ; Here accX is float and accelbiasX is const long.
By looking at the acc_x it gives me an idea what the "average" value is when the unit is vertical.
I use this value to set accelBiasX, sometimes the accX is already showing 1G so accelbiasX would be zero, this is calibration step.
If it is showing more than 1G you need to set accelbiasX, for instance if it shows 1.5G you need to set accelbiasX = 0.5*2048 so that accX shows 1G.

//Subroutine for reading the raw gyro and accelerometer data from MPU-6050
void read_mpu_6050_data(){
//Start communicating with the MPU-6050
Wire.beginTransmission(0x68);
//Send the requested starting register
Wire.write(0x3B);
//End the transmission
Wire.endTransmission();
//Request 14 bytes from the MPU-6050
Wire.requestFrom(0x68,14);
//Wait until all the bytes are received
while(Wire.available() < 14);
//Add the low and high byte to the acc_x variable
acc_x = Wire.read()<<8|Wire.read();
//Add the low and high byte to the acc_y variable
acc_y = Wire.read()<<8|Wire.read();
//Add the low and high byte to the acc_z variable
acc_z = Wire.read()<<8|Wire.read();
//Add the low and high byte to the temperature variable
temp0 = Wire.read()<<8|Wire.read();
//Add the low and high byte to the gyro_x variable
gyro_x = Wire.read()<<8|Wire.read();
//Add the low and high byte to the gyro_y variable
gyro_y = Wire.read()<<8|Wire.read();
//Add the low and high byte to the gyro_z variable
gyro_z = Wire.read()<<8|Wire.read();
}

void setup_mpu_6050_registers(){
//Activate the MPU-6050
//Start communicating with the MPU-6050
Wire.beginTransmission(0x68);
//Send the requested starting register
Wire.write(0x6B);
//Set no to sleep mode and measure
Wire.write(0x00);
//End the transmission
Wire.endTransmission();
Wire.beginTransmission(0x68);
//Send the requested starting register in hexadecimal
Wire.write(0x1C);
//Setting the accel to +/- 16g on page 15 in binary
Wire.write(0b00011000);
//Configure the accelerometer (+/-8g) in decimal
//Wire.write(0x10);
Wire.endTransmission();
Wire.beginTransmission(0x68);
//Send the requested starting register in hexadecimal
Wire.write(0x1B);
//Setting the gyro to full scale +/- 2000deg./s
Wire.write(0b00011000);
//Configure the gyro 500dps full scale in decimal
//Wire.write(0x08);
Wire.endTransmission();
}
 
Back
Top