Einstieg in den 6-DOF-IMU-Bewegungssensor (MPU-6050) mit Arduino
Komponenten und Zubehör
| Bauteil | Menge | Details |
|---|---|---|
| Arduino UNO | 1 | |
| IMU-Sensor (6 Freiheitsgrade) – MPU-6050 | 1 |
Über dieses Projekt
Heute untersuchen wir den populären IMU-Sensor (Inertial Measurement Unit) MPU-6050 und seine Anbindung an Arduino. In einem Folge-Tutorial visualisieren wir die Bewegungsdaten in 3D.
Der MPU-6050 vereint auf einem Chip:
- 3-Achsen-Gyroskop
- 3-Achsen-Beschleunigungssensor
- Onboard Digital Motion Processor (DMP) für komplexe 6-Achsen-MotionFusion-Algorithmen
Diese Motion-Tracking-Geräte sind für niedrigen Stromverbrauch, niedrige Kosten und hohe Leistung in Smartphones, Tablets und Wearables konzipiert.

Benötigte Hardware & Software
- Hardware: Arduino UNO, MPU-6050 Sensor, Verbindungsdrähte
- Software: Arduino IDE
- Kommunikationsprotokoll: I²C-Bus
Einzeln genutzte Beschleunigungs- oder Gyroskop-Sensoren sind weniger präzise als dieses Kombimodul.

Verkabelung
Beziehen Sie sich auf die folgenden Abbildungen oder die Pin-Belegung:


Pin-Belegung:
- VCC (MPU-6050) → 5 V (Arduino) (falls Modul 5 V hat, sonst 3,3 V nutzen!)
- SDA (MPU-6050) → A4 (Arduino)
- SCL (MPU-6050) → A5 (Arduino)
- GND (MPU-6050) → GND (Arduino)
- INT (MPU-6050) → Pin 2 (Digital PWM, Arduino)


Bibliotheken installieren
- MPU6050-Bibliothek herunterladen (MPU6050.zip), entpacken, Ordner „MPU6050“ in den Arduino-
libraries-Ordner kopieren. - I2Cdev-Bibliothek herunterladen (I2Cdev.zip), ebenfalls in
librarieskopieren. - Arduino IDE neu starten – beide Bibliotheken sollten unter Datei → Beispiele erscheinen.


Beispielcode laden & konfigurieren
- In der IDE: Datei → Beispiele → MPU6050 → Examples → MPU6050_DMP6 öffnen.
- Bibliotheken
I2CdevundMPU6050im Sketch einbinden. - Kompilieren (Strg+R).
- Richtigen COM-Port wählen (Werkzeuge → Port).
- Sketch hochladen (Strg+U).
- Serial Monitor öffnen (Strg+Umschalt+M), Baudrate auf 115200 einstellen.
Hinweis: Bei 8-MHz-Prozessoren (z. B. Teensy 3,3 V, Arduino Pro Mini 3,3 V) nur 38400 Baud nutzen. - Falls „Initializing I2C devices…“ nicht erscheint: Reset-Taste drücken.



Wissensecke: DMP & I²C
DMP (Digital Motion Processing): Der MPU-6050 hat einen integrierten Motion Processor, der Beschleunigungs- und Gyroskopdaten zu präzisen 3D-Werten (Yaw, Pitch, Roll) fusioniert.

I²C (Inter-Integrated Circuit): Zwei bidirektionale Leitungen (SDA = Serial Data, SCL = Serial Clock) plus Masse. Jedes Gerät hat eine eindeutige Adresse. Mehrere Master möglich – hier ist Arduino Master, MPU-6050 Slave.
3D-Visualisierung
Die Bewegung in 3D visualisieren wir im nächsten Tutorial. (Link in Originalquelle)

Code
Arduino code for MPU sensor (Arduino)
// I2Cdev und MPU6050 müssen als Bibliotheken installiert sein
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
// #include "MPU6050.h" // nicht nötig bei MotionApps
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// Standard-I2C-Adresse 0x68 (AD0 low), 0x69 (AD0 high)
MPU6050 mpu; // MPU6050 mpu(0x69); // für AD0 high
/* =========================================================================
HINWEIS: Neben 3,3V, GND, SDA, SCL benötigt dieser Sketch die Verbindung
des MPU-6050 INT-Pins mit Arduino External Interrupt #0 (Pin 2 bei Uno/Mega).
========================================================================= */
/* =========================================================================
HINWEIS: Arduino 1.0.1 mit Leonardo Board erzeugt Kompilierfehler bei
Serial.write(buf, len). Fix in USBAPI.h nötig (in nächster IDE-Version).
========================================================================= */
#define OUTPUT_READABLE_YAWPITCHROLL
// #define OUTPUT_READABLE_QUATERNION
// #define OUTPUT_READABLE_EULER
// #define OUTPUT_READABLE_REALACCEL
// #define OUTPUT_READABLE_WORLDACCEL
// #define OUTPUT_TEAPOT
#define LED_PIN 13
bool blinkState = false;
// MPU Steuerung/Status
bool dmpReady = false;
uint8_t mpuIntStatus, devStatus;
uint16_t packetSize, fifoCount;
uint8_t fifoBuffer[64];
// Orientierungs-/Bewegungsvariablen
Quaternion q;
VectorInt16 aa, aaReal, aaWorld;
VectorFloat gravity;
float euler[3], ypr[3];
// Teapot-Paket
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
// ================================================================
// INTERRUPT-ROUTINE
// ================================================================
volatile bool mpuInterrupt = false;
void dmpDataReady() { mpuInterrupt = true; }
// ================================================================
// SETUP
// ================================================================
void setup() {
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
TWBR = 24; // 400 kHz I2C-Takt (200 kHz bei 8 MHz CPU)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
Serial.begin(115200);
while (!Serial); // Leonardo-Enumeration abwarten
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
Serial.println(F("Testing device connections..."));
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
Serial.println(F("\nSend any character to begin DMP programming and demo: "));
while (Serial.available() && Serial.read()); // Buffer leeren
while (!Serial.available()); // Auf Zeichen warten
while (Serial.available() && Serial.read()); // Wieder leeren
Serial.println(F("Initializing DMP..."));
devStatus = mpu.dmpInitialize();
// Eigene Gyro-Offsets (für minimale Empfindlichkeit skaliert)
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788); // 1688 Werkseinstellung
if (devStatus == 0) {
Serial.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
Serial.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
} else {
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
pinMode(LED_PIN, OUTPUT);
}
// ================================================================
// HAUPTSCHLEIFE
// ================================================================
void loop() {
if (!dmpReady) return;
while (!mpuInterrupt && fifoCount < packetSize) {
// Andere Programmteile hier...
}
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
fifoCount = mpu.getFIFOCount();
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
mpu.resetFIFO();
Serial.println(F("FIFO overflow!"));
} else if (mpuIntStatus & 0x02) {
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
mpu.getFIFOBytes(fifoBuffer, packetSize);
fifoCount -= packetSize;
#ifdef OUTPUT_READABLE_YAWPITCHROLL
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
Serial.print("ypr\t");
Serial.print(ypr[0] * 180/M_PI); Serial.print("\t");
Serial.print(ypr[1] * 180/M_PI); Serial.print("\t");
Serial.println(ypr[2] * 180/M_PI);
#endif
// Weitere Ausgabe-Modi per #define wählbar (siehe Code-Anfang)
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
}
}
Schaltplan

Herstellungsprozess
- Line-Tracking-Sensor mit Raspberry Pi – Einfacher KY-033 Tür/Line Detektor
- Robuste Temperatur- & Sensor-API auf Raspberry Pi mit GY-91 Modul bauen
- LED mit PIR-Bewegungsmelder am Raspberry Pi steuern
- Raspberry Pi GPIO meistern: PIR-Bewegungsmelder an B+/Model 2 anschließen
- HC-SR501 PIR-Bewegungssensor an Raspberry Pi anschließen, kalibrieren und programmieren
- TJBot starten: Bauen, konfigurieren und per Sprache steuern
- Schritt-für-Schritt: RAK 831 LoRa Gateway auf Raspberry Pi 3 deployen
- LoRa-Gateway mit RAK831-Modul auf Raspberry Pi 3 bauen – Schritt-für-Schritt-Anleitung
- KI in der Versicherung: Ein praxisnaher Starter-Guide für die reale Umsetzung
- Arduino Einsteiger Tutorial #1: Erstes Projekt (Blink)