Portada MPU6050II

Sorteo

El módulo MPU6050 posee 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, el acelerómetro trabaja sobre el principio piezo eléctrico, además tiene un sensor de temperatura.

Los acelerómetros internamente tienen un MEMS “MicroElectroMechanical Systems” que de forma similar a un sistema masa-resorte permite medir la aceleración. Los giroscopios utilizan un MEMS “MicroElectroMechanical Systems” para medir la velocidad angular usando el efecto Coriolis.

Para describir el funcionamiento realizo una simple interconexión del MPU-6050 con una placa Arduino UNO. El MPU6050 es un sensor de movimiento, que tiene un conversor ADC de 16 bits que convierte los datos a un valor digital, el módulo de giroscopio se comunica con el Arduino a través de la comunicación serie I2C a través del reloj serial “SCL” y datos “SDA”, el chip MPU6050 necesita 3.3V pero un regulador de voltaje en la tarjeta GY-521 le permite alimentarlo hasta 5V, en nuestro caso en un Arduino UNO.

El procesador interno del IMU “Inertial Measurment Units” es capaz de realizar cálculos precisos de los valores que miden sus sensores internos que son, aceleraciones lineales y angulares, para informarnos de valores útiles como los ángulos de inclinación con respecto a los 3 ejes principales. Un dato importante es que ni la aceleración ni la velocidad lineal afectan la medición de giro.

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. Como la comunicación del módulo es por medio del I2C, esto le permite trabajar con la mayoría de microcontroladores. En el módulo los pines SCL y SDA tienen una resistencia pull-up en placa para una conexión directa al microcontrolador que estemos utilizando.

Sensor Giroscópico

Un giroscopio es un elemento que funciona para miden velocidades angulares basándose en el mantenimiento del impulso de rotación. Si intentamos hacer girar un objeto que está girando sobre un eje que no es el eje sobre el que está rotando, el objeto ejercerá un momento contrario al movimiento con el fin de preservar el impulso de rotación total.

El giroscopio muestra el cambio de rango en rotación en sus ejes X, Y y Z.

Acelerómetro 

Mide la aceleración, inclinación o vibración y transforma la magnitud física de aceleración en otra magnitud eléctrica que será la que emplearemos en los equipos de adquisición estándar. Los rangos de medida van desde las décimas de g, hasta los miles de g.

El circuito integrado MPU-6050 contiene un acelerómetro y giroscopio MEMS en un solo empaque. Cuenta con una resolución de 16-bits, lo cual significa que divide el rango dinámico en 65536 fracciones, estos aplican para cada eje X, Y y Z al igual que en la velocidad angular. El sensor es ideal para diseñar control de robótica, medición de vibración, sistemas de medición inercial “IMU”, detector de caídas, sensor de distancia y velocidad, y muchas cosas más. El MPU-6050 contiene un giroscópico, un acelerómetro, además de un sensor de temperatura, mediante I2C regresa unos valores conocidos como raw o “crudos” según el registro seleccionado.

A continuación se mostraron los rangos de escala y el valor máximo raw. Dado en g.

Rango De Escala Completa Giroscopio Sensibilidad del Giroscopio Rango De Escala Completa Acelerómetro Sensibilidad del Acelerómetro
±250 131 ±2 16384
±500 65.5 ±4 8192
±1000 32.8 ±8 4096
±2000 16.4 ±16 2048

Caracteristicas Técnicas del MPU6050

  • Salida digital de 6 ejes.
  • Giroscopio con sensibilidad de ±250, ±500, ±1000, y ±2000dps
  • Acelerómetro con sensibilidad de ±2g, ±4g, ±8g y ±16g
  • Algoritmos embebidos para calibración
  • Sensor de temperatura digital
  • Entrada digital de video FSYNC
  • Interrupciones programables
  • Voltaje de alimentación: 2.37 a 3.46V
  • Voltaje lógico: 1.8V±5% o VDD
  • 10000g tolerancia de aceleración máxima

 

Elementos a requerir

  • Acelerómetro Giroscopio MPU-6050 6DOF.
  • Arduino Uno R3.
  • Cable USB-serial

Diagrama de Conexión

En la  conexión el INT del MPU6050 no es necesaria.

Acelerometro Giroscopio MPU 6050 

ARDUINO UNO

VCC

VCC

GND

GND

SDA

PIN ANALOGICO CUATRO

SCL

PIN ANALOGICO CINCO

Las bibliotecas de Arduino  que usaremos para facilitar nuestro trabajo las pueden descargar del siguiente enlace:

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

y la  librería que maneja el I2Cdev de:

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

Inicie su Arduino IDE  haga click  al menú Archivos/Ejemplos… y navegue hasta MPU6050 y encontrará el archivo MPU6050_DMP6, ábralo y seleccione el puerto COM adecuado, suba el código  y en el monitor serial elija la velocidad de 115200 Baudios.

Recalibrando el MPU6050

Hay muchos casos  que se puede encontrar que se presentan muchas vibraciones y ruido en las medidas, aun cuando tengamos instalado el módulo MPU6050 en el prototipo, siempre puede haber un  una  mala calibración en sus componentes, motivo por el cual debemos calibrar el módulo, asegurándonos de que no haya un error de calibrado.

Podemos solucionar estos problemas al configurar el módulo MPU6050 OFFSETS, para compensar dichos errores.

Lineas para calibrar los offset del MPU6050.

// calibrar_mpu6050.ino
// Librerias I2C para controlar el mpu6050 con Arduino,
// la libreria MPU6050.h necesita I2Cdev.h, la libreria 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.println("\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++;
}

En el proceso de  la calibración hay que mantener el sensor sin moverlo en la posición de trabajo habitual, entonces el programa empieza por leer los offsets y nos pide que enviemos un carácter por el puerto serie.

El programa trata de corregir los errores de las medidas, para ello modifica constantemente el offsets, usando un filtro y cada 100 lecturas comprueba los valores si se acercan a los que deseamos leer, aumentando o disminuyendo los offsets. Esto hará que las lecturas filtradas se acerquen a:

aceleración: p_ax=0 , p_ay=0 , p_az=+16384
velocidad angular: p_gx=0 , p_gy=0 , p_gz=0

Como indica en el monitor debemos anotar las compensaciones obtenidas para configurarlas en nuestros proyectos, usando la función mpu.setXAccelOffset(), como se indica a continuación.

Abriremos el archivo MPU6050_PMT y buscaremos la parte de Calibration results como se aprecia en la figura que sigue.

La calibración solo hay que hacerla una vez. EL filtro complemento en si, es para combinar el acelerómetro y el giroscopio. Si solo utilizáramos el acelerómetro para determinar el ángulo, cualquier aceleración generada por un desplazamiento generaría errores en el ángulo. En cambio sí solo usamos el giroscopio vamos a obtener un error acumulativo por causa de la integración de w “velocidad angular”. Este filtro se utiliza acunado, queremos sensar el ángulo pero el MPU está en constante movimiento (Drones, robots móviles, etc). En cambio, si el PMU va a estar fijo podemos tomar sólo el vector de la aceleración de la gravedad para determinar los ángulos.

Escalado de mediciones

Vamos a escalar las mediciones a valores con las unidades de aceleración y velocidad angular. Carguemos el siguiente programa que usa una ecuación para convertir el valor leído en un valor de aceleración o velocidad angular.

Este programa nos permite escalar valores de aceleración y velocidad angular.

// escalar_valores.ino
// Librerias I2C para controlar el mpu6050 con Arduino,
// la libreria MPU6050.h necesita I2Cdev.h y la libreria I2Cdev.h necesita Wire.h
/* 
 Conociendo 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.
 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
*/
 
#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);
}

Con el MPU6050, sólo podemos obtener los ángulos X e Y, con el filtro de complemento usamos los ángulos obtenidos del acelerómetro, los cuales se limitan a X e Y, puesto que una rotación en Z del acelerómetro no la detectará ya que usamos la gravedad para determinar el ángulo. Para esto es mejor usar un Magnetómetro similar al HMC5883L.

Los valores obtenidos ya están escalados a unidades de aceleración y velocidad angular, hemos convertido la aceleración a valores en m/s al cuadrado por lo que se reemplazó el valor de g=9.81 si el sensor se mantiene en posición horizontal se deben obtener mediciones cercanas a 9.8 m/s al cuadrado “aceleración de la gravedad terrestre “ es la componente z de la aceleración

Código

El código obtener inclinación viene bastante bien descrito y no hará falta muchas aclaraciones.

Puesta en marcha…

Para ejecutar la demostración  3D, vamos a utilizar una sencilla maqueta en cartón  de un Eurofighter para que se comprenda mejor la evolución de los parámetros Yaw, Roll y Pitch a medida que se generan al cambiar la posición del IMU.

El primer paso es subir el código al IDE Arduino , vamos a probar con Arduino, en ese caso, nos sirve el diagrama descrito anteriormente.

Fuentes

Enlaces 

 

 Video

 
Saludos Makers , hasta la próxima German
 
 
views
297
 

ElectroMercado

  • arduino | circuitos
1 Comentario
  1. Daniel01
    Daniel01 5 meses

    Hola German es fácil su implementación del MPU 6050, por lo que estuve leyendo la conexión es sencilla , pero la calibración y eso se complica un poco. Saludos

    0

Contesta

CONTACTANOS

Esta es su red social de tecnología para compartir tus ideas y proyectos .Puedes enviarnos un correo si tienes dudas.Nos vemos

Enviando

Inicia Sesión con tu Usuario y Contraseña

o    

¿Olvidó sus datos?

Create Account