How to use the accelerometer- gyroscope GY-521

Find out how the world turns. Read the values of the accelerometer and the gyroscope.

Jul 23, 2017

292712 views

38 respects

Components and supplies

1

GY-521 MPU-6050 3 Axis Gyroscope + Accelerometer Module For Arduino

1

Arduino UNO

Project description

Code

Project code

arduino

Downloadable files

circuit diagram

circuit diagram

Image

circuit diagram

circuit diagram

Image

Comments

Only logged in users can leave comments

Image
Image

al2398hc

2 months ago

I am doing a high school project and I need help with programming. I am designing that 3 LEDs in the 2-3-4 digital output of the MEGA2560 board light up depending on the movement of the GY-521 (red- a lot of movement, yellow- normal movement and green- slow movement). can you help me

Image
Image

Anonymous user

2 years ago

I have another problem, Gyro data is sended first and then Acceleration //read accel data GyX=(Wire.read()<<8|Wire.read()) + GyXoff; GyY=(Wire.read()<<8|Wire.read()) + GyYoff; GyZ=(Wire.read()<<8|Wire.read()) + GyZoff; //read temperature data temp=(Wire.read()<<8|Wire.read()) + toff; tx=temp; t = tx/340 + 36.53; //tf = (t * 9/5) + 32; // farenhait //read gyro data AcX=(Wire.read()<<8|Wire.read()) + AcXoff; AcY=(Wire.read()<<8|Wire.read()) + AcYoff; AcZ=(Wire.read()<<8|Wire.read()) + AcYoff; //get pitch/roll getAngle(GyX,GyY,GyZ); Also I need change input to function to input Gy as values to pitch, because data is sensed from module in opposite to what this tutorial show. Now I have accurate data. Problem is whit this module, that Gyroscope don't have Z axis. There is only X and Y, and for my needs I need Z axis more then that X and Y for my project. Now I need think if I need use magnetic earth module to display Z rotation

Image
Image

Anonymous user

2 years ago

How do you change the accelerometer scale in the code? It seems like it is automatically set to +/-2g and I see no way of changing it.

Image
Image

Anonymous user

2 years ago

Is there a way to connect, say, 7 of them to one arduino and get result values separately but fast enough that they are essentially at the same time, I guess what I am asking is, is there a way to change the i2c device id?

Image
Image

Anonymous user

2 years ago

No, not without some sort of I2C multiplexer. The I2C device address can be set on the MPU-60X0 parts, but only the least significant bit, meaning you can only have two devices on the bus at the one time (with having it's ADO pin pulled high, and the other having it's ADO pin pulled low).

Image
Image

Anonymous user

2 years ago

So the values I get are very inconsistent, when it is not moving at all it has a difference to the prvious one of up to 160. Can I somehow make this more accurate?

Image
Image

Anonymous user

2 years ago

So a quick question, i'm very new to programming and using Arduino first off. If i'd like to change the pin out from: SCL -> A5 SDA -> A4 to: SCL -> A3 SDA-> A2 What part of the code would I need to change? This is for a school project. Any help would be appreciated, Thank you very much. Cheers!

Image
Image

kgray9

2 years ago

SDA and SCL can also be connected to the topmost pins on the digital side of an Arduino Uno. They're usually labeled on the bottom.

Image
Image

Nicholas_N

2 years ago

SCL and SDA must be connected to A5 and A4 otherwise it will not work.

Image
Image

Anonymous user

2 years ago

The z-axis of accelerometer of MPU6050 is not providing any range of values as the x and y axes, the z-axis readings just flicker upon tilting in the z-axis direction. How do I resolve this problem? I need the z-axis readings to vary as I tilt the device in z-axis direction.

Image
Image

Anonymous user

2 years ago

I have this same problem. And also Gyroscope in my module is displayed first, then accelerometer

Image
Image

iFrostizz67

2 years ago

Thanks a lot ! It will help me a lot for a project !! :)

Image
Image

Anonymous user

2 years ago

Very good illustration, i have couple of questions please reply 1) please explain line 8,9 and 15 in the code? why wire.write 0x6B, 0 and 0x3B to MPU? 2) how do you know first requested 6 bytes are for acc and next 6 for gyro, how one can know, i explore google but could not find datasheet of Gy521.

Image
Image

Anonymous user

2 years ago

Datasheet you're after is for the MPU-6050, not the GY521 ;) If you look up the "MPU-6050 Register Map and Register Descriptions document" you'll find the register list you're looking for. When you request 6 bytes from register 0x3B/59 onwards, you get the MSB and LSB for AccX, AccY and AccZ, followed by two bytes for temperature, and then another six bytes for the gyro. The code should have either requested 14 bytes instead of 12, and also either displayed or dealt with the temperature, or read six bytes, and then another six bytes from 0x43/67 onwards. As far as what the other lines do, I believe 8 &9 enable the internal 8MHz oscillator, basically so that the MPU becomes accessible. I'm not sure why it's needed, as it should default to this on power up. Maybe some other required startup step is being skipped, and this is a workaround, or isn't actually needed.

Image
Image

Gallax

2 years ago

Crazy question, but did you have the username cratos333 ever? I used to get codes from a guy

Image
Image

Anonymous user

2 years ago

I'm surprised that it doesnt give any errors but it doesnt give me any good values. It just tells me the same values all the time. Can you explain that how i could fix this?

Image
Image

Anonymous user

2 years ago

I got error when i compile your code with Arduino Due 'call of overloaded 'beginTransmission(MPU_Type*)' is ambiguous'

Image
Image

Anonymous user

2 years ago

What is the reason for the bit shift and is that an ORing? in the lines like: AcX=Wire.read()<<8|Wire.read();

Image
Image

Nicholas_N

2 years ago

That line reads two registers. With two registers we have one variable.

Image
Image

Anonymous user

2 years ago

Hello :) Thank you very much for sharing this project! How did you do the diagram/drawing of the gyro?

Image
Image

Anonymous user

2 years ago

Great project! You might want to use functions tho to make your code more reusable.

Image
Image

Anonymous user

2 years ago

The code has an error in it.. The data being recalled has a temperature reading between the accel and the gyro data. This code fixes it and it also 1. converts the accel data to roll and pitch angles. 2. calculates the temperature in F and C 3. adds correction values for the accel and temp data. ====================== #include<Wire.h> #include <math.h> const int MPU=0x68; int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; double pitch,roll; void setup(){ Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(9600); } void loop(){ Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU,14,true); int AcXoff,AcYoff,AcZoff,GyXoff,GyYoff,GyZoff; int temp,toff; double t,tx,tf; //Acceleration data correction AcXoff = -950; AcYoff = -300; AcZoff = 0; //Temperature correction toff = -1600; //Gyro correction GyXoff = 480; GyYoff = 170; GyZoff = 210; //read accel data AcX=(Wire.read()<<8|Wire.read()) + AcXoff; AcY=(Wire.read()<<8|Wire.read()) + AcYoff; AcZ=(Wire.read()<<8|Wire.read()) + AcYoff; //read temperature data temp=(Wire.read()<<8|Wire.read()) + toff; tx=temp; t = tx/340 + 36.53; tf = (t * 9/5) + 32; //read gyro data GyX=(Wire.read()<<8|Wire.read()) + GyXoff; GyY=(Wire.read()<<8|Wire.read()) + GyYoff; GyZ=(Wire.read()<<8|Wire.read()) + GyZoff; //get pitch/roll getAngle(AcX,AcY,AcZ); //send the data out the serial port Serial.print("Angle: "); Serial.print("Pitch = "); Serial.print(pitch); Serial.print(" | Roll = "); Serial.println(roll); Serial.print("Temp: "); Serial.print("Temp(F) = "); Serial.print(tf); Serial.print(" | Temp(C) = "); Serial.println(t); Serial.print("Accelerometer: "); Serial.print("X = "); Serial.print(AcX); Serial.print(" | Y = "); Serial.print(AcY); Serial.print(" | Z = "); Serial.println(AcZ); Serial.print("Gyroscope: "); Serial.print("X = "); Serial.print(GyX); Serial.print(" | Y = "); Serial.print(GyY); Serial.print(" | Z = "); Serial.println(GyZ); Serial.println(" "); delay(333); } //convert the accel data to pitch/roll void getAngle(int Vx,int Vy,int Vz) { double x = Vx; double y = Vy; double z = Vz; pitch = atan(x/sqrt((y*y) + (z*z))); roll = atan(y/sqrt((x*x) + (z*z))); //convert radians into degrees pitch = pitch * (180.0/3.14); roll = roll * (180.0/3.14) ; }

Image
Image

cyber2024

2 years ago

Nice work mate. Not to nitpick, but you have added AcYoff incorrectly to the AcZ calc. >AcZ=(Wire.read()<<8|Wire.read()) + AcYoff; I'm using your code to help me reduce latency, the adafruit library takes 6ms to read data, this is getting down to around 1ms which is how frequently I need to update my steppers. Thanks!

Image
Image

Anonymous user

2 years ago

can i get library of wire & math .

Image
Image

Anonymous user

2 years ago

I know this post is 5 years old but, I am trying to use this code on an MPU-6050, and i am getting -1 for all values. I have my gyroscope plugged in exactly as the diagram says, with the exception of using the 5V line instead of 3.3V, as its indicated that that is better. Is it possible my MPU is just dead?

Image
Image

neue

3 years ago

Hello :) Thank you very much for sharing this project! How did you do the diagram/drawing of the gyro?

Image
Image

Anonymous user

4 years ago

I have another problem, Gyro data is sended first and then Acceleration //read accel data GyX=(Wire.read()<<8|Wire.read()) + GyXoff; GyY=(Wire.read()<<8|Wire.read()) + GyYoff; GyZ=(Wire.read()<<8|Wire.read()) + GyZoff; //read temperature data temp=(Wire.read()<<8|Wire.read()) + toff; tx=temp; t = tx/340 + 36.53; //tf = (t * 9/5) + 32; // farenhait //read gyro data AcX=(Wire.read()<<8|Wire.read()) + AcXoff; AcY=(Wire.read()<<8|Wire.read()) + AcYoff; AcZ=(Wire.read()<<8|Wire.read()) + AcYoff; //get pitch/roll getAngle(GyX,GyY,GyZ); Also I need change input to function to input Gy as values to pitch, because data is sensed from module in opposite to what this tutorial show. Now I have accurate data. Problem is whit this module, that Gyroscope don't have Z axis. There is only X and Y, and for my needs I need Z axis more then that X and Y for my project. Now I need think if I need use magnetic earth module to display Z rotation

Image
Image

Gallax

4 years ago

Crazy question, but did you have the username cratos333 ever? I used to get codes from a guy

Image
Image

Anonymous user

4 years ago

I'm surprised that it doesnt give any errors but it doesnt give me any good values. It just tells me the same values all the time. Can you explain that how i could fix this?

Image
Image

Anonymous user

5 years ago

So the values I get are very inconsistent, when it is not moving at all it has a difference to the prvious one of up to 160. Can I somehow make this more accurate?

Image
Image

Anonymous user

6 years ago

How do you change the accelerometer scale in the code? It seems like it is automatically set to +/-2g and I see no way of changing it.

Image
Image

Adarsh2401

6 years ago

How can I restrict the gyroscope to show reading in only one axis (y- axis)

Image
Image

Anonymous user

2 years ago

You could just delete the serial.println of x and z in the code and it would only display y

Image
Image

johnbchron

6 years ago

Great project! You might want to use functions tho to make your code more reusable.

Image
Image

Anonymous user

6 years ago

The z-axis of accelerometer of MPU6050 is not providing any range of values as the x and y axes, the z-axis readings just flicker upon tilting in the z-axis direction. How do I resolve this problem? I need the z-axis readings to vary as I tilt the device in z-axis direction.

Image
Image

Anonymous user

2 years ago

I have this same problem. And also Gyroscope in my module is displayed first, then accelerometer

Image
Image

Anonymous user

6 years ago

I got error when i compile your code with Arduino Due 'call of overloaded 'beginTransmission(MPU_Type*)' is ambiguous'

Image
Image

Anonymous user

6 years ago

Is there a way to connect, say, 7 of them to one arduino and get result values separately but fast enough that they are essentially at the same time, I guess what I am asking is, is there a way to change the i2c device id?

Image
Image

Anonymous user

2 years ago

No, not without some sort of I2C multiplexer. The I2C device address can be set on the MPU-60X0 parts, but only the least significant bit, meaning you can only have two devices on the bus at the one time (with having it's ADO pin pulled high, and the other having it's ADO pin pulled low).

Image
Image

iFrostizz67

7 years ago

Thanks a lot ! It will help me a lot for a project !! :)

Image
Image

Anonymous user

7 years ago

The code has an error in it.. The data being recalled has a temperature reading between the accel and the gyro data. This code fixes it and it also 1. converts the accel data to roll and pitch angles. 2. calculates the temperature in F and C 3. adds correction values for the accel and temp data. ====================== #include<Wire.h> #include <math.h> const int MPU=0x68; int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; double pitch,roll; void setup(){ Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(9600); } void loop(){ Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU,14,true); int AcXoff,AcYoff,AcZoff,GyXoff,GyYoff,GyZoff; int temp,toff; double t,tx,tf; //Acceleration data correction AcXoff = -950; AcYoff = -300; AcZoff = 0; //Temperature correction toff = -1600; //Gyro correction GyXoff = 480; GyYoff = 170; GyZoff = 210; //read accel data AcX=(Wire.read()<<8|Wire.read()) + AcXoff; AcY=(Wire.read()<<8|Wire.read()) + AcYoff; AcZ=(Wire.read()<<8|Wire.read()) + AcYoff; //read temperature data temp=(Wire.read()<<8|Wire.read()) + toff; tx=temp; t = tx/340 + 36.53; tf = (t * 9/5) + 32; //read gyro data GyX=(Wire.read()<<8|Wire.read()) + GyXoff; GyY=(Wire.read()<<8|Wire.read()) + GyYoff; GyZ=(Wire.read()<<8|Wire.read()) + GyZoff; //get pitch/roll getAngle(AcX,AcY,AcZ); //send the data out the serial port Serial.print("Angle: "); Serial.print("Pitch = "); Serial.print(pitch); Serial.print(" | Roll = "); Serial.println(roll); Serial.print("Temp: "); Serial.print("Temp(F) = "); Serial.print(tf); Serial.print(" | Temp(C) = "); Serial.println(t); Serial.print("Accelerometer: "); Serial.print("X = "); Serial.print(AcX); Serial.print(" | Y = "); Serial.print(AcY); Serial.print(" | Z = "); Serial.println(AcZ); Serial.print("Gyroscope: "); Serial.print("X = "); Serial.print(GyX); Serial.print(" | Y = "); Serial.print(GyY); Serial.print(" | Z = "); Serial.println(GyZ); Serial.println(" "); delay(333); } //convert the accel data to pitch/roll void getAngle(int Vx,int Vy,int Vz) { double x = Vx; double y = Vy; double z = Vz; pitch = atan(x/sqrt((y*y) + (z*z))); roll = atan(y/sqrt((x*x) + (z*z))); //convert radians into degrees pitch = pitch * (180.0/3.14); roll = roll * (180.0/3.14) ; }

Image
Image

Anonymous user

2 years ago

can i get library of wire & math .

Image
Image

cyber2024

2 years ago

Nice work mate. Not to nitpick, but you have added AcYoff incorrectly to the AcZ calc. >AcZ=(Wire.read()<<8|Wire.read()) + AcYoff; I'm using your code to help me reduce latency, the adafruit library takes 6ms to read data, this is getting down to around 1ms which is how frequently I need to update my steppers. Thanks!

Image
Image

Anonymous user

7 years ago

Very good illustration, i have couple of questions please reply 1) please explain line 8,9 and 15 in the code? why wire.write 0x6B, 0 and 0x3B to MPU? 2) how do you know first requested 6 bytes are for acc and next 6 for gyro, how one can know, i explore google but could not find datasheet of Gy521.

Image
Image

Anonymous user

2 years ago

Datasheet you're after is for the MPU-6050, not the GY521 ;) If you look up the "MPU-6050 Register Map and Register Descriptions document" you'll find the register list you're looking for. When you request 6 bytes from register 0x3B/59 onwards, you get the MSB and LSB for AccX, AccY and AccZ, followed by two bytes for temperature, and then another six bytes for the gyro. The code should have either requested 14 bytes instead of 12, and also either displayed or dealt with the temperature, or read six bytes, and then another six bytes from 0x43/67 onwards. As far as what the other lines do, I believe 8 &9 enable the internal 8MHz oscillator, basically so that the MPU becomes accessible. I'm not sure why it's needed, as it should default to this on power up. Maybe some other required startup step is being skipped, and this is a workaround, or isn't actually needed.

Image
Image

Anonymous user

7 years ago

So a quick question, i'm very new to programming and using Arduino first off. If i'd like to change the pin out from: SCL -> A5 SDA -> A4 to: SCL -> A3 SDA-> A2 What part of the code would I need to change? This is for a school project. Any help would be appreciated, Thank you very much. Cheers!

Image
Image

Nicholas_N

2 years ago

SCL and SDA must be connected to A5 and A4 otherwise it will not work.

Image
Image

kgray9

2 years ago

SDA and SCL can also be connected to the topmost pins on the digital side of an Arduino Uno. They're usually labeled on the bottom.

Image
Image

Anonymous user

8 years ago

What is the reason for the bit shift and is that an ORing? in the lines like: AcX=Wire.read()<<8|Wire.read();

Image
Image

Nicholas_N

2 years ago

That line reads two registers. With two registers we have one variable.