Practicas con el sensor de 3 ejes y Arduino.
INTRODUCCIÓN.
Cuando iniciamos una nueva tarea que requiere de un nuevo dispositivo al que no habíamos tenido la ocasión de utilizar, lo propio es tener dudas y naturalmente debemos buscamos información que nos aclare los conceptos y conocimientos que se requieren para manejar, cuando no dominar el nuevo «juguete». Si usted se encuentra en este caso, tal vez haya llegado al sitio que estaba esperando. Espero aclararle las preguntas que tiene en estos momentos.
El MPU-6050 no es caro, especialmente teniendo en cuenta el hecho de que combina un acelerómetro y un giroscopio en el mismo dispositivo.
Comprendo que tenga dudas, a la hora de configurar un IMU (Unidad de Medición de Inercia), utilizando un Arduino para obtener su lectura, ya que no es nada sencillo, pues la mayoría de estas unidades, utilizan protocolos como I2C o SPI que dan valores empíricos que requieren un conocimiento y desarrollo matemático importante. Sin mencionar que, algunas IMU siempre dan lecturas erróneas, dependiendo de como se utilicen que, es el caso en que se encuentran los principiantes. Veremos como depurar esos valores además, calcularemos ángulos de posición y aprovechando herramientas como los filtros para el «ruido» con un Filtro Complementario (Complementary Filter). Este es el aspecto que tiene este sensor:
En este tutorial, haré una introducción básica al MPU-6050 y mostraré cómo se puede conectar a un Arduino. Veremos como hacer un modelo 3D utilizando los datos de MPU-6050 y Arduino. Este artículo viene a ser una descripción de la experiencia que he vivido, en mi primer contacto con un sensor de nueva generación de sensores de movimiento, inercia y aceleración, en el caso concreto del Invensense MPU-6050. Los sensores IMU básicos (Unidad de Medición de Inercia), compatibles con los microcontroladores actuales como el que nos ocupa el Arduino, para interactuar con el mejor sensor IMU disponible y económico.
EL SENSOR MPU-6050.
Según el fabricante. «La unidad de procesamiento de movimiento MPU-60X0 es la primera solución del mundo en procesamiento de movimientos, con la fusión integrada de sensores con 9-ejes, la fusión de sensores utiliza su motor propiedad MotionFusion™ probado en el campo de teléfonos móviles, tabletas, aplicaciones, controladores de juegos, mandos a distancia, puntero de movimiento y otros dispositivos de consumo.
El MPU-60X0 tiene integrado un giroscopio MEMS de 3 ejes, un acelerómetro de 3 ejes MEMS, y un procesador digital de movimiento (DMP™) motor acelerador de hardware con un puerto I2C auxiliar que se conecta a las interfaces de sensores digitales de terceras partes tales como magnetómetros. Cuando se conecta a un magnetómetro de 3 ejes, el MPU-60X0 entrega una salida completa de 9 ejes MotionFusion para su primario I2C o puerto SPI (SPI está disponible sólo en MPU-6000)».
El MPU-60X0 combina la aceleración y el movimiento de rotación más la información de rumbo en un único flujo de datos para la aplicación. Esta integración de la tecnología MotionProcessing™ presenta un diseño más compacto y tiene ventajas de costos inherentes en comparación con soluciones discretas de giroscopio más acelerómetro. El MPU-60X0 también está diseñado para interactuar con múltiples sensores digitales no inerciales, tales como sensores de presión, en su bus I2C auxiliar maestro. El MPU-60X0 es un procesador de movimiento de segunda generación y es la huella compatible con la familia MPU-30X0.
Así pues, el sensor MPU-6050 es una pequeña pieza tecnológica de procesamiento de movimiento. El cual mediante la combinación de un MEMS (Sistemas Microelectromecánicos) giroscopio de 3 ejes y un MEMS acelerómetro de 3 ejes en la misma pastilla de silicio junto con un DMP™ (Movimiento Digital Processor™), es capaz de procesar los algoritmos de movimientos complejos de 9 ejes (MotionFusion™) en una placa.
El MPU-6050 elimina los problemas de alineación del eje transversal que puede arrastrarse hacia arriba en porciones discretas. Las piezas integran el algoritmo MotionFusion para 9 ejes ‘pueden incluso acceder a magnetómetros externos u otros sensores a través de un bus I2C auxiliar maestro, permitiendo reunir un conjunto completo de dispositivos sensores de datos, sin la intervención del procesador del sistema. El MPU-6050 es un 6 DOF (grados de libertad = Degrees of Freedom) o un sensor IMU de seis ejes, lo que significa que da seis valores de salida.
El procesador digital de movimiento (DMP) incorporado se encuentra dentro de la MPU-6050 y descarga el cálculo de los algoritmos de procesamiento de movimiento desde el procesador host. Los datos resultantes pueden ser leídos de los registros de la DMP, o pueden estar tamponados en un FIFO. El DMP tiene acceso a uno de los pines externos de la MPU, que pueden ser utilizados para la generación de interrupciones. El propósito del DMP es descargar los requisitos de temporización y la potencia de procesamiento del procesador anfitrión.
El sensor MPU-6050 es muy preciso, ya que contiene una conversión hardware de 16 bits de A/D por cada canal, para la digitalización de las salidas del acelerómetro. Para ello capta los canales x, y y z al mismo tiempo. Como se ha comentado, el sensor utiliza el I2C-bus para interconectar con el Arduino. Aunque algunas versiones (como la mostrada) llevan un regulador que permite conectarla a 5V.
Precaución con la gama de tensiones de funcionamiento desde 2.37V a 3.45V.
La lectura de los valores brutos es fácil.
La lectura de los valores brutos para el acelerómetro y el giroscopio es fácil. El modo de suspensión tiene que ser inhabilitado, y luego los registros encontrados para el acelerómetro y el giroscopio se pueden leer.
Sin embargo, el sensor también contiene un buffer FIFO 1024 byte. Los valores de los sensores pueden ser programados para poder colocarlos en la memoria intermedia FIFO. Y el tampón podrá ser leído por el Arduino.
El buffer FIFO se utiliza junto con la señal de interrupción. Si los datos de lugares MPU-6050 en el búfer FIFO, el Arduino indica con la señal de interrupción por lo que el Arduino sabe que hay datos en el búfer FIFO a la espera de ser leído.
Las cosas se ponen realmente complejas con el «DMP».
El sensor tiene un «procesador digital de movimiento» (DMP), también llamado «unidad de procesamiento digital de movimiento«. Este DMP se puede programar con firmware y es capaz de hacer cálculos complejos con los valores de los sensores.
Para esta DMP, InvenSense tiene una política de desánimo, al no suministrar suficiente información de cómo programar el DMP. Sin embargo, algunos han usado la ingeniería inversa para capturar firmware.
El DMP («Procesador digital de movimiento») puede hacer cálculos rápidos o directamente en el chip. Esto reduce la carga para el microcontrolador (como el Arduino). Vamos ser más prácticos.
Boceto Corto Ejemplo.
El boceto corto de ejemplo es un esbozo muy breve y muestra todos los valores brutos (de acelerómetro, giroscopio y temperatura). El esquema práctico se muestra en la figura 3. Debería funcionar en Arduino Uno, Nano, Leonardo, y también Due.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// MPU-6050 Short Example Sketch // By Arduino User JohnChi // August 17, 2014 // Public Domain #include const int MPU=0x68; // I2C address of the MPU-6050 int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; void setup(){ Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); Serial.begin(9600); } void loop(){ Wire.beginTransmission(MPU); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU,14,true); // request a total of 14 registers AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) Serial.println("MPU-6050"); Serial.print("Datos del Acelerometro."); Serial.print("AcX = "); Serial.print(AcX); Serial.print(" | AcY = "); Serial.print(AcY); Serial.print(" | AcZ = "); Serial.print(AcZ); Serial.print(" | Tmp = "); Serial.println(Tmp/340.00+36.53); //equation for temperature in grados C a partir de hoja de datos Serial.println("Datos del Giroscopo."); Serial.print("GyX = "); Serial.print(GyX); Serial.print(" | GyY = "); Serial.print(GyY); Serial.print(" | GyZ = "); Serial.println(GyZ); delay(333); } |
UTILIZANDO EL MPU-6050.
El esquema que trazaremos en este caso es muy sencillo y conocido, utiliza un pin de interrupción de los que dispone el Arduino. Por lo que conectaremos el pin digital #2 del Arduino (pin de interrupción 0) al pin marcado como INT en el MPU-6050. Si el módulo de su MPU-6050 tiene un pin de 5V, entonces usted puede conectarlo al pin 5V del Arduino. En caso contrario, tendrá que conectarlo al pin 3.3V. A continuación, el GND del Arduino está conectado al GND del MPU-6050. Como el MPU-6050 que se comunica con el protocolo I2C, conectar el pin etiquetado como SDA en el MPU 6050 al pin analógico del Arduino A4 (SDA). Y el pin etiquetado como SCL en el MPU 6050 al pin analógico del Arduino A5 (SCL). Recomiendo utilizar cables flexibles y relativamente largos, ya hemos terminado el cableado al Arduino, como se muestra en el siguiente diagrama que es muy común.
Descargue la librería MPU-6050 para Arduino. Usted puede encontrar la librería aquí, descomprima /extraiga la carpeta llamada «MPU6050» y pegarla dentro de la carpeta «library» del Arduino dentro de la carpeta de bibliotecas. Haga lo mismo con la librería I2Cdevlib, si no la tiene en su Arduino.
Para utilizar el MPU-6050, debemos saber la dirección I2C con la aplicación que hice en su día para estos casos, este es el enlace.
CARGAR EL CÓDIGO Y PROBAR EL ARDUINO MPU 6050.
Si usted ha instalado correctamente la librería, vaya a la carpeta ejemplos y encontrará los archivos: MPU6050_raw.ino, MPUTeapot.pde y la carpeta MPU6050_DMP6 con el archivo que nos interesa: MPU6050_DMP6.ino es el que debe cargar en Arduino. La forma sencilla es, cuando abra el IDE Arduino, en: Archivo -> Ejemplos se puede ver el «MPU6050». A continuación, abra el programa de ejemplo de: Archivo -> ejemplos -> MPU6050 -> Ejemplos -> MPU6050_DMP6, el cual viene muy descrito y le será de utilidad leer su contenido, por dicho motivo no expondré aquí, este archivo.
Ahora, tiene que subir este código a su Arduino. Después de cargar el código, abra el monitor Serie y ajuste la velocidad de transmisión sobre 115200. A continuación compruebe si ve en el monitor de serie algo como, «Inicializando dispositivos I2C …». Si no lo ve, sólo tiene que pulsar el botón de reinicio de Arduino. Ahora, verá una línea que dice «Enviar cualquier carácter para comenzar la programación y demostración DMP:». Así que sólo tiene que escribir cualquier carácter en el monitor serie y enviarlo. Y usted comenzará a ver los valores de guiñada, cabeceo y balanceo que vienen de la MPU-6050. [Según Wikipedia. Dado un sistema de tres ejes fijos en el aeroplano, llamados eje de guiñada (yaw en inglés), de cabeceo (pitch) y de alabeo(roll), existen tres rotaciones principales, normalmente llamadas igual que el eje sobre el que se producen, que permiten alcanzar el sistema del aeroplano desde el sistema de referencia…]
Al igual que:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
/* * mpu6050.pde * * http://robologs.net/2014/10/15/tutorial-de-arduino-y-mpu-6050/ * */ #include "Wire.h" // libreria //Dirección I2C de la IMU #define MPU 0x68 // asegurarse que esta dirección I2C de la IMU // Ratios de conversion especificados en la documentación // Deberemos dividir los valores que nos dé el Giroscopio y el // Acelerómetro entre estas constantes para obtener un valor // coherente. RAD_A_DEG es la conversión de radianes a grados. #define A_R 16384.0 // aceleracion #define G_R 131.0 // giroscopo //Conversion de radianes a grados 180/PI #define RAD_A_DEG = 57.295779 //MPU-6050 da los valores en enteros de 16 bits //Valores sin refinar int16_t AcX, AcY, AcZ, GyX, GyY, GyZ; //Angulos float Acc[2]; float Gy[2]; float Angle[2]; void setup() { Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(9600); } void loop() { //Leer los valores del Acelerometro de la IMU Wire.beginTransmission(MPU); Wire.write(0x3B); //Pedir el registro 0x3B - corresponde al AcX Wire.endTransmission(false); Wire.requestFrom(MPU,6,true); //A partir del 0x3B, se piden 6 registros AcX=Wire.read()<<8|Wire.read(); //Cada valor ocupa 2 registros AcY=Wire.read()<<8|Wire.read(); AcZ=Wire.read()<<8|Wire.read(); //Se calculan los ángulos Y, X respectivamente. Acc[1] = atan(-1*(AcX/A_R)/sqrt(pow((AcY/A_R),2) + pow((AcZ/A_R),2)))*RAD_TO_DEG; Acc[0] = atan((AcY/A_R)/sqrt(pow((AcX/A_R),2) + pow((AcZ/A_R),2)))*RAD_TO_DEG; //Leer los valores del Giroscopio Wire.beginTransmission(MPU); Wire.write(0x43); Wire.endTransmission(false); Wire.requestFrom(MPU,4,true); //A diferencia del Acelerometro, solo se piden 4 registros GyX=Wire.read()<<8|Wire.read(); GyY=Wire.read()<<8|Wire.read(); //Calculo del angulo del Giroscopio Gy[0] = GyX/G_R; Gy[1] = GyY/G_R; //Aplicar el Filtro Complementario Angle[0] = 0.98 *(Angle[0]+Gy[0]*0.010) + 0.02*Acc[0]; Angle[1] = 0.98 *(Angle[1]+Gy[1]*0.010) + 0.02*Acc[1]; //Mostrar los valores por consola Serial.print("Angle X: "); Serial.print(Angle[0]); Serial.print("\n"); Serial.print("Angle Y: "); Serial.print(Angle[1]); Serial.print("\n------------\n"); delay(10); //Nuestra dt sera, pues, 0.010, que es el intervalo de tiempo en cada lectura. } |
Como ya se sabe, cada dispositivo I2C contiene una dirección única que lo representa, en el caso de la plaquita GY-521, por lo general es la dirección 0×68 o 0×69. Una buena forma de encontrar la dirección exacta es utilizando el boceto i2c_scanner, cargamos el boceto en el Arduino y en la consola serial debemos ver la dirección de nuestro módulo MPU6050.
Como leer datos RAW del sensor.
Para obtener dichos datos y al mismo tiempo obtener mayor información, podemos leer y usar el boceto publicado en el artículo MPU-6050 de ArduinoPlayGround.
Dependiendo de la dirección de nuestro modulo (0×69 o 0×68), debemos indicar dicha dirección en la constante MPU6050_I2C_ADDRESS.
Ahora en el monitor serial, debemos poder ver un conjunto de valores que arroja el módulo.
Con este boceto el monitor nos muestra los ángulos x e y que es lo que hemos pedido que muestre.
Este es un tutorial que nos sirve para entrar en este mundo de la nueva generación de sensores que la industria pone a nuestro alcance. El límite en estos momentos una vez más podemos asegurar que está en manos de los técnicos cada vez mejor formados y por supuesto ayudados por las técnicas puestas a su alcance. Volveremos sobre este dispositivo.
en que uniades nos la los datos el MPU 6050?
Hola daniel.
En el propio artículo viene descrita la respuesta, recuerda que tiene tres sensores.
1) Temperatura. ¿En que se mide la temperatura? Grados Centígrados o Fahrenheit, la respuesta.
2) Acelerómetro. ¿Con qué mide la aceleración? En metros/segundo/segundo o sea, m por segundo al cuadrado, la respuesta.
3) Giróscopo. ¿Con qué se mide un ángulo? En grados, sin entrar en más detalle, sería la respuesta.
Espero haber dado respuesta a tu pregunta.
Saludos y cuídate.