Haga clic para más productos.
No se encontraron productos.

Tutorial MPU6050, Acelerómetro y Giroscopio

509118

EL MPU6050 es una unidad de medición inercial o IMU (Inertial Measurment Units) de 6 grados de libertad (DoF) pues combina un acelerómetro de 3 ejes y un giroscopio de 3 ejes. Este sensor es muy utilizado en navegación, goniometría, estabilización, etc.

En este tutorial revisaremos los principios generales de acelerómetros y giroscopios, luego estudiaremos el sensor MPU6050 con mayor detalle y finalmente implementaremos ejemplos del MPU6050 con Arduino.

Aceleración y acelerómetros

La aceleración es la variación de la velocidad por unidad de tiempo es decir razón de cambio en la velocidad respecto al tiempo:

a=dV/dt

Así mismo la segunda ley de Newton indica que en un cuerpo con masa constante, la aceleración del cuerpo es proporcional a la fuerza que actúa sobre él mismo:

a=F/m

Este segundo concepto es utilizado por los acelerómetros para medir la aceleración. Los acelerómetros internamente tienen un MEMS(MicroElectroMechanical Systems) que de forma similar a un sistema masa resorte permite medir la aceleración.

                 MEMs acelerometro

Con un acelerómetro podemos medir esta aceleración, teniendo en cuenta que a pesar que no exista movimiento, siempre el acelerómetro estará sensando la aceleración de la gravedad.

Con el acelerómetro podemos hacer mediciones indirectas como por ejemplo si integramos la aceleración en el tiempo tenemos la velocidad y si la integramos nuevamente tenemos el desplazamiento, necesitando en ambos casos la velocidad y la posición inicial respectivamente.

 

Velocidad Angular y giroscopio

La velocidad angular es la tasa de cambio del desplazamiento angular por unidad de tiempo, es decir que tan rápido gira un cuerpo alrededor de su eje:

 velocidad angular

Los giroscopios utilizan un MEMS (MicroElectroMechanical Systems)  para medir la velocidad angular usando el efecto Coriolis   

Con un giroscopio podemos medir la velocidad angular, y si se integra la velocidad angular con respecto al tiempo se obtiene el desplazamiento angular (posición angular si se sabe dónde se inició el giro)

 

Módulo Acelerómetro y giroscopio MPU6050

Módulo MPU6050, Acelerómetro, Giroscopio I2C

EL módulo Acelerómetro MPU tiene un giroscopio de tres ejes con el que podemos medir velocidad angular y un acelerómetro también de 3 ejes con el que medimos los componentes X, Y y Z de la aceleración.

La dirección de los ejes está indicado en el módulo el cual hay que tener en cuenta para no equivocarnos en el signo de las aceleraciones.

 

 Ejes del MPU6050

 

La comunicación del módulo es por I2C, esto le permite trabajar con la mayoría de microcontroladores. Los pines SCL y SDA tienen una resistencia pull-up en placa para una conexión directa al microcontrolador o Arduino.

Tenemos dos direcciones I2C para poder trabajar:

Pin AD0

Dirección I2C

AD0=HIGH  (5V)

0x69

AD0=LOW  (GND o NC)

0x68

El pin ADDR internamente en el módulo tiene una resistencia a GND, por lo que si no se conecta, la dirección por defecto será 0x68.

El módulo tiene un regulador de voltaje en placa de 3.3V, el cual se puede alimentar con los 5V del Arduino.

 

Librería Para el PMU6050

En este tutorial trabajaremos con la librería desarrollada por Jeff Rowberg, la librería se descargar en:

https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

Esta librería trabaja con una librería adicional para la comunicación I2C:

https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/I2Cdev

Para trabajar los siguientes ejercicios es necesario instalar las librerías en el IDE Arduino.

 

Conexiones entre Arduino y el MPU6050

Las conexiones son del modo I2C estándar:

MPU6050

Arduino Uno, Nano, Mini

Arduino Mega, DUE

Arduino Leonardo

  VCC

5V

5V

5V

  GND

GND

GND

GND

  SCL

A5

21

3

  SDA

A4

20

2

 

Conexines MPU6050 y Arduino

Ej.1: Realizar mediciones del MPU6050:

En este ejemplo realizaremos lecturas tanto del acelerómetro como del giroscopio.

El sketch para este ejercicio:

// Librerias I2C para controlar el mpu6050
// la libreria MPU6050.h necesita I2Cdev.h, I2Cdev.h necesita Wire.h
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

// La dirección del MPU6050 puede ser 0x68 o 0x69, dependiendo 
// del estado de AD0. Si no se especifica, 0x68 estará implicito
MPU6050 sensor;

// Valores RAW (sin procesar) del acelerometro y giroscopio en los ejes x,y,z
int ax, ay, az;
int gx, gy, gz;

void setup() {
  Serial.begin(57600);    //Iniciando puerto serial
  Wire.begin();           //Iniciando I2C  
  sensor.initialize();    //Iniciando el sensor

  if (sensor.testConnection()) Serial.println("Sensor iniciado correctamente");
  else Serial.println("Error al iniciar el sensor");
}

void loop() {
  // Leer las aceleraciones y velocidades angulares
  sensor.getAcceleration(&ax, &ay, &az);
  sensor.getRotation(&gx, &gy, &gz);

  //Mostrar las lecturas separadas por un [tab]
  Serial.print("a[x y z] g[x y z]:\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);

  delay(100);
}

Repasemos las funciones de la librería utilizada en este ejercicio.

Inicialmente como se indico es necesario incluir las siguientes 3 librerías

#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

Posteriormente crear la variable u objeto para el MPU6050, que en nuestro caso tiene el nombre de: “sensor”

MPU6050 sensor;

En este caso la dirección I2c es 0x68, pero si deseamos trabajar con otra dirección debemos modificar la linea anterior:

MPU6050 sensor(0x69);

Posteriormente en el void loop() inicializamos tanto la comunicación I2C como el MPU6050 y en nuestro caso la comunicación serial puesto que la usaremos más adelante:

  Serial.begin(57600);    //Iniciando puerto serial
  Wire.begin();           //Iniciando I2C  
  sensor.initialize();    //Iniciando el sensor

Al inicializar el sensor, los rangos por defecto serán:

- acelerómetro -2g a +2g

- giroscopio: -250°/sec a +250°/sec

Teniendo en cuenta que la resolución de las lecturas es de 16 bits por lo que el rango de lectura es de -32768 a 32767.

En el void loop() realizamos las lecturas y las guardamos en sus variables respectivas, esto se hace con las siguientes funciones:

  sensor.getAcceleration(&ax, &ay, &az);
  sensor.getRotation(&gx, &gy, &gz);


La primera función lee la aceleración de los componentes x-y-z como parámetro, es necesario dar la dirección de las variables como argumento, para lo que se usa: &variable.

La segunda función realiza la lectura de la velocidad angular y guarda las lecturas en sus respectivas variables.

Finalmente enviamos por el puerto serial los datos leídos.

Si ubicamos el sensor en posición horizontal obtendremos medidas similares a los que mostramos a continuación.

Lecturas del MPU6050

  

Conforme movamos el sensor los componentes de aceleración irán cambiando en función del ángulo del sensor, puesto que la gravedad siempre es paralela al eje "Z" y se descompondrá en las componentes x-y-z del sensor.

  

Ej.2: Calibrando nuestro MPU6050

En este ejemplo realizaremos la calibración del MPU6050, esto es necesario ya que el sensor MPU6050 probablemente no se encuentre 100% en una posición horizontal, esto debido a que el sensor al ser soldado en el módulo puede estar desnivelado agregando un error en cada componente. De igual forma cuando instalemos el módulo en nuestro proyecto, puede estar desnivelado a pesar que a simple vista lo notemos correctamente nivelado.

Para solucionar este problema, se puede configurar en el módulo MPU6050 OFFSETS y de esta forma compensar los errores que podamos tener.


El sketch para realizar la calibración es el siguiente:

// Librerias I2C para controlar el mpu6050
// la libreria MPU6050.h necesita I2Cdev.h, I2Cdev.h necesita Wire.h
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

// La dirección del MPU6050 puede ser 0x68 o 0x69, dependiendo 
// del estado de AD0. Si no se especifica, 0x68 estará implicito
MPU6050 sensor;

// Valores RAW (sin procesar) del acelerometro y giroscopio en los ejes x,y,z
int ax, ay, az;
int gx, gy, gz;

//Variables usadas por el filtro pasa bajos
long f_ax,f_ay, f_az;
int p_ax, p_ay, p_az;
long f_gx,f_gy, f_gz;
int p_gx, p_gy, p_gz;
int counter=0;

//Valor de los offsets
int ax_o,ay_o,az_o;
int gx_o,gy_o,gz_o;

void setup() {
  Serial.begin(57600);   //Iniciando puerto serial
  Wire.begin();           //Iniciando I2C  
  sensor.initialize();    //Iniciando el sensor

  if (sensor.testConnection()) Serial.println("Sensor iniciado correctamente");

  // Leer los offset los offsets anteriores
  ax_o=sensor.getXAccelOffset();
  ay_o=sensor.getYAccelOffset();
  az_o=sensor.getZAccelOffset();
  gx_o=sensor.getXGyroOffset();
  gy_o=sensor.getYGyroOffset();
  gz_o=sensor.getZGyroOffset();
  
  Serial.println("Offsets:");
  Serial.print(ax_o); Serial.print("\t"); 
  Serial.print(ay_o); Serial.print("\t"); 
  Serial.print(az_o); Serial.print("\t"); 
  Serial.print(gx_o); Serial.print("\t"); 
  Serial.print(gy_o); Serial.print("\t");
  Serial.print(gz_o); Serial.print("\t");
  Serial.println("nnEnvie cualquier caracter para empezar la calibracionnn");  
  // Espera un caracter para empezar a calibrar
  while (true){if (Serial.available()) break;}  
  Serial.println("Calibrando, no mover IMU");  
  
}

void loop() {
  // Leer las aceleraciones y velocidades angulares
  sensor.getAcceleration(&ax, &ay, &az);
  sensor.getRotation(&gx, &gy, &gz);

  // Filtrar las lecturas
  f_ax = f_ax-(f_ax>>5)+ax;
  p_ax = f_ax>>5;

  f_ay = f_ay-(f_ay>>5)+ay;
  p_ay = f_ay>>5;

  f_az = f_az-(f_az>>5)+az;
  p_az = f_az>>5;

  f_gx = f_gx-(f_gx>>3)+gx;
  p_gx = f_gx>>3;

  f_gy = f_gy-(f_gy>>3)+gy;
  p_gy = f_gy>>3;

  f_gz = f_gz-(f_gz>>3)+gz;
  p_gz = f_gz>>3;

  //Cada 100 lecturas corregir el offset
  if (counter==100){
    //Mostrar las lecturas separadas por un [tab]
    Serial.print("promedio:"); Serial.print("t");
    Serial.print(p_ax); Serial.print("\t");
    Serial.print(p_ay); Serial.print("\t");
    Serial.print(p_az); Serial.print("\t");
    Serial.print(p_gx); Serial.print("\t");
    Serial.print(p_gy); Serial.print("\t");
    Serial.println(p_gz);

    //Calibrar el acelerometro a 1g en el eje z (ajustar el offset)
    if (p_ax>0) ax_o--;
    else {ax_o++;}
    if (p_ay>0) ay_o--;
    else {ay_o++;}
    if (p_az-16384>0) az_o--;
    else {az_o++;}
    
    sensor.setXAccelOffset(ax_o);
    sensor.setYAccelOffset(ay_o);
    sensor.setZAccelOffset(az_o);

    //Calibrar el giroscopio a 0º/s en todos los ejes (ajustar el offset)
    if (p_gx>0) gx_o--;
    else {gx_o++;}
    if (p_gy>0) gy_o--;
    else {gy_o++;}
    if (p_gz>0) gz_o--;
    else {gz_o++;}
    
    sensor.setXGyroOffset(gx_o);
    sensor.setYGyroOffset(gy_o);
    sensor.setZGyroOffset(gz_o);    

    counter=0;
  }
  counter++;
}


El programa básicamente está modificando constantemente los offset intentando eliminar el error con la medida real que deseamos, en esta caso ax=0,ay=0,az=1g y gx=0,gy=0,gz=0.

Inicialmente leemos los offsets actuales y esperamos que el usuario envía un carácter por el puerto serie.
Antes de enviar el carácter es necesario ubicar el sensor en posición horizontal y evitar moverlo durante la calibración, dicha posición será nuestro nivel para futuras mediciones.

Después de enviar el carácter el programa realiza las lecturas tanto del acelerómetro como del giroscopio, usando un filtro estabilizamos un poco las lecturas y cada 100 lecturas comprobamos si los valores son cercanos a los valores que deseamos leer, dependiendo de esto se aumenta o disminuye los offsets. Esto hará que las lecturas filtradas converjan a:

-aceleración: p_ax=0 , p_ay=0 , p_az=+16384

-Velocidad angular: p_gx=0 , p_gy=0 , p_gz=0

Cuando en el monitor serial se observen valores cercanos a los anteriores debemos desconectar o reiniciar nuestro Arduino. Con esto el MPU6050 quedará configurado con el último offset calculado en el programa de calibración.

A continuación mostramos la salida del monitor serial después de enviar el carácter y esperar que los valores se acerquen a: 0 0 +16384 0 0 0 

 Calibracion MPU6050

  

Cuando tengamos estos valores debemos reiniciar el Arduino o simplemente cerrar y abrir el monitor serial. Posteriormente podemos volver a cargar el primer ejemplo para probar las lecturas con los nuevos offsets.

 

Ej.3: Escalado de lecturas

En este ejemplo vamos a escalar las lecturas a valores con las unidades de aceleración y velocidad angular.

Primero tenemos que saber los rangos con los que está configurado nuestro MPU6050, dichos rangos pueden ser 2g/4g/8g/16g para el acelerómetro y 250/500/1000/2000(°/s) para el giroscopio.

Para este ejemplo trabajaremos con los rangos por defecto (2g y 250°/s):

Variable

valor mínimo

valor central

valor máximo

Lectura MPU6050

-32768

0

+32767

Aceleración

-2g

0g

+2g

Velocidad angular

-250°/s

0°/s

+250°/s

Para escalar simplemente debemos usar una ecuación para convertir el valor leído en un valor de aceleración o velocidad angular.

A continuación se muestra el sketch con la ecuación correspondiente para escalar los valores:

// Librerias I2C para controlar el mpu6050
// la libreria MPU6050.h necesita I2Cdev.h, I2Cdev.h necesita Wire.h
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

// La dirección del MPU6050 puede ser 0x68 o 0x69, dependiendo 
// del estado de AD0. Si no se especifica, 0x68 estará implicito
MPU6050 sensor;

// Valores RAW (sin procesar) del acelerometro y giroscopio en los ejes x,y,z
int ax, ay, az;
int gx, gy, gz;

void setup() {
  Serial.begin(57600);    //Iniciando puerto serial
  Wire.begin();           //Iniciando I2C  
  sensor.initialize();    //Iniciando el sensor

  if (sensor.testConnection()) Serial.println("Sensor iniciado correctamente");
  else Serial.println("Error al iniciar el sensor");
}

void loop() {
  // Leer las aceleraciones y velocidades angulares
  sensor.getAcceleration(&ax, &ay, &az);
  sensor.getRotation(&gx, &gy, &gz);
  float ax_m_s2 = ax * (9.81/16384.0);
  float ay_m_s2 = ay * (9.81/16384.0);
  float az_m_s2 = az * (9.81/16384.0);
  float gx_deg_s = gx * (250.0/32768.0);
  float gy_deg_s = gy * (250.0/32768.0);
  float gz_deg_s = gz * (250.0/32768.0);
  //Mostrar las lecturas separadas por un [tab]
  Serial.print("a[x y z](m/s2) g[x y z](deg/s):\t");
  Serial.print(ax_m_s2); Serial.print("\t");
  Serial.print(ay_m_s2); Serial.print("\t");
  Serial.print(az_m_s2); Serial.print("\t");
  Serial.print(gx_deg_s); Serial.print("\t");
  Serial.print(gy_deg_s); Serial.print("\t");
  Serial.println(gz_deg_s);

  delay(100);
}
 

Los valores que tenemos ahora ya están escalados a unidades de aceleración y velocidad angular. En nuestro caso hemos convertido la aceleración a valores en m/s^2 por lo que se reemplazó el valor de g=9.81, si se desea trabajar en unidades "g" no es necesario este último paso.

Si el sensor está en posición horizontal se debe obtener mediciones cercanas a 9.8 m/s^2 (aceleración de la gravedad terrestre) en la componente z de la aceleración.

 MPU6050 escalado

 

 

Ej.4: Calculando el ángulo de inclinación con el acelerómetro del MPU6050

Si tenemos en cuenta que la única fuerza que actúa sobre el sensor es la fuerza de la gravedad. Entonces los valores que obtenemos en las componentes del acelerómetro corresponden a la gravedad y los ángulos de la resultante serán la inclinación del plano del sensor, puesto que la gravedad siempre es vertical.

Para entenderlo mejor, asumiremos que estamos en un plano X-Z e inclinamos el MPU6050 un ángulo θ, dicho ángulo se calcula de la siguiente forma:

angulo de inclinacion 2D
 
Lo anterior nos sirve para calcular el ángulo en un plano 2D, pero para calcular los ángulos de inclinación en un espacio 3D tanto en X como en Y usamos las siguientes formulas:

 ecuacion angulo inclinacion 3D

 

Tener en cuenta que estamos calculando el ángulo de inclinación, si deseáramos el ángulo de rotación es decir por ejemplo el ángulo que rota el eje x en su mismo eje, entonces en las formulas necesitamos cambiar el ay por el ax y viceversa.

El sketch para calcular los ángulos de inclinación es el siguiente:

// Librerias I2C para controlar el mpu6050
// la libreria MPU6050.h necesita I2Cdev.h, I2Cdev.h necesita Wire.h
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

// La dirección del MPU6050 puede ser 0x68 o 0x69, dependiendo 
// del estado de AD0. Si no se especifica, 0x68 estará implicito
MPU6050 sensor;

// Valores RAW (sin procesar) del acelerometro  en los ejes x,y,z
int ax, ay, az;

void setup() {
  Serial.begin(57600);    //Iniciando puerto serial
  Wire.begin();           //Iniciando I2C  
  sensor.initialize();    //Iniciando el sensor

  if (sensor.testConnection()) Serial.println("Sensor iniciado correctamente");
  else Serial.println("Error al iniciar el sensor");
}

void loop() {
  // Leer las aceleraciones 
  sensor.getAcceleration(&ax, &ay, &az);
  //Calcular los angulos de inclinacion:
  float accel_ang_x=atan(ax/sqrt(pow(ay,2) + pow(az,2)))*(180.0/3.14);
  float accel_ang_y=atan(ay/sqrt(pow(ax,2) + pow(az,2)))*(180.0/3.14);
  //Mostrar los angulos separadas por un [tab]
  Serial.print("Inclinacion en X: ");
  Serial.print(accel_ang_x); 
  Serial.print("tInclinacion en Y:");
  Serial.println(accel_ang_y);
  delay(10);
}

 

A continuación mostramos los resultados al tener inclinado el MPU6050 aproximadamente 45° con respecto a X:

angulo con acelerometro MPU6050

 

Esto funciona solo si la única aceleración presente es la gravedad, pero si movemos rápidamente el MPU y sin realizar ninguna inclinación el ángulo que obtenemos con el programa anterior varía, generándonos errores para estos casos.

 

Ej.5: Calculando el ángulo de rotación usando el giroscopio del MPU5060


Como se explicó al inicio el giroscopio nos entrega la velocidad angular, y para calcular el ángulo actual necesitamos integrar la velocidad y conocer el ángulo incial. Esto lo hacemos usando la siguiente formula:

ecuacion de derivada giroscopio MPU6050

Tener en cuenta que cuando nos referimos a θx nos referimos al ángulo que gira el eje X sobre su propio eje. En la siguiente imagen se observa que la velocidad angular es perpendicular al plano de rotación.

rotacion MPU

 

Para calcular los ángulos de rotación tanto en el eje X como en Y usamos el siguiente sketch:

// Librerias I2C para controlar el mpu6050
// la libreria MPU6050.h necesita I2Cdev.h, I2Cdev.h necesita Wire.h
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

// La dirección del MPU6050 puede ser 0x68 o 0x69, dependiendo 
// del estado de AD0. Si no se especifica, 0x68 estará implicito
MPU6050 sensor;

// Valores RAW (sin procesar) del acelerometro y giroscopio en los ejes x,y,z
int gx, gy, gz;

long tiempo_prev, dt;
float girosc_ang_x, girosc_ang_y;
float girosc_ang_x_prev, girosc_ang_y_prev;

void setup() {
  Serial.begin(57600);    //Iniciando puerto serial
  Wire.begin();           //Iniciando I2C  
  sensor.initialize();    //Iniciando el sensor

  if (sensor.testConnection()) Serial.println("Sensor iniciado correctamente");
  else Serial.println("Error al iniciar el sensor");
  tiempo_prev=millis();
}



void loop() {
  // Leer las velocidades angulares 
  sensor.getRotation(&gx, &gy, &gz);
  
  //Calcular los angulos rotacion:
  
  dt = millis()-tiempo_prev;
  tiempo_prev=millis();
  
  girosc_ang_x = (gx/131)*dt/1000.0 + girosc_ang_x_prev;
  girosc_ang_y = (gy/131)*dt/1000.0 + girosc_ang_y_prev;

  girosc_ang_x_prev=girosc_ang_x;
  girosc_ang_y_prev=girosc_ang_y;

  //Mostrar los angulos separadas por un [tab]
  Serial.print("Rotacion en X:  ");
  Serial.print(girosc_ang_x); 
  Serial.print("tRotacion en Y: ");
  Serial.println(girosc_ang_y);

  delay(100);
}
 

Con este programa al girar aumentará o disminuirá el ángulo en función del sentido de giro del MPU

angulo rotacion giroscopio MPU6050

 

Tomar nota que la medida no es exacta incluso cuando no se mueve, el ángulo varía, o si se gira cierto ángulo y luego se regresa a la posición original el ángulo que medimos no es el inicial, esto se debe a que al integrar la velocidad angular y sumar el ángulo inicial hay un error producto de la mala medición del tiempo o del ruido en la lectura del MPU, el error por más pequeño que sea, se va acumulando en cada iteración y creciendo, este error es conocido como DRIFT.

Para disminuir el drift existen varios métodos, la mayoria aplica filtros para eliminar el ruido de las lecturas del sensor. También se pueden usar otros sensores como magnetómetros o acelerómetros y con los ángulos calculados con estos mejorar el cálculo del giroscopio.

Uno de los mejores filtros para eliminar el drift es el filtro Kalman, pero se necesita una buena capacidad de procesamiento computacional, haciéndolo difícil implementar en Arduino.

Otro filtro muy usado es el filtro de complemento, que mostramos a continuación:

 

Ej.6: Implementando un filtro de Complemento: acelerómetro + giroscopio

El filtro de complemento o en inglés "Complementary Filter" es uno de los más usados por su fácil implementación, combina el ángulo calculado por el giroscopio  y el ángulo calculado por el acelerómetro.

La necesidad de combinar ambas lecturas es que si solo trabajámos con el acelerómetro, este es susceptible a las aceleraciones producto del movimiento del MPU o a fuerzas externas, pero en tiempos largos el ángulo no acumula errores. A diferencia que si trabajamos solo con el giroscopio si bien este no es susceptible a fuerzas externas, con el tiempo el drift es muy grande y nos sirve solo para mediciones de tiempos cortos.

La ecuación para calcular el ángulo usando el filtro de complemento es: 

ecuacion filtro de complemento

De esta forma el ángulo del acelerómetro  está pasando por un filtro pasa bajos, amortiguando las variaciones bruscas de aceleración; y el ángulo calculado por el giroscopio tiene un filtro pasa altos teniendo gran influencia cuando hay rotaciones rápidas. Podemos probar también con otros valores diferentes a 0.98 y 0.02 pero siempre deben de sumar 1.

a continuación mostramos el sketch para realizar esta tarea:

// Librerias I2C para controlar el mpu6050
// la libreria MPU6050.h necesita I2Cdev.h, I2Cdev.h necesita Wire.h
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

// La dirección del MPU6050 puede ser 0x68 o 0x69, dependiendo 
// del estado de AD0. Si no se especifica, 0x68 estará implicito
MPU6050 sensor;

// Valores RAW (sin procesar) del acelerometro y giroscopio en los ejes x,y,z
int ax, ay, az;
int gx, gy, gz;

long tiempo_prev;
float dt;
float ang_x, ang_y;
float ang_x_prev, ang_y_prev;

void setup() {
  Serial.begin(57600);    //Iniciando puerto serial
  Wire.begin();           //Iniciando I2C  
  sensor.initialize();    //Iniciando el sensor

  if (sensor.testConnection()) Serial.println("Sensor iniciado correctamente");
  else Serial.println("Error al iniciar el sensor");
}

void loop() {
  // Leer las aceleraciones y velocidades angulares
  sensor.getAcceleration(&ax, &ay, &az);
  sensor.getRotation(&gx, &gy, &gz);
  
  dt = (millis()-tiempo_prev)/1000.0;
  tiempo_prev=millis();
  
  //Calcular los ángulos con acelerometro
  float accel_ang_x=atan(ay/sqrt(pow(ax,2) + pow(az,2)))*(180.0/3.14);
  float accel_ang_y=atan(-ax/sqrt(pow(ay,2) + pow(az,2)))*(180.0/3.14);
  
  //Calcular angulo de rotación con giroscopio y filtro complemento  
  ang_x = 0.98*(ang_x_prev+(gx/131)*dt) + 0.02*accel_ang_x;
  ang_y = 0.98*(ang_y_prev+(gy/131)*dt) + 0.02*accel_ang_y;
  
  
  ang_x_prev=ang_x;
  ang_y_prev=ang_y;

  //Mostrar los angulos separadas por un [tab]

  Serial.print("Rotacion en X:  ");
  Serial.print(ang_x); 
  Serial.print("tRotacion en Y: ");
  Serial.println(ang_y);

  delay(10);
}

 

Ahora si movemos el MPU6050 rápidamente sin rotar, la variación del ángulo será mínima, además el drift se elimina y solo se nota en tiempos cortos.

Filtro complemento con MPU6050

 

Productos relacionados
Artículos relacionados
139 Comentarios
  • Gu******** ******* *****to

    Gu******** ******* *****to 16/06/2024 Responder

    Estuve investigando sobre la rotacion en el eje Z

    Al parecer no hay una forma fiable de calcularla con este sensor MPU6050, lo que entendi resumidamente es que para calcular la rotacion en el eje X y Y se utiliza la direccion de la gravedad como referencia para calcular los angulos, sin embargo el eje Z es paralelo a esta direccion, y al rotar no genera ningun angulo por lo que es imposible saber en que direccion esta apuntando el MPU, si bien se puede usar el acelerometro para calcular esta rotacion no se tiene algo de referencia para corregirla por lo que termina siendo impreciso
    Si quieren calcular la rotacion en Z pueden probar con el MPU9250 que tiene un magnetometro (brujula) el cual usa de referencia el campo magnetico para saber en que direccion se esta mirando, o podrian combinar el MPU6050 con un magnetometro como el Hmc5883l y asi calcular el eje X y Y con el MPU y el Z con el Hmc5883l, esto ultimo no lo probé pero se me ocurrio y segun estuve investigando se puede realizar
  • RO*****

    RO***** 12/06/2024 Responder

    hola, si vas a hacer un proyecto como dron o avión no uses el codigo 6 como referencia ya que no da buen resultado or que la lectura del angulo se mescla con el acelerometro, lo mejor que puedes hacer es usar eñ codigo 5 que solo es giroscopio, si tu proyecto se va a inclinar mas de 45° usa el codigo 6.
  • be**** *****on

    be**** *****on 12/03/2024 Responder

    muchas gracias, estos 6 ejemplos me sirvieron tanto para aprender a manejar algunos códigos de la librería I2Cdev y mas que todo las funciones del mpu6050, deberás muchas gracias y suerte en tus futuros proyectos.
  • di****

    di**** 13/02/2024 Responder

    Amigo Naylamp, buenas noches. mi sensor MPU despues de aplicar el primer ejemplo mostraba valores, despues de correr el segundo ejemplo ya solo muestra valor de 0 para las 6 mediciones, puedes informarme que es lo que ha sucedido, puede ayudarme a volver a restaurar el sensor MPU6050 como estaba inicialmente. gracias
  • Ma***** ****no

    Ma***** ****no 06/11/2023 Responder

    Excelente articulo...... pero agregaría una pequeña corrección que podría dar errores en algunas mediciones (a mi me a pasado para el diseño del control de un dron) ... y es que estas ecuaciones solo son ciertas en el caso de que el acelerómetro este en reposo o a velocidad constante (sistema inercial) .... ahora, si el dron en mi caso, como se mueve con aceleraciones hacia un lado u otro.... hay que hacer algunas correcciones (y usar lecturas del giróscopo, para determinar cambios de velocidad) ... de todos modos, me parece un excelente articulo y me sirvio muchisimo como punto de partida!!!1 se agradece la informacion.
  • Es***** **ce

    Es***** **ce 15/09/2023 Responder

    Muchas gracias, fueron de gran ayuda. Excelente artículo. Muy bien explicado
  • DA**** ******SI

    DA**** ******SI 06/06/2023 Responder

    Buen día estimado, y si lo coloco en un casco? para que se encienda la luz , cuando freno . Es posible? Gracias
  • Hé***** ******ez

    Hé***** ******ez 25/01/2023 Responder

    Extraordinario artículo. Desde la tierra del tequila (México), te mando un fuerte abrazo.
  • ma****

    ma**** 09/08/2022 Responder

    hola que tal , queria acerte una consulta, esoy usando el acelerometro en cuestion y anda perfecto pero cuando le sumo un modulo gps neo 6m , el progama se cuelga , lo mismo si uso solo gps , anda bien , solo engo problemas cuando andan juntos , has tenido una experiencia similar , sabrias que puede pasar ?
  • Fr*** *******es

    Fr*** *******es 02/06/2022 Responder

    Excelente articulo, me fue de grandísima ayuda, agradecido por compartir el conocimiento.
  • Au***** ******do

    Au***** ******do 12/12/2021 Responder

    Buenos días. Ante todo muchas gracias por el artículo, muy bien documentado. Estoy intentando calibrar el MPU6050 dentro de un módulo integrado GY-87. El acelerómetro me da las salidas esperadas, en torno a los valores 0 0 +16384, pero el giroscopio me da valores oscilantes. Por ejemplo: 1947 2321 -1991 // -1998 -1628 1952 // 1948 2331-1991... Al cabo de un tiempo los valores de offset, sin embargo, se estabilizan para ambos: 844 1233 1614 32 32 31

    ¿Puede estar el dispositivo estropeado? ¿O acaso está testando alguna vibración? Gracias por la ayuda.



  • Gu***** ***va

    Gu***** ***va 09/06/2021 Responder

    Buenos dias, ante todo gracias por este trabajo tan profesional, resume muchas paginas web.
    Tengo una inquietud, en el EJEMPLO 4 (ANGULO DE INCLINACION), por que motivo no se calcula la inclinacion en Z?

    //Calcular los angulos de inclinacion:
    float accel_ang_x=atan(ax/sqrt(pow(ay,2) + pow(az,2)))*(180.0/3.14);
    float accel_ang_y=atan(ay/sqrt(pow(ax,2) + pow(az,2)))*(180.0/3.14);
    //Mostrar los angulos separadas por un [tab]
  • Jo***

    Jo*** 06/06/2021 Responder

    Excelente tutorial , esta todo muy bien detallado y me sirve perfectamente para lo que necesito ! muchas gracias !
  • Pa****** *****io

    Pa****** *****io 13/01/2021 Responder

    Muchísimas gracias por este excelente tutorial. Todo el tema muy claramente explicado. Los programas funcionan perfectamente y realmente es sin ninguna duda el mejor tutorial que he encontrado en internet.He aprendido muchísimo y eso es invaluable para mi. Un abrazo.
  • jo*** ***ao

    jo*** ***ao 29/09/2020 Responder

    cordial saludo, tan amable podrías indicarme como implemento un programa, necesito sensar que estoy detenido y luego de sobrepasar 30 kph activar una salida, es que con todas esas medidas no se como empezar, gracias de antemano.
  • Lu** ******* ***yá

    Lu** ******* ***yá 12/08/2020 Responder

    Enhorabuena, creo que es el tutorial más claro sobre la IMU6050, se empieza por los valores en bruto, luego se calibra , luego se escala, se utiliza como acelerómetro, luego como rate gyro, y finalmente se aplica una "sensor fusion" con filtro complementario.

    Muchas gracias.

    Saludos

    Luis
  • Mi**** ***do

    Mi**** ***do 30/07/2020 Responder

    Excelente Articulo
  • Mi**** ***do

    Mi**** ***do 30/07/2020 Responder

    EXCELENTE Articulo
  • le******

    le****** 25/07/2020 Responder

    quiesieraayuda para realizar lo siguiente
    https://www.youtube.com/watch?v=0BDvbljP4Yk
    estoy a tu disposicion y muchas gracias
    leonardo
    1166960000
  • le******

    le****** 25/07/2020 Responder

    hola , tus tutoriales son de primera y es por eso que en esta oportunidad recurro a ti para vr si alguien colabora o me ayuda o me realiza el siguiente proyecto que me parece muy interesante .
    quiero realizar lo siguiente: https://www.youtube.com/watch?v=0BDvbljP4Yk
    Creo que es nada facil y mas para mi con poca esperiencia asi que veo que paso podemos dar.
    muchas gracias por tu tiempo
    leonardo
    1166960000
  • Ed**** ***on

    Ed**** ***on 12/06/2020 Responder

    Buenas Noches, me podrían colaborar con la librería I2cdev.h ya que el programa no me reconoce la que se encuentra en el link de arriba
  • Ye***********

    Ye*********** 23/04/2020 Responder

    Buenas Noches, Tengo una gran pregunta con respecto a "Ej.5: Calculando el ángulo de rotación usando el giroscopio del MPU5060" en la parte donde se dan a conocer las ecuaciones: "θx= θxο+ωx∆t" para conocer el ángulo actual. Mi pregunta es: ¿cómo se demuestra esta ecuación?
    Gracias.
  • Lu** ***ez

    Lu** ***ez 20/04/2020 Responder

    Hola, tengo algunas dudas del algoritmo que usan los acelerometros de los smartwatches para medir las variables de sueñoÑ inicio, fin e interrupciones del sueño. Es posible que me brindes un contacto ( e-mail telefono) de algun experto conocido para hacerle algunas preguntas. Estare muy reconocido y agradecido
    Muchas gracias por tu atencion
    Luis Perez
  • An*****

    An***** 02/04/2020 Responder

    Disculpa, pero no se si el acelerometro arroje una salida de respuesta ya que lo que necesitó que cuando sienta la aceleracion de 980 Gales arrojé una respuesta de activar un temporizador 555
  • Jo** ********

    Jo** ******** 14/11/2019 Responder

    Buenas amigo gracias lo que tengo es una duda como yo se la posicion en el espacio en la que estoy porque lo veo yo es que el sensor mide sobre si mismo y no si esta desplazado hacia la derecha o izquiera por ejemplo...
  • sa***

    sa*** 24/10/2019 Responder

    I have a problem with MPU6050 gyro sensors, I am making school project with Vehicle Accident GPS tracking. When the normal condition, eventhing is ok. Gyro is working his axis,but when over limit gyro's x,y,z values, LCD and Serial monitor is stop their process. how can i do that?
  • Ge***** ******** ******ño

    Ge***** ******** ******ño 03/10/2019 Responder

    Hola que tal. Oye que buen tutorial. Solo me queda preguntar: ¿Para calcular el ángulo de rotacion en el eje Z, se puede aplicar la misma fórmula?
    Saludos
    • Gu***** ***va

      Gu***** ***va 09/06/2021 Responder

      Estoy en las mismas pudiste resolver la inquietud?
      tienes la respuesta?
  • sa***

    sa*** 24/09/2019 Responder


    I am trying to interface the mpu 650 module to node mcu to calibrating the values for robot i am
    trying to useed the display the calibrating values (X-Y axis) please provide the code for node mcu.
    thankyou.
  • JA****

    JA**** 18/09/2019 Responder

    CUAL ES LA VELOCIDA MINIMA ANGULAR QUE PUEDE MEDIR VUESTRO GIROSCOPIO. Podría medir la velocidad angular del planeta tierra ?
  • Da****

    Da**** 19/08/2019 Responder

    Hola,
    Estoy realizando un proyecto donde necesito saber la inclinación de vehículos de cuatro y dos ruedas para conocer el comportamiento en curvas. He realizado la programación en Arduino con filtro complementario y sensor MPU6050, también he probado con el MPU9250 pero en ambos casos sí realiza la medición correcta de forma estática pero en movimiento se ve afectado por las aceleraciones y deceleraciones, así como con las fuerzas centrífugas al tomar las curvas, aportando datos inequívocamente erróneos.
    ¿Qué es lo que me falta? ¿Algún cálculo más? ¿No es el sensor correcto quizás?
    Gracias
    • Jo*** ****ía

      Jo*** ****ía 29/07/2022 Responder

      Lo que cuentas es normal que ocurra. Por eso hay que incluir correcciones al valor leído de los acelerómetros en función de la variación de velocidad en la dirección de avance dV/dt y en función de la fuerza centrifuga w x V, siendo w la velocidad angular.

      Haciendo pruebas a bordo de un barco pasando de cero a 20 nudos o realizando circulos de evolución se apreciaban desviaciones en las mediciones de una referncia vertical que no contaba con esas correcciones.

      Eso no ocurría en otro sistema más avanzado que calculaba dichas correcciones en base a los datos de rumbo y velocidad del barco. Además era tan fino que incluía una corrección por el movimiento de la tierra en función del dato de latitud y el rumbo del barco.

      Al no compensado hubo que hacerle correcciones aproximadas a las lecturas reales de balance y cabezada en vez de hacerlas internamente de forma más exacta.
      y roll en vez de hacerlas internamente
  • Fa*** *****do

    Fa*** *****do 12/08/2019 Responder

    Excelente artículo. Felicitaciones y gracias por compartir tu conocimiento.
  • Ed*** ****as

    Ed*** ****as 27/06/2019 Responder

    Buenas tardes, primero, gracias por el contenido, es de gran utilidad!, segundo, tengo un problema con el tiempo que dura leyendo los datos del girsocopio, el sistema funciona muy bien, pero en determinado momento deja de leer y las acelereaciones y los datos de rotacion se vuelven cero
  • Ro*****

    Ro***** 26/06/2019 Responder

    Buenas noches, mi tarea es modificar el codigo para que la respuesta estabilizadora sea más rapida, como es posible esto?
  • Be**

    Be** 04/06/2019 Responder

    Hola quisiera saber cómo puedo almacenar los datos leídos por el acelerómetro para procesarlos en matlab
  • K

    K 03/04/2019 Responder

    Buenas tengo el siguiente problema con la calibración:

    He copiado y pegado el código de calibración tal cual nos lo ofrece esta página y lo he volcado sin problema al arduino.

    Se realiza la calibración correctamente y los valores convergen a los deseados. Si pulso el boton de reiniciar arduino los valores de Offsets se quedan guardados.

    PERO si desconecto el cable USB dejando al arduino sin alimentación y lo vuelvo a conectar los valores de Offsets desaparecen.

    Todo esto sin mover el acelerometro ni un milímetro.

    Alguien podría ayudarme con esto??
    Estoy haciendo un trabajo académico y es de bastante importancia para mi que alguien me ayude a solucionarlo.
    Gracias.
  • He*****

    He***** 13/03/2019 Responder

    Tengo un proyecto donde solo requiero hacer uso del Acelerometro, puedo usar otro elemento diferente al MPU6050 con esta mismas codificaciones? gracias
  • Gu***** *****io

    Gu***** *****io 11/03/2019 Responder

    Como puedo descargar las librerias, alguien me puede ayudar?
  • ja****

    ja**** 18/02/2019 Responder

    Puede vuestro acelerómetro medir la aceleración del planeta tierra al pasar el perihelio en órbita de translación alrededor del Sol. Estamos hablando de que la tierra experimenta una aceleración de miles de kilómetros a la hora debido a la órbita elíptica. Un saludo, y gracias por contestar.
  • jo**

    jo** 27/11/2018 Responder

    Disculpa amigo realize todos los pasos, pero al parecer mis resultados finales son muy diferentes casi iguala x= 1, y= 1 y z=9.8, mientras que tus resultados son x e y =0 cuando z=9.8 , cres que se deba a que mi imu este fallando?
  • Ma***** ****ia

    Ma***** ****ia 20/11/2018 Responder

    Hola...cuando realiza el filtrado haciendo f_ax = f_ax-(f_ax>>5)+ax ; p_ax = f_ax>>5 ; se estaría calculando el promedio para 32 mediciones , ya que divide f_ax por 32..... pero estoy viendo que corrige el offset cada 100 mediciones usando p_ax , ....tendría q corregir el offset cada 32 mediciones y luego poner a cero p_ax, o me equivoco?
  • ja****

    ja**** 09/10/2018 Responder

    ¿Por qué un giroscopio no puede medir la velocidad angular del planeta tierra?
    • ja****

      ja**** 14/02/2019 Responder

      QUIZÁS SIMPLEMENTE PORQUE LA TIERRA NO SE MUEVE.
  • Ed*** ******es

    Ed*** ******es 08/10/2018 Responder

    Hola buenas noches tengo un problema con el primer ejemplo. Al abrir el monitor serial. Me dice "Error al iniciar el sensor"
  • To** **nx

    To** **nx 05/10/2018 Responder

    Hi.
    Thanks for the great article.
    With my little knowledge I am trying to load the Ej.6 with the arduino IDE in a Wemos D1 mini without positive result.
    If I compile with the option of the arduino, a traditional one does it without problems.
    The error that comes to me is:
    no matching function for call to 'MPU6050::getAcceleration(int*, int*, int*)'
    Could you help me know what to modify to adapt it to the Wemos D1 mini board?
    • To** **nx

      To** **nx 06/10/2018 Responder

      Perdonad mi confusion como suele usar el traductor web de google por inercia pensaba que esta web estaba en ingles.
      Me contesto yo mismo que he encontrado lo que me estaba ocurriendo.
      Al trabajar con la plca wemos he tenido que modificar estas lineas:
      int ax, ay, az;
      int gx, gy, gz;
      Wire.begin();
      Por lo siguiente:
      int16_t ax, ay, az;
      int16_t gx, gy, gz;
      Wire.begin(4,5);
      De nuevo, pido disculpa por mi confusion y gracias por toda la informacion que aqui se brinda.
  • Al**

    Al** 04/10/2018 Responder

    Hola, solo quería comentar que es un excelente tutorial. Yo estoy aplicando el sensor MPU6050 con una STM32F103 y solo tuve que realizar ciertas modificaciones del Wire. Muchísimas gracias!!!
  • Jo**

    Jo** 06/09/2018 Responder

    Hola.
    Gracias por esta magnífica explicación.
    Quisiera saber porque, para hallar el ángulo algunos autores emplean cuaterniones y el código aquí mostrado parece no usarlos.
    Gracias,
    JR
  • Ul****

    Ul**** 30/07/2018 Responder

    Hola. Este acelerometro me puede servir para hacer mediciones de vibraciones ambientales en estructuras de concreto o acero??
    Que tan confiables son las lecturas??
  • Xa****

    Xa**** 10/07/2018 Responder

    Excelente tutorial.

    Solamente te recomedaría NO usar variables globales indiscriminadamente. Las a's y las g's funcionan perfectamente como variables locales.

    Me permití modificar un poco el código de tu primer ejemplo:

    // Librerias I2C para controlar el mpu6050
    // la libreria MPU6050.h necesita I2Cdev.h, I2Cdev.h necesita Wire.h
    #include "I2Cdev.h"
    #include "MPU6050.h"
    #include "Wire.h"

    // La dirección del MPU6050 puede ser 0x68 o 0x69, dependiendo
    // del estado de AD0. Si no se especifica, 0x68 estará implicito
    MPU6050 sensor;

    bool connected{ false };

    void setup() {
    Serial.begin(57600); //Iniciando puerto serial
    Wire.begin(); //Iniciando I2C
    sensor.initialize(); //Iniciando el sensor

    if (sensor.testConnection()) {
    Serial.println("Sensor iniciado correctamente");
    connected = true;
    }
    else {
    Serial.println("Error al iniciar el sensor");
    connected = false;
    }
    }

    void loop() {
    if( connected ){
    int ax, ay, az; int gx, gy, gz;
    // two's complement (aka, signed int)
    // pp 29, https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf

    sensor.getAcceleration(&ax, &ay, &az);
    sensor.getRotation(&gx, &gy, &gz);

    Serial.print("a[x y z] r[x y z]: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);
    }
    else{
    Serial.println( "No sensor found!" );
    }
    delay(100);
    }
  • DA*** *******OS

    DA*** *******OS 21/06/2018 Responder

    ME SALE ERROR EN ESTAS LINEAS sensor.getAcceleration(&ax, &ay, &az);
    sensor.getRotation(&gx, &gy, &gz);
    • AN*****

      AN***** 20/06/2019 Responder

      Trata de verificar que está seleccionado en la plataforma el arduino que estás utilizando
      • Ar**** ***ez

        Ar**** ***ez 20/11/2019 Responder

        Tengo el mismo problema, ya verifiqué que tengo seleccionada la placa correcta, estoy usando un Arduino DUE.
      • Ar**** ****ez

        Ar**** ****ez 19/11/2019 Responder

        Hola!, tengo el mismo problema, ya verifiqué que sí tengo seleccionada mi placa arduino correctamente, estoy usando una tarjeta Arduino Due.
  • Ge***** *****to

    Ge***** *****to 21/04/2018 Responder

    Señores
    Naylamp Mechatronics
    Cordial saludo
    Muchas gracias por la información sobre el sensor MPU6050.
    ¿Qué intervalo de tiempo hay entre uno y otro paquete de datos con la información generada por el sensor?
    Si quiero salvar esta información en una memoria SD haciendo uso de un datalogger, ¿Cuál sería el intervalo de tiempo mínimo para hacerlo?
    En un datalogger la unidad de tiempo real va de segundo en segundo. ¿Cómo hago para conseguir registrar datos en intervalos menores a un segundo?
    Gracias
  • Th***

    Th*** 01/04/2018 Responder

    ¿cómo puedo utilizar de 0 a 180 grados en el eje x?
  • An*****

    An***** 15/03/2018 Responder

    Buenas, estoy interesado en conocer el ángulo de rotación en Z, ¿alguien sabría decirme como?
  • Vi*****

    Vi***** 23/02/2018 Responder

    Hola muy buen trabajo. Me ha servido de mucho y he podido entender y comprender gran parte de tus enseñanzas.
    Tengo una pregunta: Cuando he cargado el código y he abierto el serial ploter, puedo ver la evolución de los parámetros, sin embargo, el valor del eje Z, se desplaza con el tiempo y siempre crece de forma bastante rápida, es decir, en unos 15 segundos crece desde 0 hasta 50 (supongo que grados) en la escala de la izquierda. El desplazamiento lo puedo corregir girando el eje Z en el plano horizontal en el sentido del reloj. ?
    Me puedes indicar a que puede ser debido este desplazamiento.
    Gracias por todo.
  • Ra****

    Ra**** 03/12/2017 Responder

    Saludos Naylamp, primero que nada muchas gracias por el aporte, es muy útil y completo, excelente. Quisiera me puedas ayudar con mi consulta: Implementé el control del movimiento de un motor de pasos con el MPU de forma automática, cuando conecto el Arduino a la PC para poder ver en el monitor serial y hacer que funcione el proyecto todo va muy bien, pero cuando lo hago funcionar sin conectar a la PC, es decir conectando el Arduino desde una fuente continua, no arranca. He descartado una serie de posibles fallas llegando a que el MPU no le manda datos al Arduino a no ser que arranque el monitor serial. ¿Como puedo corregir esto?
  • yi****

    yi**** 26/11/2017 Responder

    Hola amigo, como podria yo aplicarle FFT a mis datos de aceleracion o como podria yo enviar mis datos a excel he usado estos pero no me sale.
    void setup(){

    // Configura captura de datos con Parallax_DAQ
    // Mostrará en Excel: Tiempo|ACC_X|ACC_Y|ACC_Z|GYRO_X|GYRO_Y|GYRO_Z|
    // ... | ... | ... | ... | ... | ... | ... |
    // ... | ... | ... | ... | ... | ... | ... |
    //
    Serial.println("CLEARDATA");
    Serial.println("LABEL, TIME, ACC_X,ACC_Y,ACC_Z,GYRO_X,GYRO_Y,GYRO_Z");

    }
    Parte incluida en el bucle continuo:
    void loop(){

    // Print the raw values.
    //
    Serial.print(F("DATA, TIME, "));
    Serial.print(acc_gyro.value.acc_x, DEC);
    Serial.print(F(", "));
    Serial.print(acc_gyro.value.acc_y, DEC);
    Serial.print(F(", "));
    Serial.print(acc_gyro.value.acc_z, DEC);
    Serial.print(F(", "));
    Serial.print(acc_gyro.value.gyro_x, DEC);
    Serial.print(F(", "));
    Serial.print(acc_gyro.value.gyro_y, DEC);
    Serial.print(F(", "));
    Serial.print(acc_gyro.value.gyro_z, DEC);
    Serial.println(F(", "));
    • An**** ***vo

      An**** ***vo 29/10/2018 Responder

      Hola Yilber. Ya solucionaste el problema? Trabajo en algo similar y podriamos colaborarnos.
  • ER****

    ER**** 21/11/2017 Responder

    Buenos días,
    primero de todo darte la gracias por este tutorial esta muy bien explicado.
    en segundo lugar quería comentarte mi error, bueno no es un error en si.
    a la hora de hacer la calibración del sensor, no he conseguido llegar a valores cercanos al 0 como tu dices, eso me hace que al hacer la conversión en el eje Z tenga una aceleración de 10-11 m/s2.

    tengo el sensor en horizontal y sujeto para que no se mueva.
    mi pregunta es : el tiempo del calibrado es muy extenso? o tendría que ver resultados cercanos al cero en pocos minutos?
    en caso de no obtenerlos que solución me recomendaría.

    muchas gracias.
  • El*** ****da

    El*** ****da 25/09/2017 Responder

    Hola, muy buen tutorial. Veo que as respondido varias preguntas y entregas tu tiempo en hacer eso (para todos los que opinan con sus respuestas tambien les va esto :v ) y me parece muy bueno de tu parte.
    Estoy siguiendo este tutorial y queria algo de orientacion ha mas de la que me brinda google en la implementacion de este modulo con arduino y un mini drone de 4 motores, mi pregunta es: ¿habria alguna funcion como la de los led (map:led) para poder realizar mi labor con los motores de un mini drone?
  • Da***

    Da*** 10/09/2017 Responder

    disculpa como puedo determinar el angulo de rotacion en Z??
    • An*****

      An***** 15/03/2018 Responder

      Buenas, yo tambien estoy interesado en conocer el ángulo de rotación enZ, ¿alguien sabría decirnos?
      • ne****

        ne**** 26/09/2018 Responder

        // Librerias I2C para controlar el mpu6050
        // la libreria MPU6050.h necesita I2Cdev.h, I2Cdev.h necesita Wire.h
        #include "I2Cdev.h"
        #include "MPU6050.h"
        #include "Wire.h"

        // La dirección del MPU6050 puede ser 0x68 o 0x69, dependiendo
        // del estado de AD0. Si no se especifica, 0x68 estará implicito
        MPU6050 sensor;

        // Valores RAW (sin procesar) del acelerometro y giroscopio en los ejes x,y,z
        int ax, ay, az;
        int gx, gy, gz;

        long tiempo_prev;
        float dt;
        float ang_x, ang_y, ang_z;
        float ang_x_prev, ang_y_prev, ang_z_prev;

        void setup() {
        Serial.begin(57600); //Iniciando puerto serial
        Wire.begin(); //Iniciando I2C
        sensor.initialize(); //Iniciando el sensor

        if (sensor.testConnection()) Serial.println("Sensor iniciado correctamente");
        else Serial.println("Error al iniciar el sensor");
        }

        void loop() {
        // Leer las aceleraciones y velocidades angulares
        sensor.getAcceleration(&ax, &ay, &az);
        sensor.getRotation(&gx, &gy, &gz);

        dt = (millis()-tiempo_prev)/1000.0;
        tiempo_prev=millis();

        //Calcular los ángulos con acelerometro
        float accel_ang_x=atan2(ay/sqrt(pow(ax,2) + pow(az,2)))*(180.0/3.14);
        float accel_ang_y=atan(-ax/sqrt(pow(ay,2) + pow(az,2)))*(180.0/3.14);
        float accel_ang_z=atan((sqrt(pow(ax,2)+pow(ay,2)))/az)*(180.0/3.14);
        //Calcular angulo de rotación con giroscopio y filtro complemento
        ang_x =( 0.98*(ang_x_prev+(gx/131)*dt) + 0.02*accel_ang_x);
        ang_y =( 0.98*(ang_y_prev+(gy/131)*dt) + 0.02*accel_ang_y);
        ang_z=(0.98*(ang_z_prev+(gz/131)*dt)+0.02*accel_ang_z);

        ang_x_prev=ang_x;
        ang_y_prev=ang_y;
        ang_z_prev=ang_z;

        //Mostrar los angulos separadas por un [tab]

        Serial.print("Rotacion en X: ");
        Serial.print(ang_x);
        Serial.print("tRotacion en Y: ");
        Serial.print(ang_y);
        Serial.print("tRotacion en z: ");
        Serial.println(ang_z);
        delay(200);
        }
  • An*****

    An***** 28/08/2017 Responder

    Excelente tutorial no tendrán alguno de armado de un Drone!!!
  • Je*** ****or

    Je*** ****or 13/08/2017 Responder

    Hola que tal, tengo una duda en cuanto al filtro utilizado, que es exactamente lo que hace?

    f_ax = f_ax-(f_ax>>5)+ax;
    p_ax = f_ax>>5;

    podrías explicar un poco?
    Gracias.
    • Na*****

      Na***** 29/08/2017 Responder

      Hola Jesus, El bitshift se usa en lugar de una división entre 2^n, por ejemplo: f_ax >>5 equivale a f_ax /32 , Las dos líneas que mencionas equivale a: p_ax = (f_ax-f_ax/32+ax)/32 esto es el promedio de 32 lecturas.
  • Al******

    Al****** 14/07/2017 Responder

    Amigos quisiera saber como leer la temperatura del sensor mpu6050
    • Na*****

      Na***** 29/07/2017 Responder

      Hola Luis, el módulo usado tiene un regulador de 3.3V
      Hola, para leer la temperatura usa: temp=sensor.getTemperature() el resultado es un int16 con al temperatura, si no logras obtener la temperatura agrega la siguiente línea en el setup: sensor.setTempSensorEnabled(true)
  • Ma*** ******no

    Ma*** ******no 26/06/2017 Responder

    Hola, quisiera saber que tengo que modificar para trabajar con el rango de 180 a -180

    Gracias y buen dia
  • ch*****

    ch***** 17/06/2017 Responder

    hola amigo, quisiera saber si se puede conectar el Acelerómetro directa a la computadora y usarlo desde la pc directamente
    • Na*****

      Na***** 23/06/2017 Responder

      Hola Charlie, no es posible, el modulo se comunica por I2C, necesitas un microcontrolador como por ejemplo un Arduino que tenga una interfaz USB para usarlo como intermediario entre la PC y el sensor.
  • Yi****

    Yi**** 12/06/2017 Responder

    Hola como hago para trabajar el MPU 6050 para medir fuerza g que sean mayores a 2g es decir necesito medir fuerzas g comprendidas entre 5 y 7 g
    • Na*****

      Na***** 23/06/2017 Responder

      Hola Yiber, Por defecto el rango es de +/-2g en tu caso tienes que cambiar el rango a +/-8g para configurar el rango del acelerómetro usa la función setFullScaleAccelRange(MPU6050_ACCEL_FS_8) después de inicializar el MPU.
      • An**** ***vo

        An**** ***vo 29/10/2018 Responder

        Hola Naylamp

        Obtengo un error cuando trato de setear el MPU de esa manera. Tambien quisiera saber en donde figuran todos los comandos de programacion para el sensor?

        ERROR:

        lectura_escalada_preliminar:21:3: error: 'mpu' was not declared in this scope

        mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_16);

        ^

        exit status 1
        'mpu' was not declared in this scope

        Gracias
  • Ce***

    Ce*** 20/05/2017 Responder

    Excelente explicación ... una consulta si utilizo las librerías para hacer un dispositivo tengo que tener derechos de autor ? ...
  • Br****

    Br**** 21/04/2017 Responder

    Porque en la parte de millis q es para calcular el dt lo divides entre 1000 si te da un valor en milisegundos xq lo divides entre 1000 que seria como si fuera microsegundos, no lo entiendo :(
    • Na*****

      Na***** 30/04/2017 Responder

      Hola Brayan, la división es para obtener un valor en segundos, por ejemplo 5000 ms lo dividimos entre 1000 nos da 5 segundos.
  • lu** *****es

    lu** *****es 16/04/2017 Responder

    excelente tu tutorial felicitaciones y gracias por tu esfuerzo.
    el tamaño del sensor increíble lo que hace.
  • Cr******

    Cr****** 11/04/2017 Responder

    Excelente tutorial, Felicitaciones!!
    Quería preguntar si es posible calcular el desplazamiento en los ejes x,y,z.
    Entiendo que el MPU tiene un centro de gravedad y respecto de él se calculan las inclinaciones ¿estoy en lo cierto?
    Ahora bien, quisiera poder calcular el desplazamiento de este centro de gravedad. Se me ocurre que podría tomar la velocidad lineal e integrarla dos veces para obtener la posición. Es posible calcular esta integral?
    Desde ya muchas gracias.
    Saludos!!
    • Na*****

      Na***** 30/04/2017 Responder

      Hola Cristina, sería similar a nuestro ejemplo 5, en donde a partir de la velocidad angular, integramos para obtener el desplazamiento angular. En tu caso tomarías la aceleración lineal, e integrarías dos veces para obtener el desplazamiento lineal. Integra de la misma forma que lo hacemos en el ejemplo 5. Pero al igual que mencionamos en el ejemplo, vas a tener un error con respecto a la posición inicial, error que se va a ir acumulando conforme pase el tiempo.
  • Ka****

    Ka**** 06/04/2017 Responder

    Hola, si quiero pasar los datos que obtuve a excel para graficarlos, ¿cómo podría hacerlo? Gracias
    • Na*****

      Na***** 30/04/2017 Responder

      Hola Karina, lo más simple sería almacenarlo los datos en una archivo en una SD y posteriormente importar desde Excel el archivo. En el ejemplo 4 de nuestro Tutorial Arduino y memoria SD se muestra como abrir los datos desde Excel.
  • Da***

    Da*** 05/04/2017 Responder

    Disculpe, si se quisiera implementar en una FPGA programada mediante VHDL, como se haría el código que tienen las librerías? o cual es la función de las mismas?
  • Os*** ****es

    Os*** ****es 21/03/2017 Responder

    Muy buenas tardes. Para empezar muchas gracias por el tiempo y el esfuerzo en este tutorial, es de gran ayuda. Estoy tratando de portar tu código en Arduino a la plataforma NodeMCU con lenguaje Lua para obtener de igual manera los ángulos X y Y de la tarjeta. Viendo tu código me surgen dos dudas principales:


    1.- Por que en el código se usan, a través de la librería MPU6050.cpp y MPU6050.h, tanto la lectura como escritura a registros que no aparecen en los documentos recientes del fabricante, más específicamente para el acelerómetro los registros 0x06, 0x08 y 0x0A para X,Y y Z, y los registros 0x13, 0x15 y 0x17 para el giroscipio. Y aun más extraño el que se grabe a esos registros como si se tratara de registros de 1 Byte u 8 bits, siendo que se indica en el archivo MPU6050.h, que son registros compuestos de 16 bits o 2 Bytes.


    2. La segunda y la que más me he roto la cabeza por entender es la parte del filtro de las lecturas en "crudo" tanto para acelerómetro como para el giroscopio. Quiero entender que lo que se hace es un promedio de N lecturas para sacar un valor medio, para después ir restando hasta llegar al valor deseado de offset, pero no comprendo por que se realiza un bitshift de 5 posiciones para uno y de 3 para otro y por que se restan estos valores.


    Espero y tengas el tiempo para contestar estas dudas que me tienen detenido con el desarrollo para portar a otra plataforma tu código.


    Saludos desde México.
    • Na*****

      Na***** 23/03/2017 Responder

      Hola Oscar, con respecto a lo primero, efectivamente los registros de los offset ya no se especifican en la documentación, pero si se está haciendo una correcta escritura y lectura, la función getXAccelOffset() en el archivo MPU6050.cpp usa la función readBytes() y aquí se leen 2 bytes y la función setXAccelOffset() usa la funcion writeWord() con esto escribe los 2 bytes, de igual manera sucede en los otros ejes y en el giroscopio. Con respecto a lo segundo el bitshift se usa en lugar de una división entre 2^n, por ejemplo: f_gz>>3 equivale a f_gz/8 de esta forma la ecuación para sacar el promedio es: p_gz = (f_gz-f_gz/8+gz)/8, y equivale al promedio de 8 lecturas, para el caso de la aceleración usamos un bitshift de 5 (un promedio de 32) puesto que es una variable de mayor ruido y variación.
      • La***** **ra

        La***** **ra 30/05/2017 Responder

        Buenas, no logro entender porque p_gz = (f_gz-f_gz/8+gz)/8 equivale al promedio de 8 lecturas, si en la formula solo se ven implicadas 2 lecturas f_gz y gz, la unica expresion para calcular el promedio que conozco es la sumatoria de n valores dividido n, por favor alguien aclarame esta duda.

        Saludos.
  • Os*** *lo

    Os*** *lo 21/03/2017 Responder

    Muy buenas tardes. Antes que nada muchas gracias por compartir tu conocimiento y explicarlo tan detalladamente. estoy tratando de portar tu script a la plataforma NodemCU con lenguaje Lua. Dado que hay bastante información para hacer trabajar este sensor con Arduino y muy poca para el ESP8266 o NodeMCU, me he dado a la tarea de interpretar los scripts que se exponen por internet para digerir, comprender y después escribir desde cero código en Lua. En tu explicación, que de nuevo te agradezco por el tiempo y esfuerzo, me ha generado dos dudas, la primera tiene que ver con la utilización de la librería del MPU6050.cpp y MPU6050.h, el autor de la librería lee y escribe en registros que no están definidos o mostrados en las guías del mapeo de los registros del giroscopio, a menos no en las nuevas, para ser específicos, para el acelerómetro los registros 0x06, 0x08 y 0x0A (X,Y,Z) y para el giroscopio 0x13, 0x15 y 0x17 (X,Y,Z) según el archivo MPU6050.h y por lo que entiendo, tal parece que solo se lee y escribe en un solo registro de 8 bits o 1 Byte cada valor para cada eje de offset, siendo que en el mismo archivo de cabecera MPU6050.h, indica se componen de dos Bytes sumados para cada valor para los offsets (16 bits) o Low y High, como en la lectura propia de los valores en "crudo" del acelerómetro y giroscopio.

    La segunda duda y la que más me rompe la cabeza es la explicación del filtro:



    // Filtrar las lecturas

    f_ax = f_ax-(f_ax>>5)+ax;

    p_ax = f_ax>>5;



    f_ay = f_ay-(f_ay>>5)+ay;

    p_ay = f_ay>>5;



    f_az = f_az-(f_az>>5)+az;

    p_az = f_az>>5;



    f_gx = f_gx-(f_gx>>3)+gx;

    p_gx = f_gx>>3;



    f_gy = f_gy-(f_gy>>3)+gy;

    p_gy = f_gy>>3;



    f_gz = f_gz-(f_gz>>3)+gz;

    p_gz = f_gz>>3;



    No entiendo el por que de hacer un bitshift a la derecha en ambos casos, la resta de este valor y mucho menos el por que para el acelerómetro 5 bits de desplazamiento y en el giroscopio solo 3, quiero entender que se realiza un promedio de N valores leídos en "crudo", para tomar la media de estos pero no logro comprender la lógica del script.

    Espero y tengas el tiempo y la amabilidad de aclararme estas dudas con las que me encuentro detenido para hacer la portación de tu código a otra plataforma.


    Saludos desde México.
  • Ro*****

    Ro***** 09/02/2017 Responder

    Hola, oye como puedo iniciar 2 sensores al mismo tiempo.
    Como defino la dirección con tus ejemplos?
    • Na*****

      Na***** 17/02/2017 Responder

      Hola Rodrigo, con el pin AD0 del MPU puedes cambiar la dirección, en el programa tienes que instanciar con la dirección respectiva:


      MPU6050 sensor1(0x68)

      MPU6050 sensor2(0x69)
  • Na*****

    Na***** 01/02/2017 Responder

    Hola Adrán , 131 es el factor de conversión: w= Lectura*(250/32768) = lectura*(1/131)

  • Ad**** *******ez

    Ad**** *******ez 12/01/2017 Responder

    ¿Por qué división del gx sobre 131? gracias
    • Na*****

      Na***** 01/02/2017 Responder

      Estimado Adrán , 131 es el factor de conversión: w= Lectura*(250/32768) = lectura*(1/131)

  • os*** *****to

    os*** *****to 09/01/2017 Responder

    hola soy nuevo en esto pero si solo quisiera saver la aceleracion lineal
    • Na*****

      Na***** 01/02/2017 Responder

      Hola Oscar si solo necesitas la aceleración son las que se obtienen en el ejemplo 3. allí obtenemos la aceleración lineal y velocidad angular, teniendo en cuanta que en la aceleración también se está midiendo la aceleración de la gravedad.
  • ar**** *****ez

    ar**** *****ez 18/12/2016 Responder

    hola hermano...tengo una duda en el ejemplo 6 por que cambias de signo a "ax" ,,gracias ojala me ayudes
    float accel_ang_x=atan(ay/sqrt(pow(ax,2) + pow(az,2)))*(180.0/3.14);
    float accel_ang_y=atan(-ax/sqrt(pow(ay,2) + pow(az,2)))*(180.0/3.14);
  • Cr******* ****** *****es

    Cr******* ****** *****es 17/12/2016 Responder

    hola hermano tengo problema con lo que me sale en el monitor serial....sabes a que se debe y gracia


    a[x y z] g[x y z]:t272t-74t16394t3t-4t0

    a[x y z] g[x y z]:t284t-98t16390t-12t-33t-3

    a[x y z] g[x y z]:t262t-34t16428t71t81t-14

    a[x y z] g[x y z]:t214t-30t16484t-41t-67t-1

    a[x y z] g[x y z]:t232t-48t16392t-12t-17t-8

    a[x y z] g[x y z]:t320t-34t16430t1t-7t-7

    a[x y z] g[x y z]:t228t2t16494t-44t-81t-6

    a[x y z] g[x y z]:t250t-18t16426t-9t-26t-4

    a[x y z] g[x y z]:t334t-12t16402t-1t-21t-12

    a[x y z] g[x y z]:t308t-10t16402t-7t-16t-3

    a[x y z] g[x y z]:t316t-32t16396t10t14t-4

    a[x y z] g[x y z]:t266t-46t16410t-3t-23t4

    a[x y z] g[x y z]:t240t-100t16478t1t-8t-4

    a[x y z] g[x y z]:t226t-10t16398t7t9t-10

    a[x y z] g[x y z]:t280t-56t16394t7t-18t-3

    a[x y z] g[x y z]:t240t-20t16448t-33t-61t-1

    a[x y z] g[x y z]:t294t-6t16416t3t-12t-12

    a[x y z] g[x y z]:t314t-22t16320t10t5t-4

    a[x y z] g[x y z]:t312t-38t16424t3t-7t-11

    a[x y z] g[x y z]:t286t-28t16424t47t71t-7

    a[x y z] g[x y z]:t288t-18t16408t-26t-49t-11

    a[x y z] g[x y z]:t202t-82t16388t32t46t-2

    a[x y z] g[x y z]:t276t-48t16354t13t8t-17

    • Na*****

      Na***** 23/12/2016 Responder

      Hola Cristian, tus resultados son correctos, si te refieres a la “t” es porque te está faltando digitar el \, en lugar de “t” se debe enviar un "\t" que es un tab, si persiste el problema usa mejor un doble espacio " ".
  • Cr******* ****** *****es

    Cr******* ****** *****es 17/12/2016 Responder

    ayuda hermano me sale algo como esto en el monitor serial...sabes a que se debe ,,gracias

    a[x y z] g[x y z]:t272t-74t16394t3t-4t0
    a[x y z] g[x y z]:t284t-98t16390t-12t-33t-3
    a[x y z] g[x y z]:t262t-34t16428t71t81t-14
    a[x y z] g[x y z]:t214t-30t16484t-41t-67t-1
    a[x y z] g[x y z]:t232t-48t16392t-12t-17t-8
    a[x y z] g[x y z]:t320t-34t16430t1t-7t-7
    a[x y z] g[x y z]:t228t2t16494t-44t-81t-6
    a[x y z] g[x y z]:t250t-18t16426t-9t-26t-4
    a[x y z] g[x y z]:t334t-12t16402t-1t-21t-12
    a[x y z] g[x y z]:t308t-10t16402t-7t-16t-3
    a[x y z] g[x y z]:t316t-32t16396t10t14t-4
    a[x y z] g[x y z]:t266t-46t16410t-3t-23t4
    a[x y z] g[x y z]:t240t-100t16478t1t-8t-4
    a[x y z] g[x y z]:t226t-10t16398t7t9t-10
    a[x y z] g[x y z]:t280t-56t16394t7t-18t-3
    a[x y z] g[x y z]:t240t-20t16448t-33t-61t-1
    a[x y z] g[x y z]:t294t-6t16416t3t-12t-12
    a[x y z] g[x y z]:t314t-22t16320t10t5t-4
    a[x y z] g[x y z]:t312t-38t16424t3t-7t-11
    a[x y z] g[x y z]:t286t-28t16424t47t71t-7
    a[x y z] g[x y z]:t288t-18t16408t-26t-49t-11
    a[x y z] g[x y z]:t202t-82t16388t32t46t-2
    a[x y z] g[x y z]:t276t-48t16354t13t8t-17
  • jo**

    jo** 30/11/2016 Responder

    buenas noches
    me puede explicar que debo modificar al codigo del filtro complementario y obtener las lecturas de giro en z con variaciones minimas de error?
    • Na*****

      Na***** 01/12/2016 Responder

      Hola José, en el filtro de complemento usamos los ángulos obtenidos del acelerómetro, y estos se limitan a X y Y, puesto que una rotación en Z el acelerómetro no lo detectará pues usamos la gravedad para determinar el ángulo. Para esto es mejor usar un Magnetómetro.
  • ke****

    ke**** 28/10/2016 Responder

    porqué se escala dividiendo el valor en 131? osea de donde sale ese 131? ya que estoy usando es una beaglebone black en lugar de arduino me interesa saber de donde sale ese valor, igual me funciona más o menos, me sirvió en parte para lo que necesito de forma perfecta, pero igual me gustaría saber de donde sale esa constante, muchas gracias por subir y permitir ver ese tutorial.
    • Na*****

      Na***** 28/10/2016 Responder

      Estimado Keyvis , 131 es el factor de conversión: w= Lectura*(250/32768) = lectura*(1/131)
  • El* **az

    El* **az 26/10/2016 Responder

    Excelente información!!!
    Para implementar mi proyecto, debo de implementar las siguientes etapas:
    1. Calibración. Se hace sólo una vez? O tengo que calibrar el MPU6050 cada vez que lo encienda (Incluir la calibración como parte de la programación).
    2. Filtro. El filtro complementario lo utilizo para eliminar errores o disminuir perturbaciones. En el ultimo sketch que presentas se determina la rotación en X y la rotación en Y. No me queda claro como utilizo estos dos ultimos valores para obtener valores de aceleración filtrados.
    3. Escalado de lecturas y procesamiento


    • Na*****

      Na***** 28/10/2016 Responder

      Eli, La calibración solo es necesario hacerla una vez. EL filtro complemento en si es para combinar el acelerómetro y el giroscopio. Si solo utiliza el acelerómetro para determinar el ángulo, cualquier aceleración generada por un desplazamiento va generar errores en el ángulo. En cambio sí solo uso el giroscopio va a ver un error acumulativo por causa de la integración de w. Este filtro se utiliza cunado queremos sensar el ángulo pero el MPU está en constante movimiento (Drones, robots móviles, etc). Si el PMU siempre va a estar fijo puedes solo tomar el vector de la aceleración de la gravedad para determinar los ángulos.
  • Mi****

    Mi**** 20/10/2016 Responder

    Hola buenas noches, ojalá me pudieras apoyar con una idea. Necesito sensar con está IMU cuando un objeto se cae. No sé de que manera pudiera hacerlo, creo que sería de forma parecida a saber si va hacia delante o hacia atrás
    • Na*****

      Na***** 28/10/2016 Responder

      Estimado Miguel, el MPU sensa aceleraciones y velocidades angulares, y puedes detectar cualquier movimiento que influya en esas variables. Si es caída libre la aceleración no va a cambiar, pero si cuando topa el suelo, allí abría una desaceleración, ese cambio de aceleración podrías interprétalo como que el MPU ha caído al suelo, Si cuando el objeto cae y tiene rotación también puedes sensar las velocidades angulares e interprétalas como caída.
  • No****

    No**** 18/10/2016 Responder

    Hola Naylamp. Estoy llevando acabo un proyecto de fin de carrera y el tutorial me ha servido de mucho, gracias. Sin embargo, mi objetivo es hallar la velocidad velocidad lineal de un objeto de 35 cm de radio al que va sujeto el modulo MPU6050, por lo tanto una vez que tengo los grados por segundo(máximo 2000 en este caso, ya que necesito el rango máximo) lo paso a rad/s y sabiendo el radio ( v = w · R = 34,91 · 0,35 = 12,21 m/s) obtengo una cifra en metros segundo demasiado baja, necesito mayor rango de velocidad y un mayor rango de valores de movimiento ya que al agitarlo rápidamente ya me da los valores máximos (32.768 valores) lo cual debe estar mal ya que yo no puedo alcanzar esas velocidades, simplemente agitando el mpu, me resulta extraño. Por ello se me plantea, en primer lugar, aumentar el rango de valores a 32 bits (2.147.483.647 valores) y así tener un mayor rango de velocidades y un mayor rango en el limite de movimiento del modulo, creo que esta podría ser la solución, no se si estoy en lo cierto. Resumiendo, en la librería MPU6050.h necesito establecer los valores a 32 bits. He estado probando a cambiar el tipo de entero, pero no me da resultado. Que debería hacer?
    Si sigues vivo después de leer el tocho =), te agradecería que me ayudaras.
    • Na*****

      Na***** 28/10/2016 Responder

      Estimado Norber, para cambiar el rango del giroscopio 2000°/s debes usar mpu.setFullScaleGyroRange(MPU6050_GYRO_FS_2000); esto en el void setup() después de inicializar el modulo. La resolución del MPU es de 16bits y no se puede cambiar. También puedes medir la aceleración centrípeta (aceleración normal) con el acelerómetro y despejar la velocidad lineal.
  • em******

    em****** 17/10/2016 Responder

    no me aparecen las mediciones en el monitor serie nose porque... alguna ayuda????
    • Na*****

      Na***** 28/10/2016 Responder

      Verifica que la velocidad del monitor serie sea la misma que la que configuras en el código, verifica también que se haya cargado el programa. Para descartar que sea un error de conexión, al inicio, después de Serial.begin, envía algún texto por el monitor serial. Saludos
  • Jo**

    Jo** 14/10/2016 Responder

    Hola. ¿En la parte de la inclinación eso sería (x y y) Roll y pitch?, ¿Pero para yaw, la rotación en z como se determinaría?
  • Jo**

    Jo** 14/10/2016 Responder

    Hola. ¿En la parte de la inclinación eso sería (x y y) Roll y pitch?, ¿Pero para yaw, la rotación en z como se determinaría?
    • Na*****

      Na***** 28/10/2016 Responder

      Estimado José, X y Y podrías trabajarlo como Roll y pitch pero dependiendo de la poción del MPU. Para el caso de Yaw lo puedes determinar con el giroscopio pero vas a tener un error acumulativo(Drift). Lo correcto es usar un magnetómetro o brújula digital.
      • Am****

        Am**** 06/04/2017 Responder

        Haz intentado obtener un Yaw aunque sea impreciso? Me he imaginado que se puede usar el EEPROM para guardar bytes con el cambio de angulo con respecto al tiempo.. despues usar un grupo de bytes y "sumarlos" y obtener el angulo de desplazamiento... alguien tendra algun sketch con esta loquera... se que un magnetometro seria la solución a mis problemas pero soy honesto compre los MPU6050 creyendo que podria obtener el YAW y no quiero desperdiciarlos...:( Auxilio!
  • Ne****

    Ne**** 11/10/2016 Responder

    Buenas Noches (hora Venezuela) tengo un problema, ejecuto el Sketch para la calibración y me arroja que los offset son
    -1044 -303 1284 0 0 0 y envio el caracter para que inicie la calibración y parte con estos valores
    promedio: -4966 -26278 12484 -31 -371 -34
    luego de pasado unos minutos llega a los valores que uno espera y realizo el reinicio, la desconexión del cable usb o cierro el monitor serial cargo Sketch para ver si la calibración funciona y me devuelve estos valores:
    a[x y z](m/s2) g[x y z](deg/s): -0.53 -19.62 9.34 -0.65 -2.07 -0.18
    Ese proceso lo he realizado ya una 10 veces y solo una me funcionó pero perdió la cubrición. por favor necesito ayuda.

    • Na*****

      Na***** 14/10/2016 Responder

      Hola Néstor, puede ser que tu MCU esté trabajando con otro rango, el tutorial esta echo para trabajar con +/- 2g y 250 deg/s , si no guarda la calibración puedes solucionarlo configurando los offset al inicio de cada programa.
  • pe***

    pe*** 09/10/2016 Responder

    Hola que tal, excelente explicación... me nace una duda (olaja me puedas ayudar), me gustaría por medio de dos sensores MPU controlar dos servomotores de manera independiente en el plano (x y); es decir, por medio del registro del cambio angular (mpu), poder reflejarlo en cada uno de los servos, la idea es simularlo en un tipo de manipulador.

    gracias.
    • Na*****

      Na***** 14/10/2016 Responder

      Hola Pedro, va a depender con que movimiento quieres controlar el servo, por ejemplo si quieres controlar con la inclinación, solo escala el Angulo x o y de -90:90 a valores de 0:180 y envíalo al motor.
  • lu***

    lu*** 07/10/2016 Responder

    Hola, simplemente quería felicitarte y agradecerte por la explicación. Muchas gracias!
  • GU*****

    GU***** 14/09/2016 Responder

    Hola tengo una duda cuando muevo la IMU6050 en el eje X a 178 grados este llega a ese valor pero lo dejo en esa posición y este empieza a descender hasta 1 no se supone que debe quedar en ese angulo?? igual con el eje Y
    • Na*****

      Na***** 21/09/2016 Responder

      Hola Gustavo, Lo que está pasando es que el giroscopio te mide los 178° pero converge a -1 que es el valor del acelerómetro, esto porque el código y las formulas están para trabajar en un rango de -90 y 90, esto para el acelerómetro. Si deseas trabajar en el rango de -180 y 180 tienes que usar: atan2 (y, x) // atan(y/x) , esto tomara en cuenta el signo, a esto agrega condiciones, pues de todas formas se anula el signo al trabajar con los cuadrados.
      • Je******

        Je****** 16/10/2020 Responder

        puede ampliar esta informacion he intentado pero tengo algunos problemas.
      • Je******

        Je****** 16/10/2020 Responder

        Puedes ampliar esta infromacion, no he podido realizar el programa para que el angulo de medida sea de -180 a 180 °
      • Ju** ****os

        Ju** ****os 26/01/2020 Responder

        Gracias por el aporte. ¿Podrías especificar como conseguir que mida desde 180 a -180 en lugar de 90 a -90?
        Muchas gracias
      • Om** ***oa

        Om** ***oa 25/11/2017 Responder

        Hola que tal, disculpa que pregunte de nuevo pero no entiendo mucho de este tipo de ecuaciones trigonométricas y no logro conseguir que me arroje los 180° creo que con eso ya podría lograr hacer condiciones para obtener 360° o abra alguna manera de obtener 360° de antemano muchas gracias. }espero me puede ayudara para implementar al menos los 180°. Gracias saludos
      • gu*******

        gu******* 25/05/2017 Responder

        Hola, disculpe tengo el mismo problema que Gustavo, podría ser tan amable de explicar la fórmula que mencionó.
        Se lo agradecería mucho.
  • ed***** ***dt

    ed***** ***dt 25/08/2016 Responder

    Hola, gran tutorial para entender el funcionamiento de la MPU 6050, pero estoy teniendo problemas con algo. Sería cómo conducir LEDs de los valores de ángulo medido en el Ejemplo 6?
    • Na*****

      Na***** 26/08/2016 Responder

      Hola Eduardo, cuantos leds y que tipo de efecto quieres manjar en función del ángulo.
      Por ejemplo si quieres manejar 10 leds puede usar la función map:
      nLed = map(angulo, -90, 90, 1, 10);
      Y luego con un Switch() activar los leds correspondiente.
      • ed***** ***dt

        ed***** ***dt 27/08/2016 Responder

        lo siento, no puedo planear nada en absoluto !!! XD ¿Me podría ayudar?
  • An*****

    An***** 31/07/2016 Responder

    Hola! Excelente explicación! Me aclaró muchas cosas que tenía en duda... Quería hacerte una pregunta, tenés idea como es el algoritmo de cálculo cuando le agregamos un magnetómetro al sistema? Y así también poder calcular la rotación en Z? Muchas gracias!
    • Na*****

      Na***** 02/08/2016 Responder

      Hola Andrés, para trabajar con un magnetómetro los cálculos son similares, con la diferencia que sensamos el campo magnético de la tierra para orientarnos, puedes revisar nuestro tutorial del Magnetómetro HMC5883L para más información.
  • Al******* ***iz

    Al******* ***iz 05/07/2016 Responder

    Gracias por el dato, pero que valores me vote el sensor, es decir el .getRotation() que valores me dan, me quede con esa duda!
    • Na*****

      Na***** 05/07/2016 Responder

      Las funciones getAcceleration() y getRotation() te devuelven valores de -32768 a 32767 (16bits), que corresponden de -2g a 2g y de -250°/sec a +250°/sec respectivamente si están en su rango por defecto, esto se explica mejor en el ejemplo 3. Cuando calculamos el ángulo con el acelerómetro no necesitamos escalar pues estos se dividen, pero si observas cuando trabajamos con el giroscopio allí si lo escalamos (valor/131).
  • Al******* ***iz

    Al******* ***iz 05/07/2016 Responder

    Disculpa podrias explicarme el porque del uso de las ecuaciones, es decir te entiendo float accel_ang_x=atan(ax/sqrt(pow(ay,2) + pow(az,2))) ya que lo describiste pero porque multiplicas por esto(180.0/3.14); te lo agradeceria si me respondieras de urgencia un saludo!
    • Na*****

      Na***** 05/07/2016 Responder

      Alexander, La ecuación atan() nos devuelve el resultado en radianes, se multiplica por (180/pi) para convertir el ángulo en grados sexagesimales.
Dejar un comentario
Deja su comentario

Menú

Ajustes

Crear una cuenta gratuita para usar listas de deseos.

Registrarse