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.
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.
- ProyectoConstrucción de un rover autónomo por waypoints GPS
- ProyectoConstruya un Micromouse: robot para laberintos con Flood Fill
- ProyectoConstruya un robot mecanum omnidireccional con ESP32
- ProyectoConstruye un robot de autoequilibrio con MPU6050 y PID
- Ruta de aprendizajeFundamentos de electrónica para robótica: ruta guiada
- Ruta de aprendizajePlanificación de caminos y mapeo: de Flood Fill a SLAM
- Ruta de aprendizajeTracción holonómica: desplazamiento omnidireccional
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