Wie finden Sie diesen Artikel? Helfen Sie uns, bessere Inhalte für Sie bereitzustellen.
Vielen Dank! Ihr Feedback ist eingegangen.
There was a problem submitting your feedback, please try again later.
Was denken Sie über diesen Artikel?
Dieses Projekt zeigt Ihnen, wie Sie Digilent Pmod NAV (134-6482) 9-Achsen-IMU Plus-Barometer und Arduino Uno (715-4081) verwenden, um die Winkelgeschwindigkeit, die Beschleunigung und das Magnetfeld von XYZ-Vektoren zu erfassen. Pitch-, Roll- und Heading-Werte werden ebenfalls aus den Messdaten berechnet. Die Daten werden im seriellen Monitor angezeigt.
Digilent Pmod NAV
Digilent Pmod NAV wird mit dem 3-Achsen-Beschleunigungsmesser STMicro LSM9DS1, dem 3-Achsen-Gyroskop, dem 3-Achsen-Magnetometer und dem digitalen Barometer STMicro LPS25HB betrieben. Mit 16-Bit-Vollskalenregistern für Beschleunigung, Rotation und Orientierung und 24-Bit-Auflösung für Druckdaten können Anwender leicht herausfinden, ob ihr fahrender Roboter umkippt, wie hoch in der Luft sich ihr Heißluftballon befindet oder in welche Richtung er schaut.
Alle Daten werden als lineare Beschleunigung gemessen, da jede Achse einzeln gemessen wird und alle voneinander isoliert sind. Gyroskope messen die Winkeldrehrate des Moduls und geben die Gradzahl pro Sekunde (dps) an, um die das Modul um jede Achse gedreht wird. Die Empfindlichkeit liegt bei bis zu ±2000 dps. Das Magnetometer erfasst das Magnetfeld um das Modul, einschließlich des Erdmagnetfelds sowie der lokalen magnetischen Umgebung um das Modul. Jedes der drei Magnetachsenregister liefert vorzeichenbehaftete 16-Bit-Vollwertdaten mit einer Empfindlichkeit von bis zu ±16 Gauss, ein Barometer mit einem Absolutdruckbereich von 260 bis 1260 hPa, was ungefähr 0,25 bis 1,25 atm entspricht.
Hardware-Einrichtung
Der Pmod NAV kommuniziert mit dem Arduino Uno über das I2C-Kommunikationsprotokoll. Zunächst müssen Sie den Pmod NAV an den Arduino Uno anschließen. Hier finden Sie die Verdrahtungsanleitung.
Pmod NAV Pin | Arduino Uno Pin |
---|---|
Stiftleiste J1 Pin 6 (3V3 - 3,3V Stromversorgung) 3V3 | 3V3 |
Stiftleiste J1 Pin 5 (GND - Masse) GND | GND |
Stiftleiste J1 Pin 4 (SCK - Serieller Takt) A5 (SCL) | A5 (SCL) |
Stiftleiste J1 Pin 2 (SDI - Master-Out-Slave-In)* >A4 (SDA) | >A4 (SDA) |
* Hinweis: Wir können SDI als I2C Serial Data (SDA) verwenden (siehe LMSDS1-Datenblatt Digital Interfaces, Seite 28)
Arduino-Entwurf
Wir beziehen SparkFun LSM9DS1-Bibliothek und Wire-Bibliothek ein. Mit dem LSM9DS1 können Sie den Pmod NAV konfigurieren und die Funktionen einfacher ausführen, während die Wire-Bibliothek die Kommunikation mit I2C-Geräten unterstützt. Das Projekt basiert auf dem Beispiel LSM9DS1_Basic_I2C, das in dieser Bibliothek zu finden ist.
Die Adressen der Geräte finden wir im Datenblatt: 0x1E (Magnetometer) sowie 0x6B (Beschleunigungsmesser und Gyroskop). Da das Magnetfeld der Erde von einem Ort zum anderen variiert, müssen wir die Deklination addieren oder subtrahieren, um den richtigen Wert des Magnetfelds zu erhalten.
Als nächstes müssen wir Objekte erstellen und die I2C-Kommunikation initialisieren. Wir verwenden drei verschiedene Funktionen, um die Beschleunigung, die Winkeldrehung bzw. das Magnetfeld zu messen. Wir erstellen auch drei Funktionen, um drei Datensätze anzuzeigen. Die Höhe wird anhand der gemessenen Beschleunigung und des Magnetfelds berechnet.
Die Ausgabe wird unten gezeigt:
/************************************************************************
Test of Pmod NAV (Based on Jim Lindblom's program)
*************************************************************************
Description: Pmod_NAV
All data (accelerometer, gyroscope, magnetometer) are displayed
In the serial monitor
Material
1. Arduino Uno
2. Pmod NAV (dowload library
https://github.com/sparkfun/SparkFun_LSM9DS1_Arduino_Library )
Licence Beerware
Wiring
Module<--------------------> Arduino
J1 pin 6 (3V3) to 3V3
J1 pin 5 (GND) to GND
J1 pin 4 (SCK) to A5 (SCL)
J1 pin 2 (SDI) to A4 (SDA)
************************************************************************/
// The earth's magnetic field varies according to its location.
// Add or subtract a constant to get the right value
// of the magnetic field using the following site
// http://www.ngdc.noaa.gov/geomag-web/#declination
#define DECLINATION -5.55 // declination (in degrees) in Cluj-Napoca (Romania).
/************************************************************************/
#define PRINT_CALCULATED //print calculated values
//#define PRINT_RAW //print raw data
// Call of libraries
#include <Wire.h>
#include <SparkFunLSM9DS1.h>
// defining module addresses
#define LSM9DS1_M 0x1E //magnetometer
#define LSM9DS1_AG 0x6B //accelerometer and gyroscope
LSM9DS1 imu; // Creation of the object
void setup(void)
{
Serial.begin(115200); // initialization of serial communication
Wire.begin(); //initialization of the I2C communication
imu.settings.device.commInterface = IMU_MODE_I2C; // initialization of the module
imu.settings.device.mAddress = LSM9DS1_M; //setting up addresses
imu.settings.device.agAddress = LSM9DS1_AG;
if (!imu.begin()) //display error message if that's the case
{
Serial.println("Communication problem.");
while (1);
}
}
void loop()
{
//measure
if ( imu.gyroAvailable() )
{
imu.readGyro(); //measure with the gyroscope
}
if ( imu.accelAvailable() )
{
imu.readAccel(); //measure with the accelerometer
}
if ( imu.magAvailable() )
{
imu.readMag(); //measure with the magnetometer
}
//display data
printGyro(); // Print "G: gx, gy, gz"
printAccel(); // Print "A: ax, ay, az"
printMag(); // Print "M: mx, my, mz"
printAttitude(imu.ax, imu.ay, imu.az, -imu.my, -imu.mx, imu.mz); //print pitch, roll and heading
Serial.println();
delay(1000);
}
//display gyroscope data
void printGyro()
{
Serial.print("G: ");
#ifdef PRINT_CALCULATED
Serial.print(imu.calcGyro(imu.gx), 2); //calculate angular velocity
Serial.print(", ");
Serial.print(imu.calcGyro(imu.gy), 2);
Serial.print(", ");
Serial.print(imu.calcGyro(imu.gz), 2);
Serial.println(" deg/s"); //measured in deg/s
#elif defined PRINT_RAW
Serial.print(imu.gx); //or display raw data
Serial.print(", ");
Serial.print(imu.gy);
Serial.print(", ");
Serial.println(imu.gz);
#endif
}
//display accelerometer data
void printAccel()
{
Serial.print("A: ");
#ifdef PRINT_CALCULATED
Serial.print(imu.calcAccel(imu.ax), 2); //calculate acceleration
Serial.print(", ");
Serial.print(imu.calcAccel(imu.ay), 2);
Serial.print(", ");
Serial.print(imu.calcAccel(imu.az), 2);
Serial.println(" g"); //measured in g
#elif defined PRINT_RAW
Serial.print(imu.ax); //or display raw data
Serial.print(", ");
Serial.print(imu.ay);
Serial.print(", ");
Serial.println(imu.az);
#endif
}
//display magnetometer data
void printMag()
{
Serial.print("M: ");
#ifdef PRINT_CALCULATED
Serial.print(imu.calcMag(imu.mx), 2); //calculate magnetic field components
Serial.print(", ");
Serial.print(imu.calcMag(imu.my), 2);
Serial.print(", ");
Serial.print(imu.calcMag(imu.mz), 2);
Serial.println(" gauss"); //measured in gauss
#elif defined PRINT_RAW
Serial.print(imu.mx); //or display raw data
Serial.print(", ");
Serial.print(imu.my);
Serial.print(", ");
Serial.println(imu.mz);
#endif
}
//display additional calculated values
void printAttitude(float ax, float ay, float az, float mx, float my, float mz)
{
float roll = atan2(ay, az); //calculate roll
float pitch = atan2(-ax, sqrt(ay * ay + az * az)); //calculate pitch
float heading; //variable for hading
//calculate heading
if (my == 0) {
heading = (mx < 0) ? PI : 0;
}
else {
heading = atan2(mx, my);
}
//correct heading according to declination
heading -= DECLINATION * PI / 180;
if (heading > PI) {
heading -= (2 * PI);
}
else if (heading < -PI) {
heading += (2 * PI);
}
else if (heading < 0) {
heading += 2 * PI;
}
//convert values in degree
heading *= 180.0 / PI;
pitch *= 180.0 / PI;
roll *= 180.0 / PI;
//display calculated data
Serial.print("Pitch, Roll: ");
Serial.print(pitch, 2);
Serial.print(", ");
Serial.print(roll, 2);
Serial.println(" °");
Serial.print("Heading: ");
Serial.print(heading, 2);
Serial.println(" °");
}