Get angle degress with MPU6050

Hello, I’m new to this forum and new to the arduino world. I am a computer engineering student and I have a project that I want to measure the degrees of a window every time it opens or closes.

This is the code I use that works but only when the movement is perpendicular to the ground. In the test I did in the window where the movement is parallel to the ground I can not take correct measurements. How else could I take measurements when the movement is parallel to the ground?
Can I do this with this sensor or will I need a magnetic one?

#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

#define MPU6050_ACCEL_FS_16         0x03
#define MPU6050_GYRO_FS_250         0x00
#define MPU6050_PWR2_LP_WAKE_CTRL_BIT       7
#define uS_TO_S_FACTOR 1000000ULL  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  15        /* Time ESP32 will go to sleep (in seconds) */

MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;
float pitchx, rolly;

void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);
  Wire.begin();

  // initialize device
  Serial.println("Initializing I2C devices...");
  accelgyro.initialize();

  // verify connection
  Serial.println("Testing device connections...");
  Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

  //Set Gyroscope scale 250°/s
  accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_250);
  Serial.print("Gyro scale is: "); Serial.println(accelgyro.getFullScaleGyroRange());

  //Set Acceleration scale 16g
  accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_16);
  Serial.print("acce scale is: "); Serial.println(accelgyro.getFullScaleAccelRange());

  Serial.print("GyroOffset x: "); Serial.println(accelgyro.getXGyroOffset());
  Serial.print("GyroOffset y: "); Serial.println(accelgyro.getYGyroOffset());
  Serial.print("GyroOffset z: "); Serial.println(accelgyro.getZGyroOffset());
  Serial.print("AccelOffset x: "); Serial.println(accelgyro.getXAccelOffset());
  Serial.print("AccelOffset y: "); Serial.println(accelgyro.getYAccelOffset());
  Serial.print("AccelOffset z: "); Serial.println(accelgyro.getZAccelOffset());

  for (int i = 0; i < 1000; i++) {

    // read raw accel/gyro measurements from device
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

    // display tab-separated accel/gyro x/y/z values
    Serial.print("a/g:\t");
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.print(az); Serial.print("\t");
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);



    rolly = (atan2(ay , az) * 180.0 / PI);
    pitchx = (atan2(-ax , sqrt(ay * ay + az * az)) * 180.0 / PI) ;

    Serial.print("Roll: ") ;
    Serial.println(rolly) ;
    Serial.print("Pitch: ") ;
    Serial.println(pitchx) ;
    delay(100);
  }

  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Going for sleep now");
  esp_deep_sleep_start();
}

void loop() {
  // put your main code here, to run repeatedly:

}

There is no need to read the gyro, as it not used. Below is the simplest MPU-6050 code.

// minimal MPU-6050 tilt and roll (sjr)
// works perfectly with GY-521, pitch and roll signs agree with arrows on sensor module 7/2019
// tested with eBay Pro Mini, **no external pullups on SDA and SCL** (works with internal pullups!)
// 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, true); //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);
}

How else could I take measurements when the movement is parallel to the ground?

How does that change tilt angle? What do you mean by “degrees of a window”? Please make and post a drawing.

Hello Jremington,

This code only works when the window opens in revocation. When the window opens normally where the movement is parallel to the ground I do not take any correct measurements. Let’s say that the window when closed is at 0 degrees. For example when I open the window at 45 degrees I should take a 45 degree tilt, but instead I take almost the same measurements when the window is at 0 degrees.

Τhe sensor is mounted vertically above the window handle.

!(http://<a href=)sensor2"

If there is no change in tilt, a tilt sensor is not what you should be using.

You could try a 3D orientation sensor, like the BNO055.

So when you plug the thing into your computer to read the serial prints on your monitor and you move the breadboard with the mpu, what does it do?

Does it print out a differing numbers as the mpu is tilted?

Hello Idahowalker,

Εvery time I open the window in random degrees or in specific all the measurements I take are almost the same. I think this is responsible bcause there is no change in the z axis so that I can measure the specific degrees through pitch, roll. Βut when the movement is perpendicular to the ground there is a big change in the z axis, so I can calculate the degrees correctly.

Perhaps you could show some sample data, I would definitely expect the z to vary as the angle changes.

You could just use a potentiometer mounted on the frame and linked the the window . Avoids having to pass wiring across a hinge too !