Haga clic para más productos.
No se encontraron productos.
Búsqueda de blogs
Artículos Recientes
Categorías del blog
Últimos comentarios
No hay artículos
Artículos relacionados

Tutorial MPU6050, Acelerómetro y Giroscopio

238903

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
127 Comentarios
  • Gustavo Silva

    Gustavo Silva 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]
  • Jorge

    Jorge 06/06/2021 Responder

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

    Patricio Antonio 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.
  • jorge henao

    jorge henao 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.
  • Luis Sempere Payá

    Luis Sempere Payá 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
  • Miguel Pardo

    Miguel Pardo 30/07/2020 Responder

    Excelente Articulo
  • Miguel Pardo

    Miguel Pardo 30/07/2020 Responder

    EXCELENTE Articulo
  • leonardo

    leonardo 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
  • leonardo

    leonardo 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
  • Eduard Baron

    Eduard Baron 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
  • YersonSalazar

    YersonSalazar 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.
  • Luis Perez

    Luis Perez 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
  • Antonio

    Antonio 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
  • Jose Cultrera

    Jose Cultrera 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...
  • satya

    satya 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?
  • Gerardo Ramírez Carreño

    Gerardo Ramírez Carreñ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
    • Gustavo Silva

      Gustavo Silva 09/06/2021 Responder

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

    satya 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.
  • JAVIER

    JAVIER 18/09/2019 Responder

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

    Daniel 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
  • Fabio Marredo

    Fabio Marredo 12/08/2019 Responder

    Excelente artículo. Felicitaciones y gracias por compartir tu conocimiento.
  • Edwin Vargas

    Edwin Vargas 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
  • Rodrigo

    Rodrigo 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?
  • Bere

    Bere 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.
  • Helbert

    Helbert 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
  • Gustavo Ignacio

    Gustavo Ignacio 11/03/2019 Responder

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

    javier 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.
  • jose

    jose 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?
  • Marcelo Calcia

    Marcelo Calcia 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?
  • javier

    javier 09/10/2018 Responder

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

      javier 14/02/2019 Responder

      QUIZÁS SIMPLEMENTE PORQUE LA TIERRA NO SE MUEVE.
  • Edgar Olivares

    Edgar Olivares 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"
  • Tony Sanx

    Tony Sanx 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?
    • Tony Sanx

      Tony Sanx 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.
  • Aldo

    Aldo 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!!!
  • Jose

    Jose 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
  • Ulises

    Ulises 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??
  • Xavier

    Xavier 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);
    }
  • DAVID LANCHEROS

    DAVID LANCHEROS 21/06/2018 Responder

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

      ANONIMO 20/06/2019 Responder

      Trata de verificar que está seleccionado en la plataforma el arduino que estás utilizando
      • Arturo Perez

        Arturo Perez 20/11/2019 Responder

        Tengo el mismo problema, ya verifiqué que tengo seleccionada la placa correcta, estoy usando un Arduino DUE.
      • Arturo Pérez

        Arturo Pérez 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.
  • Germán Alberto

    Germán Alberto 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
  • Thais

    Thais 01/04/2018 Responder

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

    Antonio 15/03/2018 Responder

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

    Vicente 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.
  • Rafael

    Rafael 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?
  • yilber

    yilber 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(", "));
    • Andres Bravo

      Andres Bravo 29/10/2018 Responder

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

    ERNEST 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.
  • Elias Cepeda

    Elias Cepeda 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?
  • Danny

    Danny 10/09/2017 Responder

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

      Antonio 15/03/2018 Responder

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

        neyser 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);
        }
  • Anthony

    Anthony 28/08/2017 Responder

    Excelente tutorial no tendrán alguno de armado de un Drone!!!
  • Jesus Amador

    Jesus Amador 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.
    • Naylamp

      Naylamp 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.
  • Allinger

    Allinger 14/07/2017 Responder

    Amigos quisiera saber como leer la temperatura del sensor mpu6050
    • Naylamp

      Naylamp 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)
  • Mafer Vizcaino

    Mafer Vizcaino 26/06/2017 Responder

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

    Gracias y buen dia
  • charlie

    charlie 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
    • Naylamp

      Naylamp 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.
  • Yilber

    Yilber 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
    • Naylamp

      Naylamp 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.
      • Andres Bravo

        Andres Bravo 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
  • Cesar

    Cesar 20/05/2017 Responder

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

    Brayan 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 :(
    • Naylamp

      Naylamp 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.
  • luis morales

    luis morales 16/04/2017 Responder

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

    Cristina 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!!
    • Naylamp

      Naylamp 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.
  • Karina

    Karina 06/04/2017 Responder

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

      Naylamp 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.
  • David

    David 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?
  • Oscar Flores

    Oscar Flores 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.
    • Naylamp

      Naylamp 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.
      • Lautaro Vera

        Lautaro Vera 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.
  • Oscar Flo

    Oscar Flo 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.
  • Rodrigo

    Rodrigo 09/02/2017 Responder

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

      Naylamp 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)
  • Naylamp

    Naylamp 01/02/2017 Responder

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

  • Adrán Ricárdez

    Adrán Ricárdez 12/01/2017 Responder

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

      Naylamp 01/02/2017 Responder

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

  • oscar roberto

    oscar roberto 09/01/2017 Responder

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

      Naylamp 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.
  • aridai Ramirez

    aridai Ramirez 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);
  • Cristhian Santel Morales

    Cristhian Santel Morales 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

    • Naylamp

      Naylamp 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 " ".
  • Cristhian Santel Morales

    Cristhian Santel Morales 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
  • jose

    jose 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?
    • Naylamp

      Naylamp 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.
  • keybis

    keybis 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.
    • Naylamp

      Naylamp 28/10/2016 Responder

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

    Eli Diaz 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


    • Naylamp

      Naylamp 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.
  • Miguel

    Miguel 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
    • Naylamp

      Naylamp 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.
  • Norber

    Norber 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.
    • Naylamp

      Naylamp 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.
  • emmanuel

    emmanuel 17/10/2016 Responder

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

      Naylamp 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
  • Jose

    Jose 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?
  • Jose

    Jose 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?
    • Naylamp

      Naylamp 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.
      • Amadeo

        Amadeo 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!
  • Nestor

    Nestor 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.

    • Naylamp

      Naylamp 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.
  • pedro

    pedro 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.
    • Naylamp

      Naylamp 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.
  • lucas

    lucas 07/10/2016 Responder

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

    GUSTAVO 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
    • Naylamp

      Naylamp 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.
      • Jefferso

        Jefferso 16/10/2020 Responder

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

        Jefferso 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 °
      • Juan Carlos

        Juan Carlos 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
      • Omar Ochoa

        Omar Ochoa 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
      • guadalupe

        guadalupe 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.
  • eduardo arndt

    eduardo arndt 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?
    • Naylamp

      Naylamp 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.
      • eduardo arndt

        eduardo arndt 27/08/2016 Responder

        lo siento, no puedo planear nada en absoluto !!! XD ¿Me podría ayudar?
  • Andrés

    Andrés 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!
    • Naylamp

      Naylamp 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.
  • Alexander Ortiz

    Alexander Ortiz 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!
    • Naylamp

      Naylamp 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).
  • Alexander Ortiz

    Alexander Ortiz 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!
    • Naylamp

      Naylamp 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