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 | ||
| 2 | Masse GND | 3-5 V | VCC, 3,3 V |
| 3 | SCL | Empfang von Daten | TX, D4 |
| 4 | SDA | Senden von Daten | RX, D3 |
| 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.
| DemoI2C_Scanner.ino |
#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(){}
|
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.
| Chip | WHO_AM_I |
|---|---|
| MPU-6500 | 0x70
|
| MPU-9250 | 0x71
|
| DemoWhoAmI.ino |
#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() {
}
|
URL: https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/ArduinoUnoR3/examples/DemoWhoAmI/DemoWhoAmI.ino
Arduino-Bibliothek installieren
MPU9250_asukiaaa
| 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 |
| DemoUnoR4Wifi.ino |
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
|
| GetDate.ino aus der Bibliothek MPU9250_asukiaaa | ||
#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);
}
|
| E15_RadInkrementalgeberFahrt.ino |
/* 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 */
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
}
}
|
Weitere AlphaBot und Arduino Demos finden Sie im SVN-Repositorium
https://svn.hshl.de/svn/Informatikpraktikum_1/trunk/Arduino/ArduinoLibOrdner/
MATLAB®
Simulink
Messung
Video
Datenblätter
→ zurück zum Hauptartikel: Sensor-Baukasten | HSHL-Mechatronik-Baukasten