IMU MPU-9250/6500: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
 
(17 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 6: Zeile 6:




== Einleitung ==
= Einleitung =
Die Inertiale Messeinheit (Engl. intertial measurement unit, IMU) ist ein 9-Achsen-Positionserkennungsmodul, das die folgenden Sensoren kombiniert:
Die Inertiale Messeinheit (Engl. intertial measurement unit, IMU) ist ein 9-Achsen-Positionserkennungsmodul, das die folgenden Sensoren kombiniert:
* 3-Achsen-Gyroskop
* 3-Achsen-Gyroskop
Zeile 14: Zeile 14:
Ein Digital Motion Processor (DMP) ist zudem in einer winzigen Gehäusegröße von nur 3x3x1&thinsp;mm verbaut. Das Modul kann über einen I<sup>2</sup>C-Bus angesprochen werden. Der MPU-9250 ist ein Multi-Chip-Modul welches die MPU-6500 (Geschleunigung und Gyro) via I<sup>2</sup>C mit dem AKM-8963 (Magnetometer) verbindet.
Ein Digital Motion Processor (DMP) ist zudem in einer winzigen Gehäusegröße von nur 3x3x1&thinsp;mm verbaut. Das Modul kann über einen I<sup>2</sup>C-Bus angesprochen werden. Der MPU-9250 ist ein Multi-Chip-Modul welches die MPU-6500 (Geschleunigung und Gyro) via I<sup>2</sup>C mit dem AKM-8963 (Magnetometer) verbindet.


== Technische Übersicht ==
= Technische Übersicht =
{| class="wikitable"
{| class="wikitable"
|+ Tabelle 1: Eigenschaften des MPU-9250/6500
<!--|+ style = "text-align: left"| Tabelle 1: Eigenschaften des MPU-9250/6500 -->
! style="font-weight: bold;" | Eigenschaft
|-
! style="font-weight: bold;" | Daten
! Eigenschaft !! Daten
|-
|-
| Artikel || MPU-9250/6500
| Artikel || MPU-9250/6500
Zeile 37: Zeile 37:
|}
|}


== Datenblätter ==
== Pinbelegung ==
*[[Medium:MPU-9250-InvenSense.pdf|InvenSense: Datenblatt MPU-9250 Rev. 1.4]]
{| class="wikitable"
*[[Medium:PS-MPU-9250A-01-v1.1.pdf|InvenSense: Datenblatt MPU-9250 Rev. 1.1]]
|-
! Pin !! MPU-9250  !! Signal !! Arduino Uno R3
|-
| 1 || Betriebsspannung Vcc  || VCC  || VCC, 3,3&thinsp;V
|-
| 2 ||  Masse GND || GND || GND
|-
| 3 || SCL || I<sup>2</sup>C Taktleitung || SCL
|-
| 4 || SDA  || I<sup>2</sup>C Datenleitung|| SDA
|-
| 5 || EDA || ||
|-
| 6 || ECL || ||
|-
| 7 || ADO/SDO|| ||
|-
| 8 || INT || ||
|-
| 9 || NCS || ||
|-
| 10 || FSYNC || ||
|}
 
= Messverfahren =
 
=Software=
==Arduino==
=== I²C-Scanner ===
Prüfen Sie welche Sensoren am I2C-Bus angeschlossen sind.
{| role="presentation" class="wikitable mw-collapsible mw-collapsed"
| <strong>DemoI2C_Scanner.ino  &thinsp;</strong>
|-
| <source line lang="C" style="font-size:medium">#include <Wire.h>
 
void setup()
{
  Serial.begin(115200);
  Wire.begin();
  Serial.println("I2C Scan");
  for(byte address=1; address<127; address++)
  {
    Wire.beginTransmission(address);
    if(Wire.endTransmission()==0)
    {
      Serial.print("Gefunden: 0x"); // 0x71 MPU9250 auf einem GY-6500/GY-9250-Board
      Serial.println(address, HEX);
    }
  }
}
void loop(){}
</source>
|}
URL: https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/ArduinoUnoR3/examples/DemoI2C_Scanner/DemoI2C_Scanner.ino
'''Erwartetes Ergebnis'''
I2C Scan
Gefunden: 0x68
 
<code>0x68</code> ist die I²C-Adresse des Sensors.
 
=== Prüfen welcher Chip verbaut wurde ===
Bei diesen Modulen kommt es vor, dass ein Board als MPU-9250 verkauft wird, aber tatsächlich ein MPU6500 bestückt ist.
 
Lesen Sie das Register <code>0x75</code> per I²C aus.
{| class="wikitable"
|+ Tabelle 1: Erwartete Antwort
|-
! Chip !! WHO_AM_I
|-
| MPU-6500 || <code>0x70</code>
|-
| MPU-9250 || <code>0x71</code>
|}
{| role="presentation" class="wikitable mw-collapsible mw-collapsed"
| <strong>DemoWhoAmI.ino  &thinsp;</strong>
|-
| <source line lang="C" style="font-size:medium">#include <Wire.h>
void setup() {
  Serial.begin(115200);
  while (!Serial);
  Wire.begin();  // I²C initialisieren
  Wire.beginTransmission(0x68);
  Wire.write(0x75);              // WHO_AM_I-Register
  Wire.endTransmission(false);
  Wire.requestFrom(0x68, 1);
 
  if (Wire.available()) {
    byte id = Wire.read();
    Serial.print("WHO_AM_I = 0x");
    Serial.println(id, HEX);
    if (id == 0x71)
      Serial.println("MPU-9250 erkannt");
    else if (id == 0x70)
      Serial.println("MPU-6500 erkannt");
    else
      Serial.println("Unbekannter Sensor");
  } else {
    Serial.println("Keine Antwort vom Sensor.");
  }
}
void loop() {
}
</source>
|}
URL: https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/ArduinoUnoR3/examples/DemoWhoAmI/DemoWhoAmI.ino
 
=== Arduino-Bibliothek installieren===
MPU9250_asukiaaa
 
{| class="wikitable"
|+ Tabelle 1: Übersicht der Demos
|-
! Demo !! Funktion
|-
| DemoUnoR4Wifi.ino || Demo zum Senden von Sensordaten via Wifi für die Arduino IDE
|-
| DemoUnoR4Wifi.m || Demo zum Empfangen von Sensordaten via Wifi mit MATLAB<sup>®</sup>
|-
| GetDate.ino  || Demo zum Auslesen der IMU-Daten des Sensors MPU 9250
|-
| E15_RadInkrementalgeberFahrt.ino  || Demo zum Ansteuern der Motoren und auslesen der Odometrie des AlphaBot
|}
{| role="presentation" class="wikitable mw-collapsible mw-collapsed"
| <strong>DemoUnoR4Wifi.ino  &thinsp;</strong>
|-
| <source line lang="matlab" style="font-size:medium">
clear all; clc;
 
port = 7000; % UDP Port, auf dem MATLAB lauscht
 
u = udpport("IPV4", "LocalPort", port);
 
disp("Warte auf UDP-Daten vom Arduino ...")
 
while true
    nBytes = u.NumBytesAvailable;
    if nBytes  > 0 % Prüfen, ob Daten vorhanden sind
        data = read(u, nBytes, "string");
        disp(data)
    end
end
</source>
|}
{| role="presentation" class="wikitable mw-collapsible mw-collapsed"
| <strong>GetDate.ino</strong> aus der Bibliothek MPU9250_asukiaaa&thinsp;
|-
| <source line lang="C" style="font-size:medium">#include <MPU9250_asukiaaa.h>
 
#ifdef _ESP32_HAL_I2C_H_
#define SDA_PIN 21
#define SCL_PIN 22
#endif
 
MPU9250_asukiaaa mySensor;
float aX, aY, aZ, aSqrt, gX, gY, gZ, mDirection, mX, mY, mZ;
 
void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.println("started");
 
#ifdef _ESP32_HAL_I2C_H_ // For ESP32
  Wire.begin(SDA_PIN, SCL_PIN);
  mySensor.setWire(&Wire);
#endif
 
  mySensor.beginAccel();
  mySensor.beginGyro();
  mySensor.beginMag();
 
  // You can set your own offset for mag values
  // mySensor.magXOffset = -50;
  // mySensor.magYOffset = -55;
  // mySensor.magZOffset = -10;
}
 
void loop() {
  uint8_t sensorId;
  int result;
 
  result = mySensor.readId(&sensorId);
  if (result == 0) {
    Serial.println("sensorId: " + String(sensorId));
  } else {
    Serial.println("Cannot read sensorId " + String(result));
  }
 
  result = mySensor.accelUpdate();
  if (result == 0) {
    aX = mySensor.accelX();
    aY = mySensor.accelY();
    aZ = mySensor.accelZ();
    aSqrt = mySensor.accelSqrt();
    Serial.println("accelX: " + String(aX));
    Serial.println("accelY: " + String(aY));
    Serial.println("accelZ: " + String(aZ));
    Serial.println("accelSqrt: " + String(aSqrt));
  } else {
    Serial.println("Cannod read accel values " + String(result));
  }
 
  result = mySensor.gyroUpdate();
  if (result == 0) {
    gX = mySensor.gyroX();
    gY = mySensor.gyroY();
    gZ = mySensor.gyroZ();
    Serial.println("gyroX: " + String(gX));
    Serial.println("gyroY: " + String(gY));
    Serial.println("gyroZ: " + String(gZ));
  } else {
    Serial.println("Cannot read gyro values " + String(result));
  }
 
  result = mySensor.magUpdate();
  if (result != 0) {
    Serial.println("cannot read mag so call begin again");
    mySensor.beginMag();
    result = mySensor.magUpdate();
  }
  if (result == 0) {
    mX = mySensor.magX();
    mY = mySensor.magY();
    mZ = mySensor.magZ();
    mDirection = mySensor.magHorizDirection();
    Serial.println("magX: " + String(mX));
    Serial.println("maxY: " + String(mY));
    Serial.println("magZ: " + String(mZ));
    Serial.println("horizontal direction: " + String(mDirection));
  } else {
    Serial.println("Cannot read mag values " + String(result));
  }
 
  Serial.println("at " + String(millis()) + "ms");
  Serial.println(""); // Add an empty line
  delay(500);
}
</source>
{| role="presentation" class="wikitable mw-collapsible mw-collapsed"
| <strong>DemoUnoR4Wifi.m  &thinsp;</strong>
|-
| <source line lang="C" style="font-size:medium">// Notw. Hardware HC-05 Bluetooth Modul
// Vorbereitung:
//                1) Binden Sie den Uno R4 in Ihr Netzwerk ein (Z. 25, 26).
//                2) Tragen Sie die IP Ihres MATLAB Rechners ein (Z. 32).
//                3) Übertragen Sie das Skript an den Uno R4.
//                4) Wählen Sie einen frein UDP-Port (Z. 38).
//*****************************************************************************
 
#include <WiFiS3.h>
#include <WiFiUdp.h>
 
// WLAN Zugangsdaten
char ssid[] = "Ihr_WLAN_Name";    // Anpassen
char pass[] = "Ihr_WLAN_Passwort"; // Anpassen
 
WiFiUDP udp;
 
// IP-Adresse des MATLAB-Rechners
IPAddress matlabIP(192, 168, 1, 1);  // Anpassen
 
// MATLAB UDP-Port
unsigned int matlabPort = 7000;
 
void setup()
{
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Verbinde WLAN...");
 
  while (WiFi.begin(ssid, pass) != WL_CONNECTED)
  {
    delay(5000);
    Serial.print(".");
  }
 
  Serial.println();
  Serial.println("WLAN verbunden");
  Serial.print("Arduino IP: ");
  Serial.println(WiFi.localIP());
  udp.begin(7001);
}
 
 
void loop()
{
  static int Zaehler_s16 = 0;            // Beispiel für Messwert
  float Zeit_f32 = float(millis())/1000;  // Zeit in s
 
  char Daten_s8[50];
 
  // Format: Float;Integer
  sprintf(Daten_s8, "%.3f;%d", Zeit_f32, Zaehler_s16);
 
  Serial.println(Daten_s8);
 
  // UDP senden
  udp.beginPacket(matlabIP, matlabPort);
  udp.write(Daten_s8);
  udp.endPacket();
 
  Zaehler_s16++; // Zähler inkrementieren
 
  delay(100);
}
</source>
|}
|}
{| role="presentation" class="wikitable mw-collapsible mw-collapsed"
| <strong>E15_RadInkrementalgeberFahrt.ino&thinsp;</strong>
|-
| <source line lang="C" style="font-size:medium">/* Bibliotheken einbinden */
#include "AlphaBot.h"
 
/* Globale KONSTANTEN deklarieren */
AlphaBot R2D2 = AlphaBot();              // Instanz des Alphabot wird erzeugt. */
const byte PORT_ENC_L_u8 = 2;            // Die linke Lichtschranke (CNTL) liegt an Arduino D2
const byte PORT_ENC_R_u8 = 3;            // Die rechte Lichtschranke (CNTR) liegt an Arduino D3
const byte ANZAHL_INCREMENTE_u8 = 40;    // Die Encoderscheibe hat 20 Löcher und somit 40 Zustände
const int MOTOR_POWER_s16 = 80;          // Motorleistung
const unsigned long BAUDRATE_u32 = 9600;  // Serielle Übertragungsgeschwindigkeit in Baud
const unsigned long DELAY_MS_u32 = 1000;  // Delay in ms
 
/* Globale Variablen */
volatile byte valEncL_u8 = 0;              // https://www.arduino.cc/reference/de/language/variables/data-types/byte/
volatile byte valEncR_u8 = 0;              // Inkrementzähler
volatile long int RadumdrehungenL_s32 = 0;  // https://www.arduino.cc/reference/de/language/variables/data-types/long/
volatile long int RadumdrehungenR_s32 = 0;  // Zähler für die kompletten Radumdrehungen
 
/* Einmalige Systeminitialisierung */
void setup() {
  Serial.begin(BAUDRATE_u32);                // Seriellen Monitor starten
  pinMode(PORT_ENC_L_u8, INPUT);              // Eingangsport D2 definieren
  pinMode(PORT_ENC_R_u8, INPUT);              // Eingangsport D3 definieren
  attachInterrupt(0, updateEncoderL, CHANGE); // 0: D2 Auslösen des Interrupts bei Signalwechsel
  attachInterrupt(1, updateEncoderR, CHANGE); // 1: D3 https://www.arduino.cc/reference/de/language/functions/external-interrupts/attachinterrupt/
}
/* Zyklusschleife */
void loop() { 
  /* Ausgaben im Seriellen Monitor */
  Serial.print(valEncL_u8);
  Serial.print(" :-: ");
  Serial.print(valEncR_u8);
  Serial.print(" :-: ");
  Serial.print(RadumdrehungenL_s32);
  Serial.print(" :-: ");
  Serial.print(RadumdrehungenR_s32);
  Serial.print("\n");
  delay(DELAY_MS_u32);
 
  R2D2.MotorRun(MOTOR_POWER_s16, MOTOR_POWER_s16);  // Fahrt starten
  delay(DELAY_MS_u32);                              // Fahrzeit
  R2D2.Brake();                                    // Alle Motoren stoppen
}


<!--
/* Unterfunktionen */
== Kennlinie ==
void updateEncoderL(){                  // Inkrementalgeber Links
  valEncL_u8++;
  if (valEncL_u8 > ANZAHL_INCREMENTE_u8)// 40 Zustandswechsel = 1 Radumdrehung
  {
    valEncL_u8 = 0;                    // Reset Inkrementzähler
    RadumdrehungenL_s32++;              // Umdrehungen inkrementieren
  }
}


void updateEncoderR(){                  // Inkrementalgeber Rechts
  valEncR_u8++;
  if (valEncR_u8 > ANZAHL_INCREMENTE_u8)// 40 Zustandswechsel = 1 Radumdrehung
  {
    valEncR_u8 = 0;                    // Reset Inkrementzähler
    RadumdrehungenR_s32++;              // Umdrehungen inkrementieren
  }
}
</source>
|}
Weitere AlphaBot und Arduino Demos finden Sie im SVN-Repositorium
https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/


== Messschaltung ==
== MATLAB<sup>®</sup> ==
-->
== Simulink ==


== Software ==
= Messung =


== Video ==
= Video =
{{#ev:youtube|https://youtu.be/mzwovYcozvI| 600 | | How to use MPU-9250 Gyroscope, Accelerometer, Magnetometer for Arduino|frame}}
{{#ev:youtube|https://youtu.be/mzwovYcozvI| 600 | | How to use MPU-9250 Gyroscope, Accelerometer, Magnetometer for Arduino|frame}}
= Datenblätter =
*[[Medium:MPU-9250-InvenSense.pdf|InvenSense: Datenblatt MPU-9250 Rev. 1.4]]
*[[Medium:PS-MPU-9250A-01-v1.1.pdf|InvenSense: Datenblatt MPU-9250 Rev. 1.1]]


----
----
→ zurück zum Hauptartikel: [[Arduino]]
→ zurück zum Hauptartikel: [[:Kategorie:Sensoren|Sensor-Baukasten]] | [[HSHL-Mechatronik-Baukasten]]

Aktuelle Version vom 22. Juli 2026, 06:07 Uhr

Abbildung 1: IMU MPU-9250/6500

Autor: Prof. Schneider


Einleitung

Die Inertiale Messeinheit (Engl. intertial measurement unit, IMU) ist ein 9-Achsen-Positionserkennungsmodul, das die folgenden Sensoren kombiniert:

  • 3-Achsen-Gyroskop
  • 3-Achsen-Beschleunigungssensor
  • 3-Achsen-Magnetfeldsensor (Erdmagnetfeld/Kompass)

Ein Digital Motion Processor (DMP) ist zudem in einer winzigen Gehäusegröße von nur 3x3x1 mm verbaut. Das Modul kann über einen I2C-Bus angesprochen werden. Der MPU-9250 ist ein Multi-Chip-Modul welches die MPU-6500 (Geschleunigung und Gyro) via I2C mit dem AKM-8963 (Magnetometer) verbindet.

Technische Übersicht

Eigenschaft Daten
Artikel MPU-9250/6500
ADU 3x 16-Bit Analog-Digital Konverter für Gyro, Beschleunigung und Magnetfeld
Schnittstelle I2C und SPI Schnittstelle
Spannungsversorgung 3 V bis 5 V
Messbereich Gyroskop einstellbar: ±250, ±500, ±1000 and ±2000 °/s
Messbereich Beschleunigung einstellbar: ±2g, ±4g, ±8g and ±16g
Messbereich Magnetometer ±4800 µT
Hersteller InvenSense, TDK

Pinbelegung

Pin MPU-9250 Signal Arduino Uno R3
1 Betriebsspannung Vcc VCC VCC, 3,3 V
2 Masse GND GND GND
3 SCL I2C Taktleitung SCL
4 SDA I2C Datenleitung SDA
5 EDA
6 ECL
7 ADO/SDO
8 INT
9 NCS
10 FSYNC

Messverfahren

Software

Arduino

I²C-Scanner

Prüfen Sie welche Sensoren am I2C-Bus angeschlossen sind.

URL: https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/ArduinoUnoR3/examples/DemoI2C_Scanner/DemoI2C_Scanner.ino

Erwartetes Ergebnis

I2C Scan
Gefunden: 0x68

0x68 ist die I²C-Adresse des Sensors.

Prüfen welcher Chip verbaut wurde

Bei diesen Modulen kommt es vor, dass ein Board als MPU-9250 verkauft wird, aber tatsächlich ein MPU6500 bestückt ist.

Lesen Sie das Register 0x75 per I²C aus.

Tabelle 1: Erwartete Antwort
Chip WHO_AM_I
MPU-6500 0x70
MPU-9250 0x71
URL: https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/ArduinoUnoR3/examples/DemoWhoAmI/DemoWhoAmI.ino

Arduino-Bibliothek installieren

MPU9250_asukiaaa

Tabelle 1: Übersicht der Demos
Demo Funktion
DemoUnoR4Wifi.ino Demo zum Senden von Sensordaten via Wifi für die Arduino IDE
DemoUnoR4Wifi.m Demo zum Empfangen von Sensordaten via Wifi mit MATLAB®
GetDate.ino Demo zum Auslesen der IMU-Daten des Sensors MPU 9250
E15_RadInkrementalgeberFahrt.ino Demo zum Ansteuern der Motoren und auslesen der Odometrie des AlphaBot

Weitere AlphaBot und Arduino Demos finden Sie im SVN-Repositorium

https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/

MATLAB®

Simulink

Messung

Video

How to use MPU-9250 Gyroscope, Accelerometer, Magnetometer for Arduino

Datenblätter


→ zurück zum Hauptartikel: Sensor-Baukasten | HSHL-Mechatronik-Baukasten