# Mpu9250 inclination detecting code - need help in defining the default value

**URL:** <https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391>\
**Category:** Arduino\
**Created:** [14 September 2020 14:49 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391 "2020-09-14T14:49:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jinkyung128517](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@Jinkyung128517](https://forum.core-electronics.com.au/u/Jinkyung128517)\
**Post date:** [14 September 2020 14:49 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/1 "2020-09-14T14:49:45Z")

</div>

hi there, I need some help with my code, my project is about making a device that detects users’ posture and gives haptic feedback when they are slouched (20degree) or reclined back (40degrees). so what I want to is to detect forward tilt of 20 degrees and back-recline of 40 degrees (when the sensor is at 90 degrees default) and when the values are more than or equal to those front and back angles, the device will give notification with an output sensor. like how it is shown below:

 ![image](https://canada1.discourse-cdn.com/flex028/uploads/core_electronics/original/2X/b/ba9148033a03d5656ce20749853981c56fa80e89.png)

this is the code:  
#include \<MPU9250.h\>

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68  
MPU9250 IMU(Wire,0x68);  
int status;  
float ax0 = 0 ;  
float ay0 = 0 ;  
float az0 = 0 ;

void setup() {  
// serial to display data  
Serial.begin(115200);  
while(!Serial) {}

// start communication with IMU  
status = IMU.begin();  
if (status \< 0) {  
Serial.println(“IMU initialization unsuccessful”);  
Serial.println(“Check IMU wiring or try cycling power”);  
Serial.print("Status: ");  
Serial.println(status);  
while(1) {}  
}  
ax0 = IMU.getAccelX\_mss();  
ay0 = IMU.getAccelY\_mss();  
az0 = IMU.getAccelZ\_mss();

}  
void loop() {  
// read the sensor  
IMU.readSensor();  
float ax = IMU.getAccelX\_mss();  
float ay = IMU.getAccelY\_mss();  
float az = IMU.getAccelZ\_mss();  
//float inclination=180.0 _acos(az/sqrt(ax_ ax+ay _ay+az_ az))/M\_PI;.  
float inclination = 180.0 _acos( (ax0_ ax + ay0 _ay + az0_ az)/sqrt( (ax _ax + ay_ ay + az _az)_ (ax0 _ax0 + ay0_ ay0 + az0\*az0)))/M\_PI;  
Serial.println (inclination);  
delay(200);  
}

At the moment the code reads the inclination value, but I am not quite sure which inclination it is whether it is Y-axis or x or z…

Because when I tilt the sensor forward and back it just gives the angle ( for e.g. When I tilt 20 forward and 20 backward, instead of displaying ‘70’ and ‘110’ it shows ‘20’ and ‘20’). So I think the starting angle value needs to be set at ’90’degrees in order to measure the correct back and forth inclinations. I cannot understand the formula (180.0_acos( (ax0_ax + ay0_ay + az0_az)/sqrt( (ax_ax + ay_ay + az_az)_(ax0_ax0 + ay0_ay0 + az0\*az0)))/M\_PI;) So I don’t know where I can fix to change the default value to 90. Could you please help me with these problems?

Thanks, heaps

---

<div class="post-metadata">

**Author:** ![James46717](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@James46717](https://forum.core-electronics.com.au/u/James46717)\
**Post date:** [15 September 2020 00:01 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/2 "2020-09-15T00:01:30Z")

</div>

Have tried to figure the formulae, but with out the values returned from the device I am a bit it the dark.  
Suggestion:  
Print the values as returned by the device before using them in the formulae, it might give an indication of how to detect one direction from the other.  
eg:

```
float ax = IMU.getAccelX_mss();
float ay = IMU.getAccelY_mss();
float az = IMU.getAccelZ_mss();
Serial.println (ax, 10);
Serial.println (ay, 10);
Serial.println (az, 10);

```

The 10 in the print statement means show 10 decimal places. Helps if the numbers are greater than 2 decimal places. Without it print will only show 2 decimal places.

Regards  
Jim

---

<div class="post-metadata">

**Author:** ![Bryce](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/bryce/32/3631_2.png) [@Bryce](https://forum.core-electronics.com.au/u/Bryce)\
**Post date:** [15 September 2020 01:03 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/3 "2020-09-15T01:03:07Z")

</div>

Hey Jinky,

Excellent idea for a project, I’d personally be using a ‘running’ variable called _dir_ or similar, set to either zero, one, or negative one by a switch() {} which would ‘flip-flop’ about zero when the value passes a certain point which you can hardcode and then use float inclination = 90-(dir)(180acos(…) as an idea. Please let me know if you’re able to implement this one or if there’s anything else that we can do for you.

Bryce  
Core Electronics | Support

---

<div class="post-metadata">

**Author:** ![James46717](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@James46717](https://forum.core-electronics.com.au/u/James46717)\
**Post date:** [16 September 2020 07:20 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/4 "2020-09-16T07:20:32Z")

</div>

The information I have shows very different formulae to get inclination information from 3-axis accelerometer data. Unsure what the formulae in your code is trying to achieve.  
The pics are from Analog Devices application note AN-1057.

Regards  
Jim

![image](https://canada1.discourse-cdn.com/flex028/uploads/core_electronics/original/2X/c/c83598e7f67a58795f2d69fd6251ccbed3c3d26d.png)

![image](https://canada1.discourse-cdn.com/flex028/uploads/core_electronics/original/2X/b/b0a682a8a9a9c5b38589319042ad881ff9303a55.png)

---

<div class="post-metadata">

**Author:** ![James46717](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@James46717](https://forum.core-electronics.com.au/u/James46717)\
**Post date:** [17 September 2020 05:44 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/5 "2020-09-17T05:44:12Z")

</div>

I bought an Adafruit MPU6050 to experiment with. Been meaning to do it for a while. Not the same as what you have but the principle is the same.

The code you posted makes more sense now.  
ax0, ay0 & az0 are the starting at rest positions when the micro starts up.  
ax, ay & az are the deviation from the starting position in 3 axis.

The formulae: `acos( (ax0*ax + ay0*ay + az0*az)/sqrt( (ax*ax + ay*ay + az*az)* (ax0*ax0 + ay0*ay0 + az0*az0)));` calculates the amount of overall deviation from the starting position. `180 / M_PI` converts this to degrees. It will always be positive as it takes no account of direction.

But you can easily determine the direction by checking the sign of AX, AY calculated from the following formulae.

```
  float AX = atan(ax/(sqrt(ay*ay + az*az))) * 180 /M_PI;
  float AY = atan(ay/(sqrt(ax*ax + az*az))) * 180 /M_PI;
  float AZ = atan((sqrt(ax*ax + ay*ay))/az) * 180 /M_PI;

```

Printout from my program.

At rest  
_AX = 7.87 AY = -1.13 AZ = 7.95_  
_T = 0.10_

Tilt forward  
_AX = 32.15 AY = 0.72 AZ = 32.16_  
_T = 24.44_

Tilt Back  
_AX = -22.02 AY = -2.70 AZ = 22.21_  
_T = 29.85_

Tilt Right  
_AX = 6.66 AY = -31.60 AZ = 32.46_  
_T = 30.46_

Tilt Left  
_AX = 3.78 AY = 35.17 AZ = 35.44_  
_T = 36.43_

T indicates there has been a change from rest, sign of AX and AY tells in which direction.

Cheers  
Jim

---

<div class="post-metadata">

**Author:** ![Bryce](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/bryce/32/3631_2.png) [@Bryce](https://forum.core-electronics.com.au/u/Bryce)\
**Post date:** [17 September 2020 23:03 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/6 "2020-09-17T23:03:25Z")

</div>

Hey James,

Excellent solution, it also may be worth putting your code up here if you feel comfortable with that so that we can dissect it use in the original project.

Bryce  
Core Electronics | Support

---

<div class="post-metadata">

**Author:** ![James46717](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@James46717](https://forum.core-electronics.com.au/u/James46717)\
**Post date:** [17 September 2020 23:38 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/7 "2020-09-17T23:38:02Z")

</div>

Happy to help Bryce.

The device and library is different but once the values are read the calculations are the same.  
Setting the range and bandwidth would be different too.

Regards  
Jim

```
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

float ax0 = 0;
float ay0 = 0;
float az0 = 0;

Adafruit_MPU6050 mpu;

//==================================
void setup(void) {
  Serial.begin(115200);
  Serial.println("--------------");
  Serial.println(" MPU6050 test ");
  Serial.println("--------------");

// initialise MPU6050
  if (!mpu.begin()) {
    Serial.println("MPU6050 not found");
    while (true) { }
  }
// Accelerometer:
// MPU6050_RANGE_2_G  
// MPU6050_RANGE_4_G  
// MPU6050_RANGE_8_G
// MPU6050_RANGE_16_G
// Gyro:
// MPU6050_RANGE_250_DEG  
// MPU6050_RANGE_500_DEG  
// MPU6050_RANGE_1000_DEG  
// MPU6050_RANGE_2000_DEG
// Filter Bandwidth
// MPU6050_BAND_260_HZ  
// MPU6050_BAND_184_HZ  
// MPU6050_BAND_94_HZ  
// MPU6050_BAND_44_HZ  
// MPU6050_BAND_21_HZ  
// MPU6050_BAND_10_HZ  
// MPU6050_BAND_5_HZ
  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  delay(2000);

// Read the initial position
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  ax0 = a.acceleration.x;
  ay0 = a.acceleration.y;
  az0 = a.acceleration.z;

  Serial.println("");
  delay(100);
}
//==================================
void loop() {

// Get new sensor events with the readings
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

// Get the raw values 
  float ax = a.acceleration.x;
  float ay = a.acceleration.y;
  float az = a.acceleration.z;

// Print raw values
  Serial.print("ax = ");
  Serial.print(ax);
  Serial.print(" ay = ");
  Serial.print(ay);
  Serial.print(", az = ");
  Serial.print(az);
  Serial.println(" m/s^2");

// Calculate the angles for the 3 axis
  float AX = atan(ax/(sqrt(ay*ay + az*az)));
  float AY = atan(ay/(sqrt(ax*ax + az*az)));
  float AZ = atan((sqrt(ax*ax + ay*ay))/az);

// Convert radians to degrees
  AX = AX * 180/M_PI;
  AY = AY * 180/M_PI;
  AZ = AZ * 180/M_PI;

// Print degrees
  Serial.print("AX = ");
  Serial.print(AX);
  Serial.print(" AY = ");
  Serial.print(AY);
  Serial.print(" AZ = ");
  Serial.println(AZ);

// Calculate the movement with respect to the initial position and all angles
  float t = acos((ax0*ax + ay0*ay + az0*az)/sqrt((ax*ax + ay*ay + az*az)*(ax0*ax0 + ay0*ay0 + az0*az0)));

// Convert radians to degrees
  t = t * 180.0/M_PI;

  Serial.print("T = ");
  Serial.println(t);

  Serial.println("");
  delay(2000);
}
```

---

<div class="post-metadata">

**Author:** ![Jinkyung128517](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@Jinkyung128517](https://forum.core-electronics.com.au/u/Jinkyung128517)\
**Post date:** [18 September 2020 07:44 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/8 "2020-09-18T07:44:27Z")

</div>

Thank you so much for the code,I applied to the initial code that I had with yours, and the serial monitor is showing this:

> 17:33:00.321 → ax = 3.46 ay = -7.50, az = AY = -55.60 AZ = 60.16  
> 17:33:00.321 → T = 114.65  
> 17:33:00.321 →   
> 17:33:02.312 → ax = -2.91 ay = 2.45, az = -9.23 m/s^2  
> 17:33:02.312 → AX = -16.93 AY = 14.22 AZ = -22.40  
> 17:33:02.312 → T = 26.95  
> 17:33:02.312 →

The code is this:

```
#include <Qduino.h>
#include <Wire.h>
#include <MPU9250.h>

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68
MPU9250 IMU(Wire,0x68);
int status;
float ax0 = 0 ;
float ay0 = 0 ;
float az0 = 0 ;

void setup() {
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}

  // start communication with IMU 
  status = IMU.begin();
  if (status < 0) {
    Serial.println("IMU initialization unsuccessful");
    Serial.println("Check IMU wiring or try cycling power");
    Serial.print("Status: ");
    Serial.println(status);
    while(1) {}
  }
  ax0 = IMU.getAccelX_mss();
  ay0 = IMU.getAccelY_mss();
  az0 = IMU.getAccelZ_mss();
        
}
void loop() {
// read the sensor
  IMU.readSensor();
  float ax = IMU.getAccelX_mss();
  float ay = IMU.getAccelY_mss();
  float az = IMU.getAccelZ_mss();

// Print raw values
  Serial.print("ax = ");
  Serial.print(ax);
  Serial.print(" ay = ");
  Serial.print(ay);
  Serial.print(", az = ");
  Serial.print(az);
  Serial.println(" m/s^2");

// Calculate the angles for the 3 axis
  float AX = atan(ax/(sqrt(ay*ay + az*az)));
  float AY = atan(ay/(sqrt(ax*ax + az*az)));
  float AZ = atan((sqrt(ax*ax + ay*ay))/az);

// Convert radians to degrees
  AX = AX * 180/M_PI;
  AY = AY * 180/M_PI;
  AZ = AZ * 180/M_PI;

// Print degrees
  Serial.print("AX = ");
  Serial.print(AX);
  Serial.print(" AY = ");
  Serial.print(AY);
  Serial.print(" AZ = ");
  Serial.println(AZ);

// Calculate the movement with respect to the initial position and all angles
  float t = acos((ax0*ax + ay0*ay + az0*az)/sqrt((ax*ax + ay*ay + az*az)*(ax0*ax0 + ay0*ay0 + az0*az0)));

// Convert radians to degrees
  t = t * 180.0/M_PI;

  Serial.print("T = ");
  Serial.println(t);

  Serial.println("");
  delay(2000);
}

```

I think I am getting what I suppose to get in the serial monitor but there are a couple of things that i do not understand. So ‘T’ represents the angle/degree changes but which direction is it representing? x,y or z? (maybe i am not understanding it correctly). If i want to check the slouched posture+back reclined posture angle (forward tilt and back tilt) of the user, i will need to see the inclined angle of _AX =_… is this correct?

---

<div class="post-metadata">

**Author:** ![James46717](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@James46717](https://forum.core-electronics.com.au/u/James46717)\
**Post date:** [18 September 2020 23:38 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/9 "2020-09-18T23:38:42Z")

</div>

I think the formulae in your original post is confusing things. I really don’t know what it it trying to show and you don’t need it to get what you want.

Below is some code I put together.  
The y & z axis are ignored except for calculating the x axis angle.  
When the device tilts forward past 70 degrees and back past 130 it displays the Beep message.

Cheers  
Jim

```
//====================================================================
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

float x = 0;
float y = 0;
float z = 0;

int x_start = 0;
int x_now = 0;

Adafruit_MPU6050 mpu;
//====================================================================
void setup(void) {
  Serial.begin(115200);
  Serial.println("--------------");
  Serial.println(" MPU6050 test ");
  Serial.println("--------------");

// initialise MPU6050
  if (!mpu.begin()) {
    Serial.println("MPU6050 not found");
    while (true) { }
  }
  delay(200);

// Get sensor readings at rest
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  x = a.acceleration.x;
  y = a.acceleration.y;
  z = a.acceleration.z;

// Convert acceleration to angular movement in radians
  x = atan(x/(sqrt(y*y + z*z)));

// Convert radians to degrees and ignore the decimal point
  x_start = (int)(x * 180/M_PI);

  delay(100);
}
//====================================================================
void loop() {

// Get sensor readings now
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  x = a.acceleration.x;
  y = a.acceleration.y;
  z = a.acceleration.z;

// Convert acceleration to angular movement in radians
  x = atan(x/(sqrt(y*y + z*z)));

// Convert radians to degrees and ignore the decimal point
  x_now = (int)(x * 180/M_PI);

// Calculate tilt angle with respect to original at rest position
// and that Vertical = 90 degrees
  int x_tilt = x_now - x_start + 90;

// Beep 
  if ((x_tilt < 70) || (x_tilt > 130)) { 
    // beep function to make noise
    Serial.println("===================");
    Serial.println(" BEEP !!!! ");
    Serial.println("===================");
  }
  Serial.print("x_tilt = ");
  Serial.println(x_tilt);
  
  delay(2000);
}
//====================================================================
```

---

<div class="post-metadata">

**Author:** ![Jinkyung128517](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@Jinkyung128517](https://forum.core-electronics.com.au/u/Jinkyung128517)\
**Post date:** [19 September 2020 09:00 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/10 "2020-09-19T09:00:55Z")

</div>

Thank you James I really appreciate your support, I got it working, my code now is this and serial monitor is showing the tilt & the “beep”  
CODE:  
#include \<Qduino.h\>  
#include \<Wire.h\>  
#include \<MPU9250.h\>

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68  
MPU9250 IMU(Wire,0x68);  
int status;  
float x0 = 0 ;  
float y0 = 0 ;  
float z0 = 0 ;  
int x\_start = 0;  
int x\_now = 0;

void setup() {  
// serial to display data  
Serial.begin(115200);  
while(!Serial) {}

// start communication with IMU  
status = IMU.begin();  
if (status \< 0) {  
Serial.println(“IMU initialization unsuccessful”);  
Serial.println(“Check IMU wiring or try cycling power”);  
Serial.print("Status: ");  
Serial.println(status);  
while(1) {}  
}  
x0 = IMU.getAccelX\_mss();  
y0 = IMU.getAccelY\_mss();  
z0 = IMU.getAccelZ\_mss();

}  
void loop() {  
// read the sensor  
IMU.readSensor();  
float x = IMU.getAccelX\_mss();  
float y = IMU.getAccelY\_mss();  
float z = IMU.getAccelZ\_mss();

// Print raw values  
Serial.print(“x = “);  
Serial.print(x);  
Serial.print(” y = “);  
Serial.print(y);  
Serial.print(”, z = “);  
Serial.print(z);  
Serial.println(” m/s^2”);

// Calculate the angles for the 3 axis  
float X = atan(x/(sqrt(y_y + z_z)));  
float Y = atan(y/(sqrt(x_x + z_z)));  
float Z = atan((sqrt(x_x + y_y))/z);

// Convert acceleration to angular movement in radians  
x = atan(x/(sqrt(y_y + z_z)));

// Convert radians to degrees and ignore the decimal point  
x\_now = (int)(x \* 180/M\_PI);

// Calculate tilt angle with respect to original at rest position  
// and that Vertical = 90 degrees  
int x\_tilt = x\_now - x\_start + 90;

// Beep  
if ((x\_tilt \< 160) || (x\_tilt \> 130)) {  
// beep function to make noise  
Serial.println("===================");  
Serial.println(" BEEP !!! “);  
Serial.println(”===================");  
}  
Serial.print("x\_tilt = ");  
Serial.println(x\_tilt);

delay(2000);  
}

# S.MONITOR: x = 6.13 y = -4.27, z = 6.34 m/s^2

```
 BEEP !!!!     

```

===================  
x\_tilt = 128

However, instead of defining the start value as ‘90’ degrees, like the previous code, I want the starting value to be at 0, so when the user wears the device in an upright sitting posture and turn on the device, the angle measurement can be starting from that point. (so wherever they place the device and doesn’t matter how the device is placed when the device is turned on, that has to be the starting point). Do I need to put this: **float t = acos((ax0 _ax + ay0_ ay + az0 _az)/sqrt((ax_ ax + ay _ay + az_ az) _(ax0_ ax0 + ay0 _ay0 + az0_ az0)));** code again? or is there another way to do it?

Moreover, I’m thinking of adding in the side inclination as well (30degrees on each side; y-axis), to do this should should the code be like:

#include \<Qduino.h\>  
#include \<Wire.h\>  
#include \<MPU9250.h\>

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68  
MPU9250 IMU(Wire,0x68);  
int status;  
float x0 = 0 ;  
float y0 = 0 ;  
float z0 = 0 ;  
int x\_start = 0;  
int x\_now = 0;  
int y\_start = 0;  
int y\_now = 0;  
void setup() {  
// serial to display data  
Serial.begin(115200);  
while(!Serial) {}

// start communication with IMU  
status = IMU.begin();  
if (status \< 0) {  
Serial.println(“IMU initialization unsuccessful”);  
Serial.println(“Check IMU wiring or try cycling power”);  
Serial.print("Status: ");  
Serial.println(status);  
while(1) {}  
}  
x0 = IMU.getAccelX\_mss();  
y0 = IMU.getAccelY\_mss();  
z0 = IMU.getAccelZ\_mss();

}  
void loop() {  
// read the sensor  
IMU.readSensor();  
float x = IMU.getAccelX\_mss();  
float y = IMU.getAccelY\_mss();  
float z = IMU.getAccelZ\_mss();

// Print raw values  
Serial.print(“x = “);  
Serial.print(x);  
Serial.print(” y = “);  
Serial.print(y);  
Serial.print(”, z = “);  
Serial.print(z);  
Serial.println(” m/s^2”);

// Calculate the angles for the 3 axis  
float X = atan(x/(sqrt(y_y + z_z)));  
float Y = atan(y/(sqrt(x_x + z_z)));  
float Z = atan((sqrt(x_x + y_y))/z);

// Convert acceleration to angular movement in radians  
x = atan(x/(sqrt(y_y + z_z)));  
y = atan(y/(sqrt(x_x + z_z)));  
// Convert radians to degrees and ignore the decimal point  
x\_now = (int)(x \* 180/M\_PI);  
y\_now = (int)(y \* 180/M\_PI);  
// Calculate tilt angle with respect to original at rest position  
// and that Vertical = 90 degrees  
int x\_tilt = x\_now - x\_start + 90;  
int y\_tilt = y\_now - y\_start + 180;  
// Beep  
if ((x\_tilt \< 70) || (x\_tilt \> 130)) {  
// beep function to make noise  
Serial.println("===================");  
Serial.println(" xBEEP !!! “);  
Serial.println(”===================");  
if ((y\_tilt \< 150) || (y\_tilt \> 210)) {  
// beep function to make noise  
Serial.println("===================");  
Serial.println(" yBEEP !!! “);  
Serial.println(”===================");  
}  
Serial.print("x\_tilt = ");  
Serial.println(x\_tilt);  
Serial.print("y\_tilt = ");  
Serial.println(y\_tilt);  
delay(2000);  
}  
}

like this?

(Sorry, my qduino is not showing up on the port again, it got turned off when i was just about to run this code above, so i couldn’t check. I need to work on the problem again. the light are on everything seems fine so I don’t know what went wrong just then. )

I thank you for your consideration in advance. Thank you so much!

---

<div class="post-metadata">

**Author:** ![James46717](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@James46717](https://forum.core-electronics.com.au/u/James46717)\
**Post date:** [19 September 2020 10:26 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/11 "2020-09-19T10:26:20Z")

</div>

This line shifts the 0 point to 90, remove the + 90 and it will be 0 again. -20 (forward) and +40 (back).

```
// Calculate tilt angle with respect to original at rest position
// and that Vertical = 90 degrees
  int x_tilt = x_now - x_start + 90;

```

Change the following line to look for the new values.

```
// Beep 
  if ((x_tilt < -20) || (x_tilt > 40)) { 
    // beep function to make noise

```

To check the y axis add the following at the appropriate places in the code.

Variable declaration.

```
int x_start = 0;
int y_start = 0;
int x_now = 0;
int y_now = 0;

```

In void setup(void)

```
// Convert acceleration to angular movement in radians
  x = atan(x/(sqrt(y*y + z*z)));
  y = atan(y/(sqrt(x*x + z*z)));

// Convert radians to degrees and ignore the decimal point
  x_start = (int)(x * 180/M_PI);
  y_start = (int)(y * 180/M_PI);

```

In void loop(void)

```
// Convert acceleration to angular movement in radians
  x = atan(x/(sqrt(y*y + z*z)));
  y = atan(y/(sqrt(x*x + z*z)));

// Convert radians to degrees and ignore the decimal point
  x_now = (int)(x * 180/M_PI);
  y_now = (int)(y * 180/M_PI);

// Calculate tilt angle with respect to original at rest position
  int x_tilt = x_now - x_start;
  int y_tilt = y_now - y_start;

// Beep 
  if ((x_tilt < -20) || (x_tilt > 40) || (y_tilt < -30) || (y_tilt > 30)) { 
    // beep function to make noise

```

Regards  
Jim

---

<div class="post-metadata">

**Author:** ![Jinkyung128517](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@Jinkyung128517](https://forum.core-electronics.com.au/u/Jinkyung128517)\
**Post date:** [20 September 2020 13:18 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/12 "2020-09-20T13:18:19Z")

</div>

**Thank you, I have tried with this code, however for some reason, the starting value isn’t 0. When I open the serial monitor (tried a few times) it shows:**

# x\_tilt = 74 y\_tilt = 63 x = 9.70 y = 2.83, z = 0.21 m/s^2

```
 BEEP !!!!     

```

# =================== x\_tilt = 73 y\_tilt = 65 x = 9.75 y = 2.78, z = 0.19 m/s^2

```
 BEEP !!!!     

```

===================

**but I would like the values to start at 0 when i upload the code. Do you think my code has some problem?**

**The code: (tried on Arduino Uno)**

#include \<Wire.h\>  
#include \<MPU9250.h\>

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68  
MPU9250 IMU(Wire,0x68);  
int status;  
float x = 0 ;  
float y = 0 ;  
float z = 0 ;  
int x\_start = 0;  
int y\_start = 0;  
int x\_now = 0;  
int y\_now = 0;;  
void setup() {  
// serial to display data  
Serial.begin(115200);  
while(!Serial) {}

// start communication with IMU  
status = IMU.begin();  
if (status \< 0) {  
Serial.println(“IMU initialization unsuccessful”);  
Serial.println(“Check IMU wiring or try cycling power”);  
Serial.print("Status: ");  
Serial.println(status);  
while(1) {}  
}  
x = atan(x/(sqrt(y_y + z_z)));  
y = atan(y/(sqrt(x_x + z_z)));  
x\_start = (int)(x \* 180/M\_PI);  
y\_start = (int)(y \* 180/M\_PI);  
}  
void loop() {  
// read the sensor  
IMU.readSensor();  
x = IMU.getAccelX\_mss();  
y = IMU.getAccelY\_mss();  
z = IMU.getAccelZ\_mss();

// Print raw values  
Serial.print(“x = “);  
Serial.print(x);  
Serial.print(” y = “);  
Serial.print(y);  
Serial.print(”, z = “);  
Serial.print(z);  
Serial.println(” m/s^2”);

// Convert acceleration to angular movement in radians  
x = atan(x/(sqrt(y_y + z_z)));  
y = atan(y/(sqrt(x_x + z_z)));

// Convert radians to degrees and ignore the decimal point  
x\_now = (int)(x \* 180/M\_PI);  
y\_now = (int)(y \* 180/M\_PI);

// Calculate tilt angle with respect to original at rest position  
int x\_tilt = x\_now - x\_start;  
int y\_tilt = y\_now - y\_start;

// Beep  
if ((x\_tilt \< -20) || (x\_tilt \> 40) || (y\_tilt \< -30) || (y\_tilt \> 30)) {  
// beep function to make noise  
Serial.println("===================");  
Serial.println(" BEEP !!! “);  
Serial.println(”===================");

}  
Serial.print("x\_tilt = ");  
Serial.println(x\_tilt);  
Serial.print("y\_tilt = ");  
Serial.println(y\_tilt);  
delay(2000);  
}

---

<div class="post-metadata">

**Author:** ![James46717](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@James46717](https://forum.core-electronics.com.au/u/James46717)\
**Post date:** [20 September 2020 21:14 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/13 "2020-09-20T21:14:41Z")

</div>

Your code looks ok.  
When my MPU6050 is sitting flat on the desk; **x\_start = 7, y\_start = -1** approximately.  
This represents the starting condition.  
In the main `loop()` `x_now & y_now` should be the same (7, -1), therefore `x_tilt & y_tilt` should be zero.

Your code is printing x, y, z just after they have been read and the values you have listed are what would be expected; if the device is sitting flat. It should also be sitting flat when the program starts so the values in `setup()` are the same.

Start the device sitting flat and dont move it.  
Try printing `x_start, x_now and y_start, y_now` after the calculation for `x_tilt, y_tilt`. They should be about the same.  
Then move the device and see how much they change.

Possibly the device could be calibrated to return zero when it is sitting flat, at rest, but that is not necessary. The values will vary from device to device and probably with environmental changes such as temperature.

Regards  
Jim

---

<div class="post-metadata">

**Author:** ![Jinkyung128517](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@Jinkyung128517](https://forum.core-electronics.com.au/u/Jinkyung128517)\
**Post date:** [21 September 2020 03:12 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/14 "2020-09-21T03:12:09Z")

</div>

Thanks for the reply, maybe I didnt make myself clear,

so in order to get 0 value the sensor needs to be flat in this case, but my intention is to actually make the initial point (when the device is turned on by the user) to be the starting point of measuring tilt angles. So when the user **turns on** the device, **no matter how the device is placed/positioned** it starts measuring the angles **from that point**.

Let’s say the user is sitting upright and turns on the device that is attached at their back. The device starts reading the angle tilts from the time they activates the device. So let’s say the upright posture value or the initial value is 0. Then, if the device gets front-tilted (20) or (20)+ degrees it beeps and when they recline backwards (-40) or (-40)+ degrees it beeps.

Is the code that I have doing that? or do I need a different formula for that?

secondly, you said the values will vary from device to device and probably with environmental changes such as temperature; how can the angle measures of movement be affected by the temperature?

Thank you

---

<div class="post-metadata">

**Author:** ![Bryce](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/bryce/32/3631_2.png) [@Bryce](https://forum.core-electronics.com.au/u/Bryce)\
**Post date:** [21 September 2020 23:45 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/15 "2020-09-21T23:45:50Z")

</div>

Hey Jinky,

That’s interesting, I wonder whether you can set up a watchdog to keep the device on continuously, or a secondary system to verify the initial position, I’ll let James run you through the code for this one given he’s written that original script (of course @James46717 if you’d like me to have a look through it for you to see how it can be modded please let me know)

As for how the values may change with temperature, indoors I’d imagine the effect would be quite insignificant as you don’t have to worry too much about sunlight, rapid changes, or anything like that. But generally the biggest reason temperature affects measurements is because of how it changes the resistance of materials (most importantly the semiconductors inside sensors) which on a physical level, when not accounted for, will cause the values that are read to maintain their precision (generally) but to read uncalibrated values which are slightly off the real value, but 90% of the time, it won’t be significant. I hope that clears up your second question. 🙂

Bryce  
Core Electronics | Support

---

<div class="post-metadata">

**Author:** ![Jinkyung128517](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@Jinkyung128517](https://forum.core-electronics.com.au/u/Jinkyung128517)\
**Post date:** [22 September 2020 01:03 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/16 "2020-09-22T01:03:08Z")

</div>

Thank you for the reply,

The device doesn’t need to read the values after it gets turned off. When it gets turned on back again, the initial value is defined at that moment again, not considering the previous initial value.

---

<div class="post-metadata">

**Author:** ![Jinkyung128517](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@Jinkyung128517](https://forum.core-electronics.com.au/u/Jinkyung128517)\
**Post date:** [22 September 2020 02:35 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/17 "2020-09-22T02:35:19Z")

</div>

Also thank you for your answer to my second question! 🙂

---

<div class="post-metadata">

**Author:** ![Bryce](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/bryce/32/3631_2.png) [@Bryce](https://forum.core-electronics.com.au/u/Bryce)\
**Post date:** [22 September 2020 02:56 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/18 "2020-09-22T02:56:27Z")

</div>

Hey Jinkyung,

(Please let me know whether the name is right 😅)

I’ve just gotten some advice on this project from one of my colleagues Michael who suggested looking into using Quartenions in 3D space which determine angle and a moment of rotation rather than simply reading the angle in order to determine the direction. I’m going to do a little more research on how this integrates with this MPU9250 and get back to you but that’s a great place to start looking.

Bryce  
Core Electronics | Support

---

<div class="post-metadata">

**Author:** ![Jinkyung128517](https://avatars.discourse-cdn.com/v4/letter/j/71e660/32.png) [@Jinkyung128517](https://forum.core-electronics.com.au/u/Jinkyung128517)\
**Post date:** [22 September 2020 03:10 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/19 "2020-09-22T03:10:22Z")

</div>

> [@Bryce](#):
>
> I’ve just gotten some advice on this project from one of my colleagues Michael who suggested looking into using Quartenions in 3D space which determine angle and a moment of rotation rather than simply reading the angle in order to determine the direction. I

Yup, that is my name! 🙂

Thank you so much! Please let me know about it, I would like to finish coding within this week so that i can solder the parts but it is ok if it is not figured out, I will try to do other things first.

---

<div class="post-metadata">

**Author:** ![James46717](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@James46717](https://forum.core-electronics.com.au/u/James46717)\
**Post date:** [22 September 2020 09:17 UTC](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391/20 "2020-09-22T09:17:18Z")

</div>

Tested the MPU6050 at various starting angles with the code provided. Changed the board position, pressed reset on the UNO, tried to hold the board still till the first reading appeared.  
In all cases it worked, `x_tilt and y_tilt` were zero or close to zero until the board is moved.  
So the code will do what you want.

Reference to being flat on desk was to remove minor movements that would be introduced by holding it by hand.

The reading of the MPU6050 sensors and calculation of `x_tilt and y_tilt` takes about 3.6 milliseconds. You could simply reset the UNO if the MPU6050 was repositioned. But the UNO takes a little while longer to start. The addition of a switch on one of the digital pins could be used to reset the position. Pressing this switch would tell the program to get the new values for `x_start and y_start`. The following is the code that would need to be executed.

```
// Get sensor readings at rest
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  x = a.acceleration.x;
  y = a.acceleration.y;
  z = a.acceleration.z;

// Convert acceleration to angular movement in radians
  x = atan(x/(sqrt(y*y + z*z)));
  y = atan(y/(sqrt(x*x + z*z)));

// Convert radians to degrees and ignore the decimal point
  x_start = (int)(x * 180/M_PI);
  y_start = (int)(y * 180/M_PI); 

```

Every electronic device is subject to temperature changes as Bryce mentioned.  
Most of these very sensitive device include a temperature monitor to allow minor programming changes if the temperature varies. It means the device can be extremely accurate when programmed correctly.  
The manufacturing process is such that there will be minor changes in the ICs. It is impossible to make every one exactly the same. My device sitting flat produces `x = 7, y = -1`. It should produce zero as it is flat. If I was to purchase another device from Core Electronics it might return `x = 2, y =1`, etc.

Anyway, all the best.  
Cheers  
Jim

[Next page](https://forum.core-electronics.com.au/t/mpu9250-inclination-detecting-code-need-help-in-defining-the-default-value/8391.md?page=2)
