Buenos días amigos técnologos, en nuestra entrada de hoy hablaremos de uno de los acelerómetros/giróscopos más usados del mercado, el MPU6050. Este es el acelerómetro giróscopo más usado para robots balancines, gimbal, drones…
En las prácticas que propondremos en nuestro tutorial, veremos como captar los datos brutos del sensor y posteriormente estos datos los convertiremos en ángulos que usaremos en nuestra programación.
Material necesario
![]() | Arduino UNO R3 |
![]() | MPU 6050 |
![]() | Cables |
Conozcamos el MPU6050
El MPU6050 es un sensor de movimiento el cual es capaz de medir la aceleración y el giro en los tres ejes del movimiento (x,y,z) con una precisión bastante considerable.
El MPU6050, tiene un conversor ADC de 16 bits, este conversor, convierte los datos a un valor digital y envía dichos datos a Arduino mediante I2C.
Prácticas propuestas
Para entender mejor el funcionamiento de sensor, vamos a realizar dos prácticas; en la primera, representaremos por el monitor serial de Arduino los valores brutos recogidos por el acelerómetro y el giróscopo. En la segunda convertiremos estos valores en ángulos.
Pero antes tenemos que hacer las conexiones pertinentes:
Esquema de conexión

Código
En esta práctica tenemos dos códigos, el codígo 1 representa los valores brutos recogidos por el MPU, el código dos representa por el monitor serial los ángulos.
Código 1
//Incluimos la librería para I2C #include <Wire.h> //Definimos la direccion I2C del MPU #define MPU 0x68 //Definimos los ratios de conversión #define A_R 16384.0 #define G_R 131.0 //Definimos la conversion de radianes a grados 180/PI #define RAD_A_DEG = 57.295779 //El MPU da los valores en enteros de 16 bits //Declaramos memorias para los valores brutos int16_t AcX; int16_t AcY; int16_t AcZ; int16_t GyX; int16_t GyY; int16_t GyZ; //Declaramos cadena de caracteres para los ángulos float Acc[2]; float Gy[2]; float Angle[2]; void setup() { //Inicializamos el I2C y el puerto serie Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(9600); } void loop() { //Leemos los valores del Acelerometro Wire.beginTransmission(MPU); Wire.write(0x3B); //Pedimos el registro 0x3B - corresponde al AcX Wire.endTransmission(false); Wire.requestFrom(MPU,6,true); //A partir del 0x3B, se piden 6 registros AcX=Wire.read()<<8|Wire.read(); //Cada valor ocupa 2 registros AcY=Wire.read()<<8|Wire.read(); AcZ=Wire.read()<<8|Wire.read(); //Leemos los valores del Giroscopio Wire.beginTransmission(MPU); Wire.write(0x43); Wire.endTransmission(false); Wire.requestFrom(MPU,4,true); //A diferencia del Acelerometro, solo se piden 4 registros GyX=Wire.read()<<8|Wire.read(); GyY=Wire.read()<<8|Wire.read(); /Mostramos los valores por el monitor serial Serial.print("Acelerometro bruto X: "); Serial.println(AcX); Serial.print("Acelerometro bruto Y: "); Serial.println(AcY); Serial.print("Acelerometro bruto Z: "); Serial.println(AcZ); Serial.print("Giroscopo bruto Y: "); Serial.println(GyX); Serial.print("Giroscopo bruto X: "); Serial.println(GyY); Serial.print("Giroscopo bruto Y: "); Serial.println(GyZ); //Esperamos 1 segundo para poder visualizarlo en el monitor serial delay(1000); }
Pantallazo monitor serial

Código 2
//Incluimos la librería para I2C #include <Wire.h> //Definimos la direccion I2C del MPU #define MPU 0x68 //Definimos los ratios de conversión #define A_R 16384.0 #define G_R 131.0 //Definimos la conversion de radianes a grados 180/PI #define RAD_A_DEG = 57.295779 //El MPU da los valores en enteros de 16 bits //Declaramos memorias para los valores brutos int16_t AcX; int16_t AcY; int16_t AcZ; int16_t GyX; int16_t GyY; int16_t GyZ; //Declaramos cadena de caracteres para los ángulos float Acc[2]; float Gy[2]; float Angle[2]; void setup() { //Inicializamos el I2C y el puerto serie Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(9600); } void loop() { //Leemos los valores del Acelerometro Wire.beginTransmission(MPU); Wire.write(0x3B); //Pedimos el registro 0x3B - corresponde al AcX Wire.endTransmission(false); Wire.requestFrom(MPU,6,true); //A partir del 0x3B, se piden 6 registros AcX=Wire.read()<<8|Wire.read(); //Cada valor ocupa 2 registros AcY=Wire.read()<<8|Wire.read(); AcZ=Wire.read()<<8|Wire.read(); //Calculamos los angulos Y, X respectivamente. Acc[1] = atan(-1*(AcX/A_R)/sqrt(pow((AcY/A_R),2) + pow((AcZ/A_R),2)))*RAD_TO_DEG; Acc[0] = atan((AcY/A_R)/sqrt(pow((AcX/A_R),2) + pow((AcZ/A_R),2)))*RAD_TO_DEG; //Leemos los valores del Giroscopio Wire.beginTransmission(MPU); Wire.write(0x43); Wire.endTransmission(false); Wire.requestFrom(MPU,4,true); //A diferencia del Acelerometro, solo se piden 4 registros GyX=Wire.read()<<8|Wire.read(); GyY=Wire.read()<<8|Wire.read(); //Calculamos el angulo del Giroscopio Gy[0] = GyX/G_R; Gy[1] = GyY/G_R; //Aplicamos un Filtro Complementario Angle[0] = 0.98 *(Angle[0]+Gy[0]*0.010) + 0.02*Acc[0]; Angle[1] = 0.98 *(Angle[1]+Gy[1]*0.010) + 0.02*Acc[1]; //Mostramos los valores por el monitor serial Serial.print("Angle X: "); Serial.println(Angle[0]); Serial.print("Angle Y: "); Serial.println(Angle[1]); //Esperamos 1 segundo para poder visualizarlo en el monitor serial delay(1000); }
Pantallazo monitor serial





Hola,
Estoy realizando un proyecto en el cual necesito medir la inclinación de vehículos de cuatro y dos ruedas para saber cómo se comportan en curvas.
He realizado la programación con filtro complementario en una placa arduino nano y MPU6050.
En estático todo correcto, pero con el vehículo en marcha los ángulos medidos se ven afectados por las fuerzas propias de la aceleración del vehículo, frenadas o fuerzas centrífugas en curvas, cimo si de un péndulo se tratase, por lo tanto no mide la inclinación real del vehículo.
Alguna idea de lo que me puede estar ocurriendo?
Gracias.
Alex, antes de pasar el codigo debes subirle una pagina de codigo en blanco y luego subir este codigo, ya he probado con varios codigos similares con ese error y asi puedo usar yo. Mira este video esta de lujo y es muy intuitivo.
(https://www.youtube.com/watch?v=kyX9cRxJNdo)
(http://electricdiylab.com/mpu-6050-gyroscope-introduction-teapot-3d-simulation/)
Alex prueba con IDE 1.6.8, ami me resulto todo bien.
Me alegra ver que el código de mi tutorial sobre MPU-6050 (http://robologs.net/2014/10/15/tutorial-de-arduino-y-mpu-6050/) os ha servido para escribir el vuestro. Aunque se agradecería un poco de atribución.
Final de línea.
Que razon tienes, copia pega tremendo, que menos que citar la fuente…
Saludos Transductor. Final de la linea.