Mpu6050 initial value

I am using mpu6050 with arduino uno and oled

/* Get tilt angles on X and Y, and rotation angle on Z
 * Angles are given in degrees, displays on SSD1306 OLED
 * 
 * License: MIT
 */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050_light.h>
 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
 
 
MPU6050 mpu(Wire);
unsigned long timer = 0;
 
void setup() {
  Serial.begin(115200);                           // Ensure serial monitor set to this value also    
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))  // Address 0x3C for most of these displays, if doesn't work try 0x3D 
  { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);                                      // Don't proceed, loop forever
  } 
  display.setTextSize(1);             
  display.setTextColor(SSD1306_WHITE);            // Draw white text
  display.clearDisplay();                         
  Wire.begin();
  mpu.begin();
  display.println(F("Calculating gyro offset, do not move MPU6050"));
  display.display();        
  mpu.calcGyroOffsets();                          // This does the calibration
  display.setTextSize(2);          
}
 
void loop() {
  mpu.update();  
  if((millis()-timer)>10)                         // print data every 10ms
  {                                           
    display.clearDisplay();                       // clear screen
    display.setCursor(0,0);                         
    display.print("P : ");
    display.println((int)mpu.getAngleX());
    display.print("R : ");
    display.println((int)mpu.getAngleY());
    display.print("Y : ");
    display.print((int)mpu.getAngleZ());
    display.display();                            // display data
    timer = millis();  
  }
}

The mpu6050 working great and i can measure pitch , roll and yaw value with no problem

But it shows the angles according to the gavity

I want it shows the zero angles at startup. So, regardless of the initial orientation of the MPU6050, the angles are zero. Moving it updates the angles relative to the initial orientation not gravity orientation

How to show the initial angles at startup zero then update the angles relative to the initial angles regardless the gravity orientation?

Means if i started it while i am holding it with 90° on the floor, the initial degree show is zero not 90°

Record the (x, y, z) components of the gravity vector on startup (R0) and calculate the tilt angle from vertical using the vector dot product of that with subsequent measurements (R).

If you normalize both vectors so |R| = |R0| = 1, then

cos(tilt_angle) = R dot R0

Calculating Euler angles with respect to X and Y is more complicated.

how this will be done do you have a code or demonstration

i tried this on the x angle, it compiled and uploaded successfully but not working gives 0 only

/* Get tilt angles on X and Y, and rotation angle on Z
 * Angles are given in degrees, displays on SSD1306 OLED
 * 
 * License: MIT
 */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050_light.h>
 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

 
MPU6050 mpu(Wire);
unsigned long timer = 0;

int initialReading;
int getAngleX;

void setup() {
  Serial.begin(115200);                           // Ensure serial monitor set to this value also    
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))  // Address 0x3C for most of these displays, if doesn't work try 0x3D 
  { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);                                      // Don't proceed, loop forever
  
  initialReading = getAngleX;

  } 
  display.setTextSize(1);             
  display.setTextColor(SSD1306_WHITE);            // Draw white text
  display.clearDisplay();                         
  Wire.begin();
  mpu.begin();
  display.println(F("Calculating gyro offset, do not move MPU6050"));
  display.display();        
  mpu.calcGyroOffsets();                          // This does the calibration
  display.setTextSize(2);          
}
 
void loop() {

     int reading = getAngleX;
     int relative = reading - initialReading;

  mpu.update();  
  if((millis()-timer)>10)                         // print data every 10ms
  {                                           
    display.clearDisplay();                       // clear screen
    display.setCursor(0,0);                         
    display.print("P : ");
    display.println(relative);
    display.print("R : ");
    display.println((int)mpu.getAngleY());
    display.print("Y : ");
    display.print((int)mpu.getAngleZ());
    display.display();                            // display data
    timer = millis();  
  }
}

This is the simplest approach to measure pitch and roll values using the MPU-6050 (or other accelerometer):

// minimal MPU-6050 tilt and roll (sjr). Works with MPU-9250 too.
// works perfectly with GY-521, pitch and roll signs agree with arrows on sensor module 7/2019
//
// Tested with 3.3V eBay Pro Mini with no external pullups on I2C bus (worked with internal pullups)
// Add 4.7K pullup resistors to 3.3V if required. A4 = SDA, A5 = SCL

#include<Wire.h>
const int MPU_addr1 = 0x68;
float xa, ya, za, roll, pitch;

void setup() {

  Wire.begin();                                      //begin the wire communication
  Wire.beginTransmission(MPU_addr1);                 //begin, send the slave adress (in this case 68)
  Wire.write(0x6B);                                  //make the reset (place a 0 into the 6B register)
  Wire.write(0);
  Wire.endTransmission(true);                        //end the transmission
  Serial.begin(9600);
}

void loop() {

  Wire.beginTransmission(MPU_addr1);
  Wire.write(0x3B);  //send starting register address, accelerometer high byte
  Wire.endTransmission(false); //restart for read
  Wire.requestFrom(MPU_addr1, 6); //get six bytes accelerometer data
  int t = Wire.read();
  xa = (t << 8) | Wire.read();
  t = Wire.read();
  ya = (t << 8) | Wire.read();
  t = Wire.read();
  za = (t << 8) | Wire.read();
// formula from https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing
  roll = atan2(ya , za) * 180.0 / PI;
  pitch = atan2(-xa , sqrt(ya * ya + za * za)) * 180.0 / PI; //account for roll already applied

  Serial.print("roll = ");
  Serial.print(roll,1);
  Serial.print(", pitch = ");
  Serial.println(pitch,1);
  delay(400);
}

i am a beginner in c++, all my previous working with python so there are some confusion for me

/* Get tilt angles on X and Y, and rotation angle on Z
 * Angles are given in degrees, displays on SSD1306 OLED
 * 
 * License: MIT
 */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050_light.h>
 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

 
MPU6050 mpu(Wire);
unsigned long timer = 0;

int initialReading;

void setup() {
  Serial.begin(115200);                           // Ensure serial monitor set to this value also    
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))  // Address 0x3C for most of these displays, if doesn't work try 0x3D 
  { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);                                      // Don't proceed, loop forever
  
  initialReading = mpu.getAngleX();

  } 
  display.setTextSize(1);             
  display.setTextColor(SSD1306_WHITE);            // Draw white text
  display.clearDisplay();                         
  Wire.begin();
  mpu.begin();
  display.println(F("Calculating gyro offset, do not move MPU6050"));
  display.display();        
  mpu.calcGyroOffsets();                          // This does the calibration
  display.setTextSize(2);          
}
 
void loop() {

     int reading = mpu.getAngleX();
     int relative = reading - initialReading;

  mpu.update();  
  if((millis()-timer)>10)                         // print data every 10ms
  {                                           
    display.clearDisplay();                       // clear screen
    display.setCursor(0,0);                         
    display.print("P : ");
    display.println((int)relative);
    display.print("R : ");
    display.println((int)mpu.getAngleY());
    display.print("Y : ");
    display.print((int)mpu.getAngleZ());
    display.display();                            // display data
    timer = millis();  
  }
}

i edit it but now giving the value according to the gravity again

thanks for helping but this measure angles to the gravity !

is not initialReading is the same as mpu.getAngleX, means will gives the angle according to the gavity?

See post #3, which answered your original question.

1 Like

you mean print it here like this?

/* Get tilt angles on X and Y, and rotation angle on Z
 * Angles are given in degrees, displays on SSD1306 OLED
 * 
 * License: MIT
 */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050_light.h>
 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

 
MPU6050 mpu(Wire);
unsigned long timer = 0;

int initialReading;

void setup() {
  Serial.begin(115200);                           // Ensure serial monitor set to this value also    
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))  // Address 0x3C for most of these displays, if doesn't work try 0x3D 
  { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);                                      // Don't proceed, loop forever
  
  initialReading = mpu.getAngleX();

  } 
  display.setTextSize(1);             
  display.setTextColor(SSD1306_WHITE);            // Draw white text
  display.clearDisplay();                         
  Wire.begin();
  mpu.begin();
  display.println(F("Calculating gyro offset, do not move MPU6050"));
  display.display();        
  mpu.calcGyroOffsets();                          // This does the calibration
  display.setTextSize(2);          
}
 
void loop() {

     int reading = mpu.getAngleX();
     int relative = reading - initialReading;

  mpu.update();  
  if((millis()-timer)>10)                         // print data every 10ms
  {                                           
    display.clearDisplay();                       // clear screen
    display.setCursor(0,0);                         
    display.print("P : ");
    display.println(initialReading);
    display.print("R : ");
    display.println((int)mpu.getAngleY());
    display.print("Y : ");
    display.print((int)mpu.getAngleZ());
    display.display();                            // display data
    timer = millis();  
  }
}

can you simplify it more

Do you not understand vector operations, like dot product?

R1_dot_R2 = R1x*R2x + R1y*R2y + R1z*R2z

Before you write any code, you really need to be very clear about what you want.

"Tilt Angles" depend on which system of angular measurement you decide to use, and there are 12 different Euler angle systems in common use. The tilt angle formulas used in the code for post #8 are described in this tutorial:
https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing

actually do not know about vector, this way seems so tricky

how this way will measure the angle relative to the orientation not gravity orientation

The gravity vector is always the reference, and that is what the accelerometer measures, which it is not being accelerated by other forces.

It appears that your math and programming skills are a bit weak for a project like this.

What would you do with the angles, if you could measure them?

Please could you write a code example on my code to demonstrate it because i really confused

i did not mean you write me a code for free really, i am just learning by examples that is how iam able to learn new coding.
i really appropriate you are helping me

This is a poor way to proceed, especially when you lack very basic math skills.

There are plenty of good programming tutorials on line, starting with the basics. Study one or more of those systematically. And you should be consulting the language references, both for Arduino and C/C++, whenever you see a line of code that you don't understand.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.