Skip to main content

Utiliser Arduino et la centrale inertielle à neuf axes Pmod NAV plus baromètre de Digilent pour obtenir des données relatives à l'orientation

awong
0

Ce projet vous montre comment utiliser la centrale inertielle à neuf axes Pmod NAV  (134-6482)  plus baromètre de Digilent et l'Arduino Uno  (715-4081)  afin d'obtenir la vitesse angulaire, l'accélération et le champ magnétique de vecteurs XYZ. Le tangage, le roulis et le cap sont également calculés à partir des données obtenues. Les données sont affichées dans l'interface d'analyse de port série.

Pmod NAV de Digilent

Le Pmod NAV de  Digilent est doté de l'accéléromètre à trois axes, du gyroscope à trois axes et du magnétomètre à trois axes LSM9DS1 de STMicroelectronics, ainsi que du baromètre numérique LPS25HB de STMicroelectronics. Grâce aux registres à pleine échelle de 16 bits pour l'accélération, la rotation et l'orientation, et à la résolution de 24 bits pour les données relatives à la pression, les utilisateurs peuvent facilement comprendre si leur robot en mouvement est en train de tomber ou non, à quelle altitude leur ballon d'air chaud se trouve, ou à quelle direction ils font face.

L'accéléromètre fournit des valeurs de pleine échelle signées 16 bits d'une sensibilité pouvant aller jusqu'à ±16 G pour chacun des trois axes cartésiens. Toutes les données sont mesurées en tant qu'accélération linéaire étant donné que tous les axes sont mesurés individuellement et sont isolés les uns des autres. Les gyroscopes mesurent la vitesse de rotation angulaire du module, indiquant les degrés par seconde (dps) de rotation du module autour de chaque axe. La sensibilité peut aller jusqu'à ±2 000 dps. Le magnétomètre détecte le champ magnétique présent autour du module, y compris le champ magnétique terrestre et l'environnement magnétique immédiat autour de ce dernier. Chacun des trois registres d'axe magnétique fournit des valeurs de pleine échelle signées 16 bits d'une sensibilité pouvant aller jusqu'à ±16 gauss. Le baromètre permet une plage de mesure de pression absolue allant de 260 à 1260 hPa, ce qui correspond environ à entre 0,25 et 1,25 atm.

Installation du matériel informatique

Le Pmod NAV communique avec l'Arduino Uno via un protocole de communication I2C. Tout d'abord, vous devez connecter le Pmod NAV à l'Arduino Uno. Voici les instructions de câblage.

Pmod NAV Pin Arduino Uno Pin
Broche 6 de la barrette mâle J1 (alimentation électrique de 3,3 V – 3V3) 3V3 3V3
Broche 5 de la barrette mâle J1 (Terre – GND) Terre (GND) Terre (GND)
Broche 4 de la barrette mâle J1 (Horloge – SCK) A5 (Horloge) A5 (Horloge)
Broche 2 de la barrette mâle J1 (SDI – Master-Out-Slave-In)* >A4 (SDA) >A4 (SDA)

wiring diagram

*Remarque : nous pouvons utiliser le SDI en tant que données série I2C (SDA) (reportez-vous à la fiche technique du LMSDS1 , interfaces numériques, page 28).

Programme Sketch d'Arduino

Nous proposons la bibliothèque du LSM9DS1 et la bibliothèque de câbles de SparkFun. Le LSM9DS1 vous permet de configurer le Pmod NAV et exécute les fonctions plus facilement, tandis que la bibliothèque de câbles aide à communiquer avec les périphériques I2C. Le projet se base sur l'example LSM9DS1_Basic_I2C que l'on trouve dans cette bibliothèque.

Nous pouvons trouver les adresses des périphériques sur la fiche technique : 0x1E (magnétomètre) et 0x6B (accéléromètre et gyroscope). Étant donné que le champ magnétique terrestre varie d'un endroit à un autre, nous devons ajouter ou soustraire la déclinaison magnétique afin d'obtenir la bonne valeur pour le champ magnétique.

Ensuite, nous devons créer des objets et initialiser la communication I2C. Nous utilisons trois fonctions différentes pour mesurer respectivement l'accélération, la rotation angulaire et le champ magnétique. Nous créons également trois fonctions afin d'afficher trois ensembles de données. L'altitude est calculée sur la base de l'accélération et du champ magnétique mesurés.

Les résultats sont indiqués ci-dessous :

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

  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(" °");
}
Love learn engineering in hands-on approach. Interested in new technology. Work in Digilent as International Sales and Distribution Manager.

Recommended Articles

Commentaires

DesignSpark Electrical Logolinkedin