Bauteil · Sensor
MPU-6050 IMU
Die MPU-6050 ist eine 6-Achsen-IMU, die Neigung, Drehung und Beschleunigung über I²C spürt – wie ein Roboter seine Lage für Balancieren und Drehen kennt.
Was es ist
Die MPU-6050 ist, wie ein Roboter seine Eigenbewegung fühlt. Sie ist eine 6-Achsen-Trägheitsmesseinheit – Gyroskop und Beschleunigungssensor auf einem Chip –, die meldet, wie der Roboter geneigt ist, wie schnell er sich dreht und wie er beschleunigt. Wo ein Ultraschallsensor nach außen auf die Welt schaut, schaut eine IMU nach innen auf den Roboterkörper – was ein selbstbalancierender Roboter oder ein Koppelnavigator braucht.
Wie es funktioniert
Darin stecken zwei Sensoren. Der Beschleunigungssensor misst lineare Beschleunigung auf X, Y und Z – im Ruhezustand ist das nur Schwerkraft, die dem Roboter sagt, wo unten ist (seine Neigung). Das Gyroskop misst, wie schnell sich der Roboter um jede Achse dreht. Beide liest man über I²C (SCL/SDA) aus.
Kein Sensor reicht allein: Das Gyro zum Winkel integriert driftet langsam; dem Beschleunigungssensor vertraut ist verrauscht, sobald sich der Roboter bewegt. Die Lösung ist Sensorfusion – beide so mischen, dass der Beschleunigungssensor die Gyrodrift korrigiert und das Gyro das Beschleunigungsrauschen glättet. Genau diese Technik behandelt Sensorrauschen, Bias und Filterung.
Wann man ihn verwendet
Zur MPU-6050 greifen, wenn ein Roboter eigene Lage oder Bewegung kennen muss:
- Selbstbalancierende Roboter – der Neigungswinkel, den die Regelschleife auf null zu halten kämpft.
- Kurs und Koppelnavigation – Drehungen spüren, um Odometrie zwischen Encoderlesungen zu verbessern.
- Bewegungserkennung / Gesten – auf Aufnehmen, Kippen oder Schütteln reagieren.
Zum Messen von Entfernung zu Dingen (Wänden, Hindernissen) stattdessen einen Entfernungssensor wie HC-SR04 oder VL53L0X nehmen – eine IMU spürt den Roboter, nicht die Welt.
Verdrahtung und Fallstricke
- I²C, 3,3–5 V. Die meisten Breakouts (das lila GY-521) haben einen Regler, also sind 5 V in Ordnung; der nackte Chip ist nur 3,3 V.
- Gyro und Accel fusionieren – nicht auf einem rohen Messwert lenken. Ein einzelner Beschleunigungsmesswert unter Bewegung ist als Neigungswinkel unbrauchbar.
- Gier driftet ohne Magnetometer; die MPU-6050 für Nick/Roll und kurzfristige Drehungen nutzen, nicht für absoluten Kompasskurs.
- Steif und waagerecht montiert halten; ein lockerer Sensor fügt Vibration hinzu, die kein Filter entfernt.
Pinbelegung
Das lila GY-521-Breakout ist die Platine, die fast alle mit „MPU-6050“ meinen. Acht Pins, und vier davon bleiben meist unverbunden.
| Pin | Name | Was er tut | Üblich |
|---|---|---|---|
| 1 | VCC | Versorgung. Der Bordregler akzeptiert 3,3–5 V; der nackte Chip nur 3,3 V | 5 V am Uno, 3,3 V am ESP32 |
| 2 | GND | Masse, geteilt mit dem Mikrocontroller | Verbunden |
| 3 | SCL | I²C-Takt | A5 am Uno |
| 4 | SDA | I²C-Daten | A4 am Uno |
| 5 | XDA | Hilfs-I²C-Daten – für ein Magnetometer, das die MPU in deinem Auftrag liest | Offen gelassen |
| 6 | XCL | Hilfs-I²C-Takt | Offen gelassen |
| 7 | AD0 | Adresswahl. Low (Standard) = 0x68, High = 0x69 |
Offen gelassen oder high für einen zweiten Sensor |
| 8 | INT | Interrupt-Ausgang – feuert bei Daten-bereit, Bewegung oder freiem Fall | Offen gelassen, bis man aufhören will zu pollen |
AD0 ist der Pin, der zwei MPU-6050 an einem Bus möglich macht – und der Grund, warum die Adresskollision hier eine leichte Antwort hat, die die meisten Sensoren nicht bieten.
An einen Arduino verdrahten
| MPU-6050 | Arduino Uno | ESP32 | Hinweis |
|---|---|---|---|
| VCC | 5 V | 3,3 V | Der Bordregler behandelt beide |
| GND | GND | GND | Muss mit allem anderen gemeinsam sein |
| SCL | A5 | GPIO 22 | Keine externen Pull-ups hinzufügen – das Board hat bereits 2,2 kΩ |
| SDA | A4 | GPIO 21 | Ebenso |
| AD0 | — | — | Nur für einen zweiten Sensor an VCC legen |
Eine Feinheit, die man an einem 5-V-Arduino kennen sollte: Die Pull-up-Widerstände des GY-521 gehen auf seine geregelte 3,3-V-Schiene – die I²C-Leitungen liegen also auf 3,3 V, nicht 5 V. Ein ATmega328P liest high oberhalb 0,6 × Vcc = 3,0 V – 3,3 V schafft die Schwelle also, aber nur um 0,3 V. In der Praxis funktioniert es zuverlässig und ist ein Grund, warum sich eine lange oder verrauschte I²C-Strecke auf diesem Board früher danebenbenimmt als auf einem 5-V-Board.
Auslesen: die Register, auf die es ankommt
Man kann diesen Sensor mit Bibliothek treiben und nie ein Register sehen – aber vier davon erklären fast jedes Problem, das Leute damit haben.
| Register | Adresse | Warum es interessiert |
|---|---|---|
PWR_MGMT_1 |
0x6B |
Der Chip startet schlafend. Hier 0 schreiben, sonst ist jede Lesung null |
WHO_AM_I |
0x75 |
Liefert 0x68 – der schnellste Beweis, dass die Verdrahtung stimmt |
GYRO_CONFIG |
0x1B |
Vollbereich: ±250, ±500, ±1000, ±2000 °/s |
ACCEL_CONFIG |
0x1C |
Vollbereich: ±2, ±4, ±8, ±16 g |
ACCEL_XOUT_H |
0x3B |
Beginn von 14 Bytes: 6 Accel, 2 Temperatur, 6 Gyro – in einem Burst lesen |
Die beiden Konfigregister setzen den Skalfaktor, durch den man Rohzählwerte teilt – und ihn falsch zu haben ist die häufigste Quelle für „meine Winkel sind viermal zu groß“:
| Bereichseinstellung | Gyro-LSB pro °/s | Bereichseinstellung | Accel-LSB pro g |
|---|---|---|---|
| ±250 °/s (Standard) | 131 | ±2 g (Standard) | 16384 |
| ±500 °/s | 65,5 | ±4 g | 8192 |
| ±1000 °/s | 32,8 | ±8 g | 4096 |
| ±2000 °/s | 16,4 | ±16 g | 2048 |
Den kleinsten Bereich wählen, der nicht sättigt. Ein Balancierroboter überschreitet selten ±250 °/s, und der enge Bereich liefert gratis vierfache Auflösung gegenüber ±1000 °/s.
Minimal funktionierender Code
Keine Bibliothek – das ist das Ganze, und es lohnt sich einmal zu fahren, damit man weiß, was die Bibliothek für einen tut.
#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);
}
Zwei Dinge, die das bewusst nicht tut: Es fusioniert die beiden Sensoren nie und zieht nie einen Bias ab. Beides kommt als Nächstes.
Kalibrierung: die zwanzig Zeilen, auf die es am meisten ankommt
Im Ruhezustand liest ein Gyro nicht null. Es liest einen kleinen, recht konstanten Offset – und weil man das Gyro zum Winkel integriert, integriert sich dieser Offset zu einem stetig wachsenden Fehler. Ein Bias von nur 2 °/s unkorrigiert sind 120° Drift nach einer Minute.
Wenige hundert Messwerte bei völlig stillem Sensor mitteln, dann abziehen:
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
Drei praktische Hinweise, die kein Datenblatt verrät:
- Bei jedem Einschalten tun, nicht einmal. Gyrobias wandert mit der Temperatur – und ein Roboter, der zehn Minuten läuft, ist nicht der kalt kalibrierte Roboter.
- „Still“ heißt still. Eine Kalibrierung, aufgenommen während jemand am Tisch lehnt, brennt diese Bewegung dauerhaft in den Bias ein.
- Der Beschleunigungssensor braucht eine Waagerecht-Referenz, keine Null. Er sollte 1 g auf der Achse lesen, die nach unten zeigt. Liest er 0,97 g, ist das dein Skalenfehler – und er zeigt sich als Neigungswinkel, der konstant ein paar Grad danebenliegt.
Warum ein Sensor nie reicht
Die beiden Sensoren versagen auf exakt gegensätzliche Arten – was ihre Fusion so gut funktionieren lässt.
| Beschleunigungssensor | Gyroskop | |
|---|---|---|
| Misst | Lineare Beschleunigung – im Ruhezustand Schwerkraft | Drehrate |
| Liefert Neigung per | Trigonometrie auf dem Schwerkraftvektor | Integrieren der Rate über die Zeit |
| Kurzfristig | Verrauscht – jede Erschütterung ist auch Beschleunigung | Hervorragend, glatt, reaktionsschnell |
| Langfristig | Im Mittel korrekt – Schwerkraft driftet nicht | Driftet unbegrenzt, weil Bias sich integriert |
| Versagt wenn | Der Roboter beschleunigt, also „unten“ nicht mehr unten ist | Immer, langsam |
Ein Komplementärfilter nimmt von jedem die gute Hälfte – dem Gyro kurzfristig trauen, den Schätzwert vom Beschleunigungssensor langsam zur Wahrheit zurückziehen lassen:
angle = 0.98f * (angle + rate * dt) + 0.02f * accelAngle;
Diese 0,98 setzt die Grenzfrequenz. Höher traut dem Gyro länger – glatter, aber driftet mehr; niedriger antwortet auf das Beschleunigungsrauschen. Das Komplementärfilter-Tutorial arbeitet durch, wie man sie bewusst statt nach Gefühl wählt.
Fehlersuche
| Symptom | Wahrscheinliche Ursache | Lösung |
|---|---|---|
| Jede Lesung exakt 0 | Der Chip schläft noch | 0 nach PWR_MGMT_1 (0x6B) schreiben, nach Wire.begin() |
| Busscanner findet nichts | 8-Bit-Adresse aus dem Datenblatt | 0xD0 des Datenblatts ist 0x68 nach links geschoben – 0x68 verwenden |
| Zwei Sensoren, nur einer erscheint | Beide auf Standardadresse | Eines Boards AD0 an VCC legen, damit es auf 0x69 antwortet |
| Winkel 4× oder 8× zu groß | Skalfaktor passt nicht zum eingestellten Bereich | Teiler an GYRO_CONFIG/ACCEL_CONFIG anpassen |
| Winkel driftet selbst im Ruhezustand stetig | Unkalibrierter Gyrobias | 500 stille Messwerte beim Start mitteln und abziehen |
| Neigung springt während der Fahrt | Roher Beschleunigungswinkel verwendet | Mit Gyro fusionieren; das „Unten“ eines fahrenden Roboters ist nicht unten |
| Messwerte frieren nach einer Weile ein | I²C-Bus blockiert | Pull-ups prüfen; Bus-Recovery-Routine hinzufügen, die SCL neunmal taktet |
| Kurs rotiert ewig langsam | Gier hat keine absolute Referenz | Erwartet – Gier braucht ein Magnetometer oder eine andere absolute Quelle |
| Verrauscht oberhalb etwa 1 kHz Vibration | Starre Montage überträgt Motorvibration | Sensor weich lagern; On-Chip-DLPF per CONFIG (0x1A) aktivieren |
MPU-6050 oder etwas Neueres?
Die MPU-6050 ist beim Hersteller abgekündigt und trotzdem die meistverwendete IMU der Hobbyrobotik – weil billig, überall dokumentiert und von jeder Bibliothek unterstützt.
| Teil | Achsen | Bemerkenswerter Unterschied | Wählen wenn |
|---|---|---|---|
| MPU-6050 | 6 | Der Standard; riesige Beispielcodemenge | Lernen, Balancieren, jedes erste IMU-Projekt |
| MPU-9250 | 9 | Bringt ein Magnetometer dazu – Gier hat also absolute Referenz | Du einen Kompasskurs brauchst, nicht nur Drehrate |
| ICM-20948 | 9 | Der aktuell produzierte Nachfolger des MPU-9250 | Neue Entwürfe, die 9 Achsen und Langzeitverfügbarkeit brauchen |
| BNO055 | 9 | Fusioniert on-chip und liefert Lage direkt | Du einen Winkel ohne Filter schreiben willst – zum mehrfachen Preis |
| LSM6DS3 | 6 | Modern, in Produktion, rauschärmer | Ein Drop-in-Upgrade, wenn MPU-6050-Vorrat ausgeht |
Die ehrliche Zusammenfassung: Braucht dein Roboter Nick und Roll – was Balancieren braucht –, reicht die MPU-6050 völlig und die Fusion ist gut selbst geschrieben zu haben. Braucht er absoluten Kurs, holt keine Filterung das aus sechs Achsen – dann willst du ein Magnetometer.
Den Graphen erkunden
Verwendet in diesen Bauprojekten
Projekte, Lernpfade und Simulatoren, die MPU-6050 IMU verwenden.
- ProjektEinen Mecanum-Roboter bauen, der seitwärts fährt
- ProjektGPS-Wegpunkt-Rover bauen: Fährt seine Route selbst
- ProjektMicromouse bauen: Labyrinth-Roboter mit Flood-Fill
- ProjektSelbstbalancierender Roboter: MPU6050 und PID
- LernpfadElektronik-Grundlagen für Roboter: Ein Lernpfad
- LernpfadHolonomer Antrieb: Seitwärts fahren ohne Drehen
- LernpfadPlanung und Kartierung: Von Flood Fill zu SLAM
Fragen
FAQ zu MPU-6050 IMU
Was ist der MPU-6050-Sensor?
Die MPU-6050 ist eine 6-Achsen-Trägheitsmesseinheit (IMU) auf einem kleinen Breakout-Board. Sie kombiniert ein 3-Achsen-Gyroskop und einen 3-Achsen-Beschleunigungssensor – ein Roboter spürt damit, wie er geneigt ist, wie schnell er sich dreht und wie er beschleunigt – alles über den I²C-Bus ausgelesen.
Wie funktioniert die MPU-6050?
Darin stecken zwei Sensoren. Der Beschleunigungssensor misst lineare Beschleunigung – im Ruhezustand ist das nur Schwerkraft, die dem Roboter sagt, wo unten ist (seine Neigung). Das Gyroskop misst die Drehrate um jede Achse. Beide liest man über I²C aus und fusioniert sie dann zu einer stabilen Lage, die keiner allein liefert.
Wofür wird die MPU-6050 verwendet?
Die Eigenbewegung eines Roboters spüren – einen selbstbalancierenden Roboter aufrecht halten, Kurs schätzen und Odometrie zwischen Encoderlesungen verbessern, sowie Aufnehmen, Kippen oder Schütteln erkennen. Sie spürt den Roboter selbst, nicht die Welt um ihn – ergänzt also einen Entfernungssensor statt ihn zu ersetzen.
Wie kalibriert man eine MPU-6050?
Im Ruhezustand lesen Gyro und Beschleunigungssensor kleine Offsets ungleich null. Kalibrieren durch Mitteln weniger hundert Messwerte bei völlig still liegendem Sensor, dann diese Offsets von jeder Messung abziehen. Das Gyro braucht das besonders – unkalibrierter Bias driftet den geschätzten Winkel am schnellsten.
Wie schließt man eine MPU-6050 an ESP32 oder Arduino an?
Über I²C – SDA und SCL an die I²C-Pins des Boards, plus Versorgung und Masse. Das lila GY-521-Breakout hat einen Regler, läuft also an 3,3 V am ESP32 oder 5 V am Arduino Uno. Eine Bibliothek liest dann die Gyroskop- und Beschleunigungsregister aus.
Weiterführende Literatur