MPU6050 Arduino: acelerómetro, giroscopio y ángulo de inclinación
MPU6050 con Arduino: conexión, dirección I2C, valores en bruto, calibración, inclinación con atan2 y filtro complementario; librería Adafruit, ESP32 y Pico.
El MPU6050 reúne en un solo chip diminuto un acelerómetro de 3 ejes y un giroscopio de 3 ejes, y es el sensor de movimiento más usado en proyectos con Arduino. Mide cuánto se inclina la placa, hacia dónde y a qué velocidad gira, y si se sacude o se cae. Con él se construyen robots que se mantienen en equilibrio, drones, estabilizadores de cámara (gimbal), podómetros y juegos controlados con el movimiento. El MPU6050 se conecta a Arduino con solo cuatro cables, por I2C.
En este artículo aprenderás paso a paso cómo funciona el MPU6050, sus ejes y valores en bruto, la conexión I2C, la lectura con y sin librería, la calibración, el cálculo del ángulo de inclinación con atan2 y el filtro complementario, que combina los puntos fuertes de ambos sensores. Después montaremos con un ESP32 una alarma que detecta caídas y escribiremos código MicroPython para la Raspberry Pi Pico.

¿Qué es el MPU6050 y cómo funciona?
El MPU6050, fabricado por InvenSense (hoy TDK), es una IMU, es decir, una unidad de medición inercial. En su interior hay diminutas estructuras mecánicas de silicio (MEMS). El acelerómetro mide cuánto se desplaza una pequeña masa sujeta con muelles cuando hay aceleración; como detecta la gravedad incluso en reposo, un sensor apoyado plano sobre la mesa marca unos 1 g (9,81 m/s²) en el eje Z, y así puedes calcular su inclinación respecto al suelo. El giroscopio mide la velocidad angular, es decir, cuántos grados por segundo gira el sensor, a partir de la fuerza de Coriolis que actúa sobre estructuras que vibran. Las medidas se convierten en números con ADC de 16 bits dentro del chip y se leen por I2C. El chip incluye además un sensor de temperatura y un procesador digital de movimiento (DMP) capaz de encargarse de los cálculos de orientación.
| Característica | Valor |
|---|---|
| Sensores | Acelerómetro de 3 ejes + giroscopio de 3 ejes + temperatura |
| Rango del acelerómetro | ±2, ±4, ±8, ±16 g |
| Rango del giroscopio | ±250, ±500, ±1000, ±2000 °/s |
| Resolución | 16 bits (de -32768 a 32767 por eje) |
| Comunicación | I2C, hasta 400 kHz |
| Dirección I2C | 0x68 (AD0 a GND) o 0x69 (AD0 a 3,3 V) |
| Tensión del chip | 2,375–3,46 V (la placa GY-521 admite 3,3–5 V) |
| Consumo | Unos 3,9 mA (5 µA en reposo) |
| Extras | DMP, FIFO de 1024 bytes, interrupción por movimiento, I2C auxiliar para un sensor externo |
Ejes, valores en bruto y sensibilidad
Las flechas de la placa indican los ejes X e Y; el eje Z es perpendicular a la placa y apunta hacia arriba. El sensor da un número de 16 bits con signo para cada eje. Para pasar ese valor en bruto a una unidad física, lo divides entre la sensibilidad correspondiente al rango elegido. Por ejemplo, en el rango por defecto de ±2 g, un valor en bruto de 16384 equivale a 1 g; con el sensor quieto sobre la mesa leerás az ≈ 16384 y ax, ay ≈ 0. En el giroscopio, con el rango de ±250 °/s, un valor de 131 corresponde a un giro de 1 grado por segundo. Un rango más amplio mide movimientos más bruscos pero muestra los cambios pequeños con menos detalle, así que elige el rango más estrecho que baste para tu proyecto.
| Ajuste | Rango del acelerómetro | LSB/g | Rango del giroscopio | LSB/(°/s) |
|---|---|---|---|---|
| 0 | ±2 g | 16384 | ±250 °/s | 131 |
| 1 | ±4 g | 8192 | ±500 °/s | 65,5 |
| 2 | ±8 g | 4096 | ±1000 °/s | 32,8 |
| 3 | ±16 g | 2048 | ±2000 °/s | 16,4 |
El chip también mide la temperatura: °C = valor en bruto / 340 + 36,53. Este valor refleja más la temperatura del propio chip que la del ambiente, pero como el punto cero del giroscopio varía con la temperatura, es útil para correcciones avanzadas.
Conexión del MPU6050: Arduino Uno, ESP32 y Pico
| Pin del MPU6050 | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | 3V3 | 3V3(OUT) |
| GND | GND | GND | GND |
| SCL | A5 | GPIO 22 | GP5 |
| SDA | A4 | GPIO 21 | GP4 |
| AD0 | Libre (dirección 0x68) | Libre (dirección 0x68) | Libre (dirección 0x68) |
| INT | D2 (opcional) | Cualquier GPIO (opcional) | Cualquier pin GP (opcional) |
| XDA, XCL | Sin conectar | Sin conectar | Sin conectar |
Como la placa GY-521 lleva un regulador de 3,3 V, puedes conectar VCC al pin 5V del Uno. El pin AD0 está llevado a GND en la placa mediante una resistencia de 4,7 kΩ, así que la dirección es 0x68 si lo dejas libre; si quieres usar dos MPU6050 en el mismo bus, conecta el AD0 de uno de ellos a 3,3 V para cambiar su dirección a 0x69. El pin INT avisa cuando hay datos nuevos o se detecta movimiento; en proyectos sencillos no hace falta conectarlo. Después de cablear, es buena costumbre comprobar con un escáner I2C que el sensor aparece; verás cómo hacerlo en Pantalla LCD I2C.
Inicio rápido con librería: Adafruit MPU6050
- Abre el Gestor de librerías en el Arduino IDE y busca Adafruit MPU6050.
- Cuando pregunte por las dependencias durante la instalación, elige Install all; así también se instalan Adafruit Unified Sensor y Adafruit BusIO.
- Conecta el sensor como en la tabla, sube el código siguiente y abre el Monitor Serie a 115200 baudios.
- Abre el Serial Plotter desde el menú Herramientas para ver los seis ejes en gráficas en directo; al inclinar la placa cambian las curvas de aceleración y al girarla, las del giroscopio.
1#include <Wire.h>
2#include <Adafruit_MPU6050.h>
3#include <Adafruit_Sensor.h>
4
5Adafruit_MPU6050 mpu;
6
7void setup() {
8 Serial.begin(115200);
9 if (!mpu.begin()) { // varsayılan adres 0x68 / default address 0x68
10 Serial.println("MPU6050 bulunamadi / not found");
11 while (true) delay(10);
12 }
13 mpu.setAccelerometerRange(MPU6050_RANGE_4_G); // ±4 g
14 mpu.setGyroRange(MPU6050_RANGE_500_DEG); // ±500 °/s
15 mpu.setFilterBandwidth(MPU6050_BAND_21_HZ); // titreşimi süz / filter out vibration
16}
17
18void loop() {
19 sensors_event_t a, g, t;
20 mpu.getEvent(&a, &g, &t);
21 Serial.print("ax:"); Serial.print(a.acceleration.x); // m/s²
22 Serial.print(" ay:"); Serial.print(a.acceleration.y);
23 Serial.print(" az:"); Serial.print(a.acceleration.z);
24 Serial.print(" gx:"); Serial.print(g.gyro.x); // rad/s
25 Serial.print(" gy:"); Serial.print(g.gyro.y);
26 Serial.print(" gz:"); Serial.print(g.gyro.z);
27 Serial.print(" T:"); Serial.println(t.temperature); // °C
28 delay(100);
29}La librería de Adafruit da los resultados directamente en unidades físicas: aceleración en m/s², velocidad angular en rad/s y temperatura en °C. Para pasar el valor del giroscopio a grados por segundo, basta con multiplicarlo por 57,3. El filtro paso bajo interno que eliges con setFilterBandwidth reduce el ruido de las vibraciones: 21 Hz es un buen punto de partida para movimientos de la mano, y si quieres captar golpes cortos, elige 94 o 260 Hz. Al arrancar, la librería lee el registro de identidad del chip (WHO_AM_I) y begin() devuelve false si no vale 0x68.
Lectura sin librería, calibración y ángulo de inclinación
Las librerías facilitan el trabajo, pero leer los registros directamente enseña mucho sobre lo que pasa dentro del sensor. El MPU6050 arranca en modo reposo; primero hay que despertarlo escribiendo 0 en el registro 0x6B (PWR_MGMT_1). Luego lees 14 bytes a partir de la dirección 0x3B: 6 bytes de aceleración, 2 de temperatura y 6 de giroscopio. Cada valor ocupa dos bytes, primero el más significativo. Estos son los registros principales que usa el código y que conviene conocer:
| Registro | Dirección | Función |
|---|---|---|
| SMPLRT_DIV | 0x19 | Divisor de la frecuencia de muestreo |
| CONFIG | 0x1A | Filtro paso bajo interno (DLPF) |
| GYRO_CONFIG | 0x1B | Rango del giroscopio (±250 … ±2000 °/s) |
| ACCEL_CONFIG | 0x1C | Rango del acelerómetro (±2 … ±16 g) |
| ACCEL_XOUT_H | 0x3B | Dirección donde empiezan las medidas (14 bytes) |
| PWR_MGMT_1 | 0x6B | Reposo y fuente de reloj; escribir 0 lo despierta |
| WHO_AM_I | 0x75 | Identidad; un MPU6050 original devuelve 0x68 |
Con el sensor en reposo, la única fuerza que ve el acelerómetro es la gravedad. Según cómo se reparte la gravedad entre los ejes, obtienes dos ángulos: el alabeo alrededor del eje X, roll = atan2(ay, az), y el cabeceo alrededor del eje Y, pitch = atan2(−ax, √(ay² + az²)). A diferencia del arcotangente normal, atan2 da el signo correcto en los cuatro cuadrantes y no divide entre cero cuando az se acerca a cero. Por ejemplo, si lees ay = 8192 y az = 14189, roll = atan2(8192, 14189) ≈ 30°. En cambio, el giro alrededor del eje Z (guiñada o yaw) es invisible para el acelerómetro, porque no cambia el reparto de la gravedad entre los ejes.
Los dos sensores tienen un punto débil. El acelerómetro es exacto a largo plazo, pero muy ruidoso durante el movimiento y las vibraciones, porque además de la gravedad mide la propia aceleración del movimiento. El giroscopio es suave a corto plazo, pero para obtener un ángulo sumas la velocidad angular a lo largo del tiempo (ángulo += velocidad × dt), y hasta una pequeña desviación se acumula y va desplazando el ángulo poco a poco. El filtro complementario combina ambos: ángulo = 0,98 × (ángulo + giroscopio × dt) + 0,02 × ángulo del acelerómetro. A corto plazo confía en el giroscopio y a largo plazo, en el acelerómetro. A 100 Hz (dt = 0,01 s), estos coeficientes dan una constante de tiempo de aproximadamente medio segundo: τ = 0,98 × 0,01 / 0,02 = 0,49 s.
La calibración es al menos tan importante como el filtro. Incluso un giroscopio completamente quieto puede mostrar una desviación constante (offset) de unos pocos °/s; si no la corriges, el ángulo calculado se desvía decenas de grados en segundos. El código siguiente promedia 500 lecturas al arrancar, con el sensor quieto, y resta ese valor de cada lectura posterior. Durante la calibración deja la placa sobre una superficie plana y no la toques; después observa las curvas de roll, pitch y yaw en el Serial Plotter.
1#include <Wire.h>
2
3const int MPU_ADDR = 0x68; // AD0 GND'de ya da boşta / AD0 to GND or floating
4const float GYRO_LSB = 131.0; // ±250 °/s aralığında 1 °/s / 1 °/s at the ±250 °/s range
5const float ALPHA = 0.98; // tamamlayıcı filtre katsayısı / complementary filter weight
6
7int16_t ax, ay, az, tempRaw, gx, gy, gz;
8float gxOff = 0, gyOff = 0, gzOff = 0; // jiroskop sapmaları / gyro offsets
9float roll = 0, pitch = 0, yaw = 0;
10unsigned long lastMicros;
11
12void writeReg(uint8_t reg, uint8_t val) {
13 Wire.beginTransmission(MPU_ADDR);
14 Wire.write(reg);
15 Wire.write(val);
16 Wire.endTransmission();
17}
18
19int16_t read16() {
20 uint8_t hi = Wire.read(); // önce yüksek bayt / high byte first
21 uint8_t lo = Wire.read();
22 return (int16_t)(((uint16_t)hi << 8) | lo);
23}
24
25void readMPU() {
26 Wire.beginTransmission(MPU_ADDR);
27 Wire.write(0x3B); // ACCEL_XOUT_H
28 Wire.endTransmission(false); // hattı bırakma, tekrar başlat / repeated start
29 Wire.requestFrom(MPU_ADDR, 14); // ivme 6 + sıcaklık 2 + jiroskop 6 bayt / accel 6 + temp 2 + gyro 6 bytes
30 ax = read16(); ay = read16(); az = read16();
31 tempRaw = read16();
32 gx = read16(); gy = read16(); gz = read16();
33}
34
35void calibrateGyro() {
36 const int N = 500;
37 long sx = 0, sy = 0, sz = 0;
38 for (int i = 0; i < N; i++) {
39 readMPU();
40 sx += gx; sy += gy; sz += gz;
41 delay(3);
42 }
43 gxOff = sx / (float)N;
44 gyOff = sy / (float)N;
45 gzOff = sz / (float)N;
46}
47
48void setup() {
49 Serial.begin(115200);
50 Wire.begin();
51 Wire.setClock(400000); // 400 kHz hızlı mod / 400 kHz fast mode
52 writeReg(0x6B, 0x00); // PWR_MGMT_1: uykudan uyandır / wake up
53 writeReg(0x1A, 0x03); // CONFIG: alçak geçiren filtre ~44 Hz / low-pass ~44 Hz
54 writeReg(0x1B, 0x00); // GYRO_CONFIG: ±250 °/s
55 writeReg(0x1C, 0x00); // ACCEL_CONFIG: ±2 g
56 delay(100);
57 Serial.println("Kalibrasyon: sensoru oynatma / calibrating: keep still");
58 calibrateGyro();
59 readMPU();
60 roll = atan2(ay, az) * RAD_TO_DEG; // başlangıç açıları / initial angles
61 pitch = atan2(-ax, sqrt((float)ay * ay + (float)az * az)) * RAD_TO_DEG;
62 lastMicros = micros();
63}
64
65void loop() {
66 readMPU();
67 unsigned long now = micros();
68 float dt = (now - lastMicros) / 1000000.0; // saniye / seconds
69 lastMicros = now;
70
71 float accRoll = atan2(ay, az) * RAD_TO_DEG; // ivmeölçerden açı / angle from accelerometer
72 float accPitch = atan2(-ax, sqrt((float)ay * ay + (float)az * az)) * RAD_TO_DEG;
73 float gxRate = (gx - gxOff) / GYRO_LSB; // °/s
74 float gyRate = (gy - gyOff) / GYRO_LSB;
75 float gzRate = (gz - gzOff) / GYRO_LSB;
76
77 roll = ALPHA * (roll + gxRate * dt) + (1 - ALPHA) * accRoll; // tamamlayıcı filtre / complementary filter
78 pitch = ALPHA * (pitch + gyRate * dt) + (1 - ALPHA) * accPitch;
79 yaw += gzRate * dt; // yalnız jiroskop: zamanla kayar / gyro only: drifts over time
80
81 Serial.print("roll:"); Serial.print(roll, 1);
82 Serial.print(" pitch:"); Serial.print(pitch, 1);
83 Serial.print(" yaw:"); Serial.println(yaw, 1);
84 delay(10); // yaklaşık 100 Hz / about 100 Hz
85}| Línea de código | ¿Qué hace? |
|---|---|
| writeReg(0x6B, 0x00) | Saca el sensor del modo reposo |
| writeReg(0x1A, 0x03) | Activa el filtro interno de unos 44 Hz |
| Wire.requestFrom(MPU_ADDR, 14) | Lee aceleración, temperatura y giroscopio de una vez |
| calibrateGyro() | Calcula la desviación del giroscopio promediando 500 lecturas |
| atan2(ay, az) * RAD_TO_DEG | Calcula el ángulo roll en grados a partir del acelerómetro |
| ALPHA * (...) + (1 - ALPHA) * ... | Filtro complementario: combina giroscopio y acelerómetro |
| yaw += gzRate * dt | Calcula yaw solo con el giroscopio; verás cómo se desvía con el tiempo |
MPU6050 con ESP32: alarma de detección de caídas
En el ESP32 la conexión es igual que en el Uno; solo cambian los pines I2C, que son GPIO 21 (SDA) y GPIO 22 (SCL), y el módulo se alimenta desde 3V3. Todos los códigos anteriores funcionan sin cambios en el ESP32; si quieres, puedes fijar los pines con Wire.begin(21, 22). El ejemplo siguiente es un detector de caídas. En un objeto en caída libre, el acelerómetro lee casi 0 g, porque el cuerpo del sensor y la masa interior caen juntos; el impacto posterior produce un pico de varios g. Si el código detecta una caída libre de al menos 100 ms seguida, en el medio segundo siguiente, de un golpe de más de 2,5 g, hace sonar durante un segundo un zumbador activo conectado a GPIO 25. Una caída libre de 100 ms equivale a caer desde unos 5 cm de altura (h = ½ × g × t²).
1#include <Wire.h>
2#include <Adafruit_MPU6050.h>
3#include <Adafruit_Sensor.h>
4
5Adafruit_MPU6050 mpu;
6const int BUZZER_PIN = 25; // aktif buzzer / active buzzer
7const float FREE_FALL_G = 0.4; // serbest düşüş eşiği / free-fall threshold
8const float IMPACT_G = 2.5; // darbe eşiği / impact threshold
9unsigned long fallStart = 0, fallEnd = 0;
10
11void setup() {
12 Serial.begin(115200);
13 pinMode(BUZZER_PIN, OUTPUT);
14 Wire.begin(21, 22); // SDA, SCL
15 if (!mpu.begin(0x68, &Wire)) {
16 Serial.println("MPU6050 bulunamadi / not found");
17 while (true) delay(10);
18 }
19 mpu.setAccelerometerRange(MPU6050_RANGE_8_G); // darbeler için geniş aralık / wide range for impacts
20 mpu.setFilterBandwidth(MPU6050_BAND_94_HZ); // kısa darbeleri kaçırma / keep short peaks
21}
22
23void loop() {
24 sensors_event_t a, g, t;
25 mpu.getEvent(&a, &g, &t);
26 float x = a.acceleration.x, y = a.acceleration.y, z = a.acceleration.z;
27 float total = sqrt(x * x + y * y + z * z) / SENSORS_GRAVITY_STANDARD; // toplam ivme, g / total acceleration in g
28 unsigned long now = millis();
29
30 if (total < FREE_FALL_G) {
31 if (fallStart == 0) fallStart = now; // düşüş başladı / fall started
32 } else if (fallStart != 0) {
33 if (now - fallStart > 100) fallEnd = now; // en az 100 ms süren düşüş / fall of at least 100 ms
34 fallStart = 0;
35 }
36
37 if (fallEnd != 0 && now - fallEnd < 500 && total > IMPACT_G) { // düşüşten sonra 0,5 s içinde darbe / impact within 0.5 s
38 Serial.println("DUSME ALGILANDI / FALL DETECTED");
39 digitalWrite(BUZZER_PIN, HIGH);
40 delay(1000);
41 digitalWrite(BUZZER_PIN, LOW);
42 fallEnd = 0;
43 }
44 if (fallEnd != 0 && now - fallEnd >= 500) fallEnd = 0; // darbe gelmedi, sıfırla / no impact, reset
45 delay(5);
46}A partir de aquí puedes añadir el Wi-Fi del ESP32 para, por ejemplo, enviar una notificación de Telegram al móvil si un familiar mayor se cae, o mostrar los ángulos en directo en una página web. Ajusta los umbrales con tus propias pruebas: una caja que cae de la mesa y un sensor en la muñeca dan picos distintos. Para elegir y conectar el zumbador, consulta ¿Qué es un zumbador?.
MPU6050 con Raspberry Pi Pico (MicroPython)
En la Pico no hace falta ninguna librería extra; la clase I2C integrada en MicroPython puede leer los registros directamente. Conecta el sensor al bus I2C0, con SDA en GP4 y SCL en GP5. Con struct.unpack convertimos los 14 bytes en siete números de 16 bits con signo; ">" significa big-endian (primero el byte más significativo) y "h", entero de 16 bits con signo. El código muestra primero las direcciones I2C encontradas; si no ves 0x68 en la lista, revisa el cableado. Para simplificar no hemos añadido calibración; si la necesitas, aplica igual el método de promediado del código de Arduino.
1from machine import Pin, I2C
2import math, struct, time
3
4MPU = 0x68
5i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
6print("Bulunan adresler / found addresses:", [hex(a) for a in i2c.scan()])
7
8i2c.writeto_mem(MPU, 0x6B, b"\x00") # uykudan uyandır / wake up
9i2c.writeto_mem(MPU, 0x1A, b"\x03") # alçak geçiren filtre ~44 Hz / low-pass ~44 Hz
10i2c.writeto_mem(MPU, 0x1B, b"\x00") # jiroskop ±250 °/s / gyro ±250 °/s
11i2c.writeto_mem(MPU, 0x1C, b"\x00") # ivmeölçer ±2 g / accelerometer ±2 g
12roll = pitch = 0.0
13last = time.ticks_us()
14
15while True:
16 data = i2c.readfrom_mem(MPU, 0x3B, 14)
17 ax, ay, az, t, gx, gy, gz = struct.unpack(">hhhhhhh", data) # büyük endian, işaretli / big-endian, signed
18 now = time.ticks_us()
19 dt = time.ticks_diff(now, last) / 1000000
20 last = now
21 acc_roll = math.degrees(math.atan2(ay, az))
22 acc_pitch = math.degrees(math.atan2(-ax, math.sqrt(ay * ay + az * az)))
23 roll = 0.98 * (roll + gx / 131 * dt) + 0.02 * acc_roll # tamamlayıcı filtre / complementary filter
24 pitch = 0.98 * (pitch + gy / 131 * dt) + 0.02 * acc_pitch
25 temp = t / 340 + 36.53 # °C
26 print("roll {:.1f} pitch {:.1f} T {:.1f}".format(roll, pitch, temp))
27 time.sleep_ms(10)Ideas de proyectos con el MPU6050
- Nivel de burbuja digital: muestra los ángulos roll y pitch en una pantalla OLED con una burbuja que se mueve.
- Servo controlado con el movimiento: al inclinar el sensor en tu mano, un servomotor gira al mismo ángulo; ideal para un brazo robótico o un cabezal de cámara.
- Juego por inclinación: juega a Pong o a un laberinto inclinando la placa en lugar de usar un joystick.
- Robot autoequilibrado: procesa el ángulo pitch con un PID y mantén el robot en pie con motores DC controlados por un L298N.
- Podómetro: mide la marcha contando los picos regulares de la aceleración total.
- Registrador de vibraciones: mide las sacudidas de una máquina o de la lavadora y avisa cuando se supere un umbral.
Errores frecuentes y soluciones
| Síntoma | Causa probable | Solución |
|---|---|---|
| begin() devuelve false ("MPU6050 not found") | Error de cableado, dirección incorrecta o chip clónico | Busca la dirección con un escáner I2C; si WHO_AM_I no es 0x68 (por ejemplo 0x70), usa el código sin librería |
| Todos los valores son 0 | El sensor está en reposo | Escribe 0 en el registro 0x6B |
| Valores -1 o congelados | Cable suelto, bus I2C largo | Acorta los cables y suelda los pines |
| El ángulo se desvía en reposo | Desviación del giroscopio sin corregir | Calibra al arrancar con el sensor quieto |
| El ángulo salta al moverse | Solo se usa el acelerómetro | Añade un filtro complementario |
| Yaw se desvía sin parar | El MPU6050 no tiene brújula | Añade un magnetómetro como el QMC5883L o usa un sensor de 9 ejes |
| Roll falla cuando pitch se acerca a ±90° | Singularidad de los ángulos de Euler | Evita esa zona o usa la salida en cuaterniones del DMP |
A pesar de su bajo precio, el MPU6050 abre la puerta a medir el movimiento: primero conoce los valores en bruto, luego calcula los ángulos y por último suavízalos con un filtro. Para ver otros sensores I2C y sus usos, echa un vistazo a la Guía de sensores para Arduino. En la app BlueGrays encontrarás proyectos de control de servos, pantallas I2C, joystick y robots con esquema y código paso a paso que puedes combinar con el MPU6050.
Preguntas frecuentes
¿Para qué sirve el MPU6050?
El MPU6050 mide la inclinación, la velocidad de giro y la aceleración de un objeto. Se usa en robots autoequilibrados, drones y gimbals, podómetros, detección de caídas y golpes, y juegos controlados con el movimiento.
¿La dirección del MPU6050 es 0x68 o 0x69?
La dirección es 0x68 si el pin AD0 está libre o conectado a GND, y 0x69 si está conectado a 3,3 V. En la placa GY-521, AD0 está llevado a GND con una resistencia, así que la dirección por defecto es 0x68. Para asegurarte, ejecuta un escáner I2C.
¿El MPU6050 funciona con 5 V?
El chip MPU6050 admite como máximo 3,46 V, pero gracias al regulador de la placa GY-521 el pin VCC se puede alimentar con 5 V. Las líneas I2C se quedan a nivel de 3,3 V, que el Arduino Uno lee sin problemas. A las placas sin regulador no se les deben aplicar 5 V.
¿Cómo se calcula el ángulo con el MPU6050?
Con el sensor quieto, los ángulos salen del acelerómetro con roll = atan2(ay, az) y pitch = atan2(−ax, √(ay² + az²)). Para obtener resultados precisos en movimiento, se integra en el tiempo la velocidad angular del giroscopio y se combina con el ángulo del acelerómetro mediante un filtro complementario o de Kalman.
¿Puede el MPU6050 medir el ángulo yaw?
Durante poco tiempo, sí: el yaw se calcula integrando la velocidad angular del eje Z. Pero como el MPU6050 no tiene magnetómetro, el yaw se desvía con el tiempo y no conoce la orientación absoluta (el norte). Para una orientación estable necesitas una brújula como el QMC5883L o una IMU de 9 ejes.
¿Qué diferencia hay entre el MPU6050 y el MPU9250?
El MPU6050 es un sensor de 6 ejes con acelerómetro y giroscopio. El MPU9250 añade un magnetómetro de 3 ejes, así que es de 9 ejes y puede medir el yaw sin deriva; además admite SPI. Como el MPU9250 ya no se fabrica, en proyectos nuevos se prefieren sucesores como el ICM-20948.
Proyectos para hacer después de leer esto
Ver todos los proyectos
Uso del servomotor
Proyecto de uso básico que posiciona el servomotor en ángulos de 0°, 90° y 180° en secuencia. Enseña la biblioteca de servomotores y la lógica de control de ángulos.

SG90 Servocontrol de ángulo con potenciómetro
Control de servomotor (SG90) con potenciómetro El objetivo principal de este proyecto es controlar con precisión la posición angular de un servomotor en tiempo real utilizando una unidad de entrada analógica, el potenciómetro. El proyecto es un ejemplo básico de ingeniería para comprender la lógica de la conversión analógico-digital (ADC) y el mapeo de señales. Lógica de funcionamiento: Lectura de Datos Analógicos: Cuando el usuario gira el potenciómetro, se aplica una señal de voltaje entre 0V

Servocontrol con joystick
Proyecto Pan-tilt que controla independientemente dos servomotores en los ejes X e Y con módulo joystick. Enseña la lógica de integración joystick-servo y seguimiento de posición.

Servomotor ESP32 (control mediante potenciómetro)
En este proyecto controlamos un servomotor SG90 mediante un potenciómetro. Ajustamos el ángulo del servo asignando el valor analógico leído en el potenciómetro al rango de 0 a 180 grados. Gracias a la biblioteca ESP32Servo, cualquier GPIO del ESP32 puede generar una señal PWM. Este es un método de control básico para brazos robóticos, cardanes de cámara y mecanismos de puertas automáticas.

Juego Pong - SSD1306
El clásico juego Pong construido con Arduino y una pantalla OLED SSD1306, equipado con un oponente autónomo de inteligencia artificial (CPU) que sigue instantáneamente los movimientos de la bola y rea

Uso de la pantalla LCD con I2C
Gracias al módulo I2C, el proyecto que imprime mensajes controlando la pantalla LCD con sólo 2 cables (SDA, SCL). Enseña cómo guardar pines con protocolo I2C.

Pantalla LCD I2C para ESP32 (16x2)
En este proyecto, mostramos texto conectando una pantalla LCD de 16x2 caracteres al ESP32 a través del protocolo I2C. Gracias al I2C, podemos controlar la pantalla con solo 2 pines de datos (SDA y SCL); así se elimina el desperdicio de pines que supone la conexión paralela clásica, que requiere más de 6 pines. El código imprime un mensaje fijo en la primera línea y un contador que aumenta cada segundo en la segunda línea. Además, al inicio ejecutamos el escáner I2C para mostrar la dirección de l

Robot para evitar obstáculos
¿Qué le parece construir un vehículo inteligente que encuentre su propio camino? El Robot Evitador de Obstáculos explora constantemente su entorno gracias al sensor ultrasónico que lleva delante. Cuan
Más artículos
Aprende a conectar el acelerómetro y giroscopio MPU6050 a Arduino, leer los valores en bruto, calibrar el sensor, calcular el ángulo de inclinación y suavizarlo con un filtro complementario; incluye una alarma de caídas con ESP32 y código para la Pico.

