MPU6050 initial value relative to starting angle

Hi everyone, I’m new to the forum and wanted ask for some help… I had a project that require detection on the sensor after it is being place on the ground… had seen some examples on how to get the angles… but the code are all set to start off with the mpu6050 being set flat… Even before the program start, I tried to change the direction, it will still give me the value on the angle of the direction relative to the flat surfce…
what should i do with the code to change the initial value on start?

As for now, i set the angle to 45 to light up the led…
can anyone advise me on where is the code to change?

//Support
//Website: http://www.brokking.net/imu.html
//Youtube: https://youtu.be/4BoIE8YQwM8
//Version: 1.0 (May 5, 2016)

#include <Wire.h>
//Declaring some global variables
int gyro_x, gyro_y, gyro_z;
long gyro_x_cal, gyro_y_cal, gyro_z_cal;
boolean set_gyro_angles;

long acc_x, acc_y, acc_z, acc_total_vector;
float angle_roll_acc, angle_pitch_acc;

float angle_pitch, angle_roll;
int angle_pitch_buffer, angle_roll_buffer;
float angle_pitch_output, angle_roll_output;

long loop_timer;
int temp;

void setup() {

 pinMode(7, OUTPUT);
 
 Wire.begin();                               
 setup_mpu_6050_registers();                                 
 for (int cal_int = 0; cal_int < 1000 ; cal_int ++){         
   read_mpu_6050_data();                                             
   gyro_x_cal += gyro_x;                                             
   gyro_y_cal += gyro_y;
   gyro_z_cal += gyro_z;
   delay(3);                                               
 }

 gyro_x_cal /= 1000;                                                 
 gyro_y_cal /= 1000;                                                 
 gyro_z_cal /= 1000;                                                 
 Serial.begin(115200);
 loop_timer = micros();                                              
}

void setup_mpu_6050_registers(){
 //Activate the MPU-6050
 Wire.beginTransmission(0x68);
 Wire.write(0x6B);
 Wire.write(0x00); 
 Wire.endTransmission();                                             
 //Configure the accelerometer (+/-8g)
 Wire.beginTransmission(0x68);
 Wire.write(0x1C);
 Wire.write(0x10);
 Wire.endTransmission();                                             
 //Configure the gyro (500dps full scale)
 Wire.beginTransmission(0x68);
 Wire.write(0x1B);
 Wire.write(0x08);
 Wire.endTransmission();                                             
}

void loop(){ 

 read_mpu_6050_data();   

 gyro_x -= gyro_x_cal;
 gyro_y -= gyro_y_cal;
 gyro_z -= gyro_z_cal;
        

 angle_pitch += gyro_x * 0.0000611;
 angle_roll += gyro_y * 0.0000611;
 
 angle_pitch += angle_roll * sin(gyro_z * 0.000001066);
 angle_roll -= angle_pitch * sin(gyro_z * 0.000001066);
 
 //Accelerometer angle calculations
 acc_total_vector = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z));
 //57.296 = 1 / (3.142 / 180) The Arduino asin function is in radians
 angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296;
 angle_roll_acc = asin((float)acc_x/acc_total_vector)* -57.296;
 
 angle_pitch_acc -= 0.0;
 angle_roll_acc -= 0.0;

 if(set_gyro_angles){
   angle_pitch = angle_pitch * 0.9996 + angle_pitch_acc * 0.0004;
   angle_roll = angle_roll * 0.9996 + angle_roll_acc * 0.0004;
 }
 else{
   angle_pitch = angle_pitch_acc;
   angle_roll = angle_roll_acc;
   set_gyro_angles = true; 
 }
 
 angle_pitch_output = angle_pitch_output * 0.9 + angle_pitch * 0.1;
 angle_roll_output = angle_roll_output * 0.9 + angle_roll * 0.1;
 Serial.print(" | Angle X  = "); Serial.print(angle_pitch_output);
 Serial.print(" | Angle Y  = "); Serial.println(angle_roll_output);

while(micros() - loop_timer < 4000);
loop_timer = micros();//Reset the loop timer

if (angle_pitch_output > 45.00 || angle_pitch_output < -45.00) {
 digitalWrite(7, HIGH); 
} else {
 digitalWrite(7, LOW);
}

}

void read_mpu_6050_data(){
 Wire.beginTransmission(0x68);  
 Wire.write(0x3B);  
 Wire.endTransmission();     
 Wire.requestFrom(0x68,14);    
 while(Wire.available() < 14); 
 acc_x = Wire.read()<<8|Wire.read();
 acc_y = Wire.read()<<8|Wire.read();
 acc_z = Wire.read()<<8|Wire.read();                                  
 temp = Wire.read()<<8|Wire.read();                                   
 gyro_x = Wire.read()<<8|Wire.read();                                 
 gyro_y = Wire.read()<<8|Wire.read();                                 
 gyro_z = Wire.read()<<8|Wire.read();                                 
}

You do not have… a lot of things.

Take a look here to get started: onehorse | Mbed

Consider that you start the MPU60X0 up and do a calibration right off the bat. What are the range settings for the gyros and accelerometers, what are the scale factors that you used for the calibration?

Please use code tags so the code looks like this:

void fGetIMU( void *pvParameters )
{
  if ( fInitializeDevice( ) )
  {
    if ( fInitializeAG() )
    {
      if ( fDO_AG_ID() )
      {
        if ( fInitializeM() )
        {
          if ( fDO_M_ID() )
          {
            fReboot();
            vTaskDelay( 10 );
            Serial.print ( " M self ID'd: " );
            Serial.println(  getMAG_ID_OK() );
            fEnableGandA(); // enable gyros and accelerometers
            fEnableM();
            setupAccelScale( LSM9DS1_ACCELRANGE_16G );
            setupGyroScale ( LSM9DS1_GYROSCALE_2000DPS );
            setupMagScale( LSM9DS1_MAGGAIN_16GAUSS );
            calibrate();
//            Serial.print( " aXbias = " );
//            Serial.print( get_aXbias(), 6 );
//            Serial.print( " aYbias = " );
//            Serial.print( get_aYbias(), 6 );
//            Serial.print( " aZias = " );
//            Serial.print( get_aZbias(), 6 );
//            Serial.print( " gXbias ");
//            Serial.print( get_gXbias(), 6 );
//            Serial.print( " gYbias = " );
//            Serial.print( get_gYbias(), 6 );
//            Serial.print( " gZbias = " );
//            Serial.println( get_gZbias(), 6 );
          } // if ( fDO_M_ID )
        } // if ( fInitializeM() )
      } // if ( fDO_AG_ID() )
    } // if ( fInitializeAG() )
  } // if ( fInitializeDevice( ) )
  ////
  TickType_t xLastWakeTime;
  const TickType_t xFrequency = pdMS_TO_TICKS( 100 );
  xLastWakeTime = xTaskGetTickCount();
  ////
  while (1)
  {
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    if (  getLSM9DS1_ID_OK() &&  getMAG_ID_OK() ) // then do things
    {
      fReadAccelerometers();
      fReadGyros();
      fReadMagnetometer();
      //      Serial.print ( "aX= ");
      Serial.print( get_aX(),6 );
      //      Serial.print (  " aY= ");
      Serial.print ( ", ");
      Serial.print( get_aY(),6 );
      //      Serial.print (  " aZ= ");
      // Serial.print ( ", ");
      // Serial.print( get_aZ(),6 );
      // Serial.print ( ", ");
      //      Serial.print ( " gX= ");
      // Serial.print(  get_gX(),6 );
      // Serial.print ( ", ");
      //      Serial.print ( " gY= ");
     // Serial.print( get_gY(),6 );
     // Serial.print ( ", ");
      //      Serial.print ( " gZ= ");
     // Serial.print( get_gZ(),6 );
     //   Serial.print ( " mX= ");
      // Serial.print( get_mX(),6 );
      // Serial.print ( ", ");
      //      Serial.print ( " mY= ");
      // Serial.print( get_mY(),6 );
      // Serial.print ( ", ");
      //      Serial.print ( " mZ= ");
      // Serial.print( get_mZ(),6 );
      Serial.println();
    } // if ( LSM9DS1_ID_OK && M_ID_OK ) // then do things
    else
    {
      Serial.print ( " LSM9DS1_ID_NOT_OK ");
      Serial.print ( getLSM9DS1_ID_OK() );
      Serial.print ( " or MAG_ID_OK not OK " );
      Serial.println(  getMAG_ID_OK() );
    }
    xLastWakeTime = xTaskGetTickCount();
  }
  vTaskDelete(NULL);
} // void fGetIMU( void *pvParameters )

Please edit your post and add code tags, as described in "How to use this forum".

To measure just pitch and roll tilt angles (with zero degrees = horizontal), only the accelerometer is used. In fact, the gyro is useless on a stationary sensor, as it measures rotation rates.

Tutorial here for tilt sensing: How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing-DFRobot

Thanks for the replies,
I guess I need to read up more on the 6050 on the relationship of the accel and gyro to proper understand why I need both?

Hi i-link,

It's possible to calculate the angle of tilt from the gyroscope by integrating (summing) the rate of rotation (in say degrees or radians per second) for a given axis divided by time. In this case time is the time between samples (dt):

gyroscope angle += angular rate / dt

The issue with using the gyroscope in this fashion however is that it drifts over time and has no absolute point of reference. In other words, the gyroscope is stable in the short term, but prone to errors over the long term.

Using some trigonometry it's also possible to use a 3-axis accelerometer to measure gravity and thereby calculate an absolute reference angle in terms of pitch and roll. The issue with the accelerometer however is that it's noisy and external disturbances or motion other than gravity affect the results. In contrast to the gyroscope, the accelerometer is stable over the long term, but prone to errors in the short term.

The solution is to use sensor fusion in order to obtain the advantages of each device, while at the same time mitigating their disadvantages. This task can be performed by simply using a complementary filter, or using more advanced techniques such as the Kalman, Madgwick or Mahony filters.

For example using a complementary filter for a given axis, usually around 99.9% of the gyroscope's integrated angle is summed with 0.1% of the accelerometer for each sample time (dt):

filtered angle = 0.999 * gyroscope angle + 0.001 * accelerometer angle

The resultant filtered angle essentially combines the gyroscope's short term stability and invariance to disturbance with the accelerometer's long term absolute reference angle that cancels the gyroscope's tendency to drift over time.

I guess I need to read up more on the 6050 on the relationship of the accel and gyro to proper understand why I need both?

You don't, to measure a fixed tilt angle. See reply #2.

If you give a better description of what you are trying to do, you might get more useful answers.