Hey! Sie scheinen aus United States zu kommen, möchten Sie auf die Englisch Webseite wechseln?
Switch to Englisch site
Skip to main content

Verwendung des 9-Achsen-IMU Plus-Barometers Arduino und Digilent Pmod NAV zur Erfassung orientierungsbezogener Daten

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.

Pmod_NAV_-_Top_-_600__82166.1476915037_.1280_.1280__d5e813df37169415d0120e377e9647b3ab182f92.png

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)

wiring diagram

* 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:

output_vLOvcTsQ3m2_1f542e0d2ba5450272e7a1bd981e04caec4c2887.png

/************************************************************************

  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(" °");
}
awong hat noch keine Biografie verfasst...