Componente · Sensor

MPU6050 IMU

El sensor inercial más utilizado en robótica: 3 ejes de aceleración, 3 ejes de velocidad angular y procesador DMP integrado mediante bus I2C.

Qué es

El MPU-6050 es la forma en que un robot siente su propio movimiento. Es una unidad de medición inercial de 6 ejes: un giroscopio y un acelerómetro en un mismo chip, que informa de cómo está inclinado el robot, con qué rapidez gira y cómo se está acelerando. Donde un sensor ultrasónico mira hacia afuera al mundo, una IMU mira hacia adentro, al propio cuerpo del robot, que es lo que necesita un robot autoequilibrado o un navegador por navegación muerta.

Diagrama etiquetado de una placa adaptadora de IMU MPU-6050 (placa GY-521): un PCB morado con el chip MPU-6050 y los componentes pasivos en el centro, un indicador de ejes X/Y/Z que muestra las tres direcciones de detección, y una cabecera de 8 pines (VCC, GND, SCL, SDA, XDA, XCL, AD0, INT) a lo largo del borde inferior.
Un giroscopio y un acelerómetro en un mismo chip detectan rotación e inclinación alrededor de los tres ejes, leídos por I²C. Descargar SVG

Cómo funciona

Dentro hay dos sensores. El acelerómetro mide la aceleración lineal en X, Y y Z: en reposo, eso es solo la gravedad, que le dice al robot hacia dónde es abajo (su inclinación). El giroscopio mide con qué rapidez gira el robot alrededor de cada eje. Ambos se leen por I²C (SCL/SDA).

Ninguno de los dos sensores basta por sí solo: integra el giroscopio para obtener un ángulo y deriva lentamente; confía en el acelerómetro y es ruidoso en cuanto el robot se mueve. La solución es la fusión de sensores: combinarlos de modo que el acelerómetro corrija la deriva del giroscopio y el giroscopio suavice el ruido del acelerómetro. Esa técnica es exactamente lo que cubre el ruido de sensores, el sesgo y el filtrado.

Cuándo usarlo

Recurre a un MPU-6050 cuando un robot necesite conocer su propia orientación o movimiento:

  • Robots autoequilibrados: el ángulo de inclinación con el que lucha el lazo de control para mantenerlo en cero.
  • Rumbo y navegación muerta: detectar giros para mejorar la odometría entre lecturas de los encoders.
  • Detección de movimiento o gestos: reaccionar a que lo cojan, lo inclinen o lo sacudan.

Para medir la distancia a cosas (paredes, obstáculos) quieres un sensor de distancia como el HC-SR04 o el VL53L0X: una IMU siente al robot, no al mundo.

Cableado y errores comunes

  • I²C, 3,3–5 V. La mayoría de placas adaptadoras (la GY-521 morada) llevan regulador, así que 5 V está bien; el chip desnudo es solo de 3,3 V.
  • Filtra el giroscopio y el acelerómetro: no directions con una lectura en crudo. Una sola muestra de acelerómetro en movimiento es inservible como ángulo de inclinación.
  • El guiñada se desvía sin magnetómetro; usa el MPU-6050 para cabeceo y alabeo y para giros a corto plazo, no para rumbo absoluto de brújula.
  • Móntalo rígido y a nivel: un sensor suelto añade vibración que el filtro no puede quitar.

Patillaje

La placa adaptadora GY-521 morada es la que casi todo el mundo quiere decir con «MPU-6050». Ocho pines, y cuatro de ellos normalmente se quedan sin conectar.

Pin Nombre Qué hace Normalmente
1 VCC Alimentación. El regulador de la placa acepta 3.3–5 V; el chip desnudo es solo 3.3 V 5 V en un Uno, 3.3 V en un ESP32
2 GND Masa, compartida con el microcontrolador Conectado
3 SCL Reloj de I²C A5 en un Uno
4 SDA Datos de I²C A4 en un Uno
5 XDA Datos de I²C auxiliares, para un magnetómetro que el MPU lee en tu nombre Al aire
6 XCL Reloj de I²C auxiliar Al aire
7 AD0 Selección de dirección. Low (por defecto) = 0x68, high = 0x69 Al aire, o a high para un segundo sensor
8 INT Salida de interrupción: dispara con datos listos, movimiento o caída libre Al aire, hasta que quieras dejar de sondear

AD0 es el pin que hace posibles dos MPU-6050 en un mismo bus, y es la razón de que aquí la colisión de direcciones tenga una respuesta fácil que la mayoría de los sensores no ofrecen.

Cablearlo a un Arduino

MPU-6050 Arduino Uno ESP32 Nota
VCC 5 V 3.3 V El regulador de a bordo cubre ambos
GND GND GND Debe ser común con todo lo demás
SCL A5 GPIO 22 No añadas pull-ups externos: la placa ya tiene 2.2 kΩ
SDA A4 GPIO 21 Igual
AD0 — — Conéctalo a VCC solo para un segundo sensor

Hay un detalle que conviene saber en un Arduino de 5 V. Las resistencias de pull-up de la GY-521 van a su riel regulado de 3,3 V, así que las líneas de I²C quedan en reposo a 3,3 V, no a 5 V. Un ATmega328P lee alto por encima de 0,6 × Vcc = 3,0 V, así que 3,3 V supera el umbral, pero solo por 0,3 V. En la práctica funciona de forma fiable, y es una de las razones por las que un tramo de I²C largo o ruidoso se comporta mal en esta placa antes que en una de 5 V.

Leerlo: los registros que importan

Puedes manejar este sensor con una biblioteca y no ver nunca un registro, pero cuatro de ellos explican casi todos los problemas que la gente tiene con él.

Registro Dirección Por qué te importa
PWR_MGMT_1 0x6B El chip arranca dormido. Escribe 0 aquí o toda lectura será cero
WHO_AM_I 0x75 Devuelve 0x68: la forma más rápida de probar que el cableado está bien
GYRO_CONFIG 0x1B Rango de fondo de escala: ±250, ±500, ±1000, ±2000 °/s
ACCEL_CONFIG 0x1C Rango de fondo de escala: ±2, ±4, ±8, ±16 g
ACCEL_XOUT_H 0x3B Inicio de 14 bytes: 6 de aceleración, 2 de temperatura, 6 de giroscopio; léelos en una sola ráfaga

Los dos registros de configuración fijan el factor de escala por el que divides las cuentas en crudo, y equivocarse es la causa más habitual de «mis ángulos son cuatro veces más grandes»:

Ajuste de rango LSB del giroscopio por °/s Ajuste de rango LSB del acelerómetro por g
±250 °/s (por defecto) 131 ±2 g (por defecto) 16384
±500 °/s 65.5 ±4 g 8192
±1000 °/s 32.8 ±8 g 4096
±2000 °/s 16.4 ±16 g 2048

Elige el rango más pequeño que no sature. Un robot equilibrador rara vez pasa de ±250 °/s, y el rango estrecho te da cuatro veces la resolución de ±1000 °/s gratis.

Código mínimo funcional

Sin biblioteca: esto es todo, y merece la pena ejecutarlo una vez para saber qué está haciendo la biblioteca por ti.

#include <Wire.h>

const uint8_t MPU = 0x68;          // 0x69 if AD0 is tied high

void setup() {
  Serial.begin(115200);
  Wire.begin();

  Wire.beginTransmission(MPU);
  Wire.write(0x6B);                 // PWR_MGMT_1
  Wire.write(0);                    // wake up — the chip boots asleep
  Wire.endTransmission(true);
}

void loop() {
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);                 // ACCEL_XOUT_H
  Wire.endTransmission(false);      // repeated start, do not release the bus
  Wire.requestFrom(MPU, (uint8_t)14);

  int16_t ax = Wire.read() << 8 | Wire.read();
  int16_t ay = Wire.read() << 8 | Wire.read();
  int16_t az = Wire.read() << 8 | Wire.read();
  Wire.read(); Wire.read();         // temperature, discarded here
  int16_t gx = Wire.read() << 8 | Wire.read();
  int16_t gy = Wire.read() << 8 | Wire.read();
  int16_t gz = Wire.read() << 8 | Wire.read();

  // Default ranges: +/-2 g and +/-250 deg/s
  float pitch = atan2(ax, sqrt((float)ay * ay + (float)az * az)) * 57.2958f;
  float rateY = gy / 131.0f;        // deg/s

  Serial.print(pitch); Serial.print(' '); Serial.println(rateY);
  delay(20);
}

Dos cosas que esto deliberadamente no hace: nunca fusiona los dos sensores, y nunca resta un sesgo. Las dos vienen ahora.

Calibración: las veinte líneas que más importan

En reposo un giroscopio no lee cero. Lee un desplazamiento pequeño y bastante constante, y como integras el giroscopio para obtener un ángulo, ese desplazamiento se integra en un error que crece sin parar. Un sesgo de solo 2 °/s sin corregir son 120° de deriva al cabo de un minuto.

Promedia unos cientos de muestras con el sensor completamente quieto y luego resta:

long sum = 0;
for (int i = 0; i < 500; i++) { sum += readGyroY(); delay(3); }
const float gyroBias = sum / 500.0f;   // subtract from every later reading

Tres notas prácticas que la ficha técnica no te va a decir:

  • Hazlo en cada encendido, no una vez. El sesgo del giroscopio se mueve con la temperatura, y un robot que lleva diez minutos en marcha no es el robot que calibraste en frío.
  • «Quieto» significa quieto. Una calibración hecha mientras alguien se apoya en el escritorio graba ese movimiento en el sesgo de forma permanente.
  • El acelerómetro necesita una referencia de nivel, no un cero. Debe leer 1 g en el eje que apunte hacia abajo. Si lee 0,97 g, ese es tu error de escala, y aparecerá como un ángulo de inclinación que siempre se va un par de grados.

Por qué un solo sensor nunca basta

Los dos sensores fallan de exactamente manera opuesta, y por eso fusionarlos funciona tan bien.

Acelerómetro Giroscopio
Mide Aceleración lineal: en reposo, la gravedad Velocidad de rotación
Da la inclinación con Trigonometría sobre el vector de gravedad Integrando la velocidad a lo largo del tiempo
A corto plazo Ruidoso: cada golpe y vibración también es aceleración Excelente, suave, con respuesta
A largo plazo Correcto en promedio: la gravedad no deriva Deriva sin límite a medida que se integra el sesgo
Falla cuando El robot acelera, así que «abajo» ya no es abajo Siempre, poco a poco

Un filtro complementario se queda con la buena mitad de cada uno: confía en el giroscopio a corto plazo y deja que el acelerómetro tire poco a poco de la estimación de vuelta hacia la verdad:

angle = 0.98f * (angle + rate * dt) + 0.02f * accelAngle;

Ese 0,02 fija el punto de conmutación. Un valor más alto confía más tiempo en el giroscopio, lo que es más suave pero deriva más; uno más bajo responde al ruido del acelerómetro. El tutorial del filtro complementario analiza cómo elegirlo a conciencia en lugar de por sensación.

Resolución de problemas

Síntoma Causa probable Solución
Todas las lecturas son exactamente 0 El chip sigue dormido Escribe 0 en PWR_MGMT_1 (0x6B) después de Wire.begin()
El escáner de bus no encuentra nada Dirección de 8 bits sacada de la ficha técnica El 0xD0 de la ficha es 0x68 desplazado: usa 0x68
Dos sensores y solo aparece uno Los dos en la dirección por defecto Liga el AD0 de una placa a VCC para que responda en 0x69
Los ángulos son 4× u 8× demasiado grandes El factor de escala no corresponde al rango configurado Haz coincidir el divisor con GYRO_CONFIG/ACCEL_CONFIG
El ángulo se desvía de forma constante incluso en reposo Sesgo del giroscopio sin calibrar Promedia 500 muestras quietas al arrancar y resta
La inclinación salta mientras conduces Estás usando el ángulo del acelerómetro en crudo Fusiona con el giroscopio; el «abajo» de un robot en movimiento no es abajo
Las lecturas se congelan al rato Bus I²C bloqueado Comprueba los pull-ups; añade una rutina de recuperación que genere nueve pulsos de reloj en SCL
El rumbo gira lentamente sin parar La guiñada no tiene referencia absoluta Es lo esperado: la guiñada necesita un magnetómetro u otra fuente absoluta
Ruidoso por encima de unos 1 kHz de vibración Montaje rígido transmitiendo la vibración de los motores Monta el sensor con algo de amortiguación; activa el DLPF del chip vía CONFIG (0x1A)

¿MPU-6050 o algo más nuevo?

El MPU-6050 está fuera de producción en el fabricante y sigue siendo la IMU más usada en robótica de afición, porque es barata, está documentada en todas partes y la admiten todas las bibliotecas.

Componente Ejes Diferencia destacada Elígelo cuando
MPU-6050 6 El de referencia; enorme cantidad de código de ejemplo Aprender, equilibrar, cualquier primer proyecto con IMU
MPU-9250 9 Añade un magnetómetro, así la guiñada tiene referencia absoluta Necesitas rumbo de brújula, no solo velocidad de giro
ICM-20948 9 El sucesor actual en producción del MPU-9250 Diseños nuevos que necesiten 9 ejes y disponibilidad a largo plazo
BNO055 9 Hace la fusión en el chip y entrega la orientación directamente Quieres un ángulo sin escribir un filtro, a varios veces el precio
LSM6DS3 6 Moderno, en producción, con menos ruido Una mejora directa cuando se agota el suministro de MPU-6050

El resumen honesto: si tu robot necesita cabeceo y alabeo, que es lo que necesita el equilibrio, el MPU-6050 es más que suficiente y la fusión es algo que está bien que escribas tú mismo. Si necesita rumbo absoluto, ningún cantidad de filtrado lo sacará de seis ejes, y lo que quieres es un magnetómetro.

Explora el grafo

Se usa en estos montajes

Proyectos, rutas de aprendizaje y simuladores que incluyen MPU6050 IMU.

Preguntas

Preguntas frecuentes sobre MPU6050 IMU

¿Qué es el sensor MPU-6050?

El MPU-6050 es una unidad de medición inercial (IMU) de 6 ejes montada en una pequeña placa breakout. Combina un giroscopio de 3 ejes y un acelerómetro de 3 ejes, de modo que un robot puede saber cuánto está inclinado, a qué velocidad gira y cómo acelera, todo ello leído por el bus I²C.

¿Cómo funciona el MPU-6050?

Dentro hay dos sensores. El acelerómetro mide la aceleración lineal; en reposo eso es solo la gravedad, que le dice al robot qué dirección es abajo (su inclinación). El giroscopio mide la velocidad de rotación alrededor de cada eje. Lees ambos por I²C y luego los fusionas para obtener una orientación estable que ninguno de los dos da por separado.

¿Para qué se usa el MPU-6050?

Para que el robot perciba su propio movimiento: mantener erguido un robot autoequilibrado, estimar el rumbo y mejorar la odometría entre lecturas de los encoders, y detectar que lo han volcado, levantado o sacudido. Percibe al propio robot, no el mundo que lo rodea, así que complementa a un sensor de distancia en lugar de sustituirlo.

¿Cómo se calibra un MPU-6050?

En reposo, el giroscopio y el acelerómetro dan pequeños offsets distintos de cero. Calibra promediando unos cientos de muestras mientras el sensor está completamente quieto y resta después esos offsets de cada lectura. El giroscopio lo necesita especialmente: el sesgo sin calibrar es lo que hace que el ángulo estimado derive más rápido.

¿Cómo se conecta un MPU-6050 a un ESP32 o a un Arduino?

Por I²C: conecta SDA y SCL a los pines I²C de la placa, además de la alimentación y la masa. La placa breakout morada GY-521 lleva un regulador, así que funciona con 3.3 V en un ESP32 o con 5 V en un Arduino Uno. Después, una biblioteca lee por ti los registros del giroscopio y del acelerómetro.

Lecturas adicionales

Referencias