How to Measure Angle With MPU-6050(GY-521)

In this Instructable, we will measure angle with an Arduino. We need some cables, an Arduino UNO and GY-521(MPU-6050) in order to measure angle.

Step 1: Connecting MPU-6050 to Arduino UNO

We need some male-female cables, an Arduino UNO and GY-521(MPU-6050) sensor to measure angle. We have to connect MPU-6050 to Arduino UNO like shown in the picture. So,

  • VCC to 5V(MPU-6050 works with 3.3V but GY-521 increases it to 5V.),
  • GND to GND,
  • SCL to A5,
  • SDA to A4,
  • ADO to GND,
  • INT to digital pin 2.

Step 2: Code

Here is the code. It uses I2C. I took some parts of code from internet.(I2C part)

//Written by Ahmet Burkay KIRNIK
//Measurement of Angle with MPU-6050(GY-521)

#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); }

Step 3: Done!

It's done! If it doesn't work or you need help, please leave a comment or send an email. You can find my email adress from comments. By the way, my English is not so good so I apologise for my bad English.

Ahmet Burkay KIRNIK

Istanbul/TURKEY

Edit: After 2 years, my English got better so I corrected some mistakes.

4 People Made This Project!

Recommendations

  • Remix Contest

    Remix Contest
  • Warm and Fuzzy Contest

    Warm and Fuzzy Contest
  • Sweet Treats Challenge

    Sweet Treats Challenge

37 Discussions

0
None
MaximeP34

7 days ago

Thanks a lot for the tutorial. Simple to use and straight to the point. I'll now be able to focus on tinkering with the readings from the gyroscope.

1
None
gowfster

9 months ago

1) Why didn't the I/O pins need to be initialized? Are they defaults in wire.h?

2) Are the min/maxVal variables are unique to your calibration but may be different for different boards? How did you derive these numbers?

3) What is the purpose of connecting to the INT pin? I've disconnected it with no adverse affects.

Note that I've added the following to act more like a tilt sensor by giving the offset from 0 tilt in x and y. Z is meaningless if you are doing simple tilt sensor.

if (x>90) {x=(x-360);}

if (y>90) {y=y-360;}

1 reply
0
None
arnabdutta01gowfster

Reply 5 months ago

1) See LowPowerLab/SI7021/issues/4

2) These are from calibration and differ from board to board.

3) Quoting the MPU-6050 datasheet:

“ The data within the accelerometer sensors’ internal register set is always updated at the Sample Rate. Meanwhile, the user-facing read register set duplicates the internal register set’s data values whenever the serial interface is idle. This guarantees that a burst read of sensor registers will read measurements from the same sampling instant. Note that if burst reads are not used, the user is responsible for ensuring a set of single byte reads correspond to a single sampling instant by checking the Data Ready interrupt. ”

If you don't use the INT pin, then you have no Data Ready interrupts.

0
None
omkar.shrimali.ece16

Question 6 months ago

When I am changing the angle it's not showing any change in the output ?

0
None
HarbakshG

6 months ago

I used the same code..

It is showing the value =225 for all three angles.

Can you please solve my problem.

1 reply
0
None
BurkayKirnikHarbakshG

Reply 6 months ago

It's probably because of incorrect wire connections. Could you please check them? BTW, I suggest you to use the code that I attached there because some things may be changed.

0
None
VannarongT

6 months ago on Step 3

Hi Ahmet Burkay KIRNIK! I am newer of mpu can u descrip me:
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);

I really want to understands each. I hope you will

1 reply
0
None
BurkayKirnikVannarongT

Reply 6 months ago

It's been long time since I wrote this code and as I remember,


Hi Ahmet Burkay KIRNIK! I am newer of mpu can u descrip me:
Wire.beginTransmission(MPU_addr);

Wire.write(0x3B);

Wire.endTransmission(false);

Wire.requestFrom(MPU_addr,14,true);

this part sets and I2C connection between mpu and arduino.

AcX=Wire.read()<<8|Wire.read();

AcY=Wire.read()<<8|Wire.read();

AcZ=Wire.read()<<8|Wire.read();

this part reads raw x, y, z values from mpu and saves them to AcX , AcY and AcZ respectively.

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);

this part translates raw values to degree. As I remember, I found that calculation part from internet and translated it to Arduino code.

0
None
ElvioS2

10 months ago on Step 3

This program was so simple and efficient! Thanks for sharing!!!

0
None
OraH2

1 year ago

I have a problem the sensor only measures 255 and doesnt change ?

2 replies
0
None
LEXIE24OraH2

Reply 10 months ago

I have the same problem, any ideas?

0
None
BurkayKirnikOraH2

Reply 1 year ago

Maybe you connected a wire incorrect. Could you check it?

0
None
AmanC46

Question 1 year ago on Step 2

what is the meaning of int xAng = map(AcX,minVal,maxVal,-90,90);

0
None
halild4

1 year ago

iyi günler

gerçekten güzel çalışma. devreyi şu anda test ediyorum. bende küçük bir hata var ama. 0-360 arası açıyı ölçerken 260 ile 290 arasında farklı değer gösteriyor. benimde 0-360 arası açıyı ölçmem gerekiyor. nerede hata yapıyorum. yardımcı olabilir misiniz acaba?

3 replies
0
None
BurkayKirnikhalild4

Reply 1 year ago

kabloları yanlış bağlamış olma ihtimaliniz var mı acaba bir kontrol edebilir misiniz?

0
None
halild4BurkayKirnik

Reply 1 year ago

Teşekkürler ilginiz için Burkay Bey. Koddaki minvalue değerini 235 e çekince düzeldi ölçümler. bugün çözebildik hatayı. bir okul projesi için adroid uygulama geliştirmeye çalışıyoruz. kodlarınız baya yardımcı oldu bize. Teşekkürler yardımlarınız için

0
None
BurkayKirnikhalild4

Reply 1 year ago

Yardımcı olabildiysem ne mutlu bana. İyi günler

0
None
FlavienB

2 years ago

Hello, where from do you take the minVal and maxVal ?

1 reply
0
None
orkunvemosi

1 year ago

Hi! The program uploads fine but the values I get with your code are strange. I get 180 degree changes on both X and Y axises. Any idea why?

Capture.JPG