chercheursduvrai.fr
To view this board in english, you must be registered.

  Reply to this topicStart new topicStart Poll

> Capteur Boussole HMC5883L
Ecrit le: Lundi 24 Août 2015 à 09h58 Posted since your last visit
Quote Post


Expert(e)
******

Groupe: Membres
Messages: 371
Membre n°: 10456
Inscrit le: 01/12/2013



En robotique, il est parfois utile d'utiliser une Boussole électronique. Ci dessous le test d'un composant HMC5883L de chez Honeywell, monté sur une platine d'essais. Ce type de platine montée avec le composant se trouve facilement à bas coût en provenance de Chine.

Le montage de la Boussole:

user posted image

Le résultat:

user posted image

Les trois premières valeurs sont la valeur en mGa (milli-gauss) des vecteurs X Y et Z mesurés par le composant.

A partir de là, on peut calculer la direction du Nord magnétique, puis en corrigeant avec la déclinaison, la direction du Nord géographique (ici, donnée par Angle en °).

La valeur M donne l'amplitude du vecteur magnétique terrestre Local en mGa, On voit que cette valeur est bien proche de 0.45 Gauss. L'amplitude du vecteur qui s'enfonce dans le sol (en France).
Ce vecteur est horizontal au niveau de l'équateur magnétique, et perpendiculaire au sol au pole Nord magnétique.

Il y a quand même pas mal de perturbation magnétique dues à l’environnement, ce qui fausse entre autre la valeur de l'inclinaison  du vecteur M par rapport au sol, qui devrait plutôt être au voisinage de 60°.

Par la suite, il faudrait ajouter du code pour faire un étalonnage, qui en fait ne sera valable que dans un environnement bien précis.

Cet étalonnage se fait en général en appliquant plusieurs rotations autour de l'axe Z pour la correction des axes X et Y. Puis après avoir pointé l'axe X vers le Nord magnétique des rotations autour de l'axe Y pour la correction de l'axe Z.

Le code du programme:


CODE
/*
 * Boussole numérique avec le module GY-273
 * Compas digital Honeywell HMC5883L
 * Interface I2C interface --> Arduino
 * 16/08/2015 - v0.1 : Adaptation par JCV
 * 23/08/2015 v0.1.1 : Modifié pour lecture des 3 axes en une fois.
 *   Correction du calcul du Nord Géo par la déclinaison (erreur signe).
 *   Ajout du calcul de l'inclinaison.
 */
#include <Wire.h>

#define VERSION "0.1.1"

// Adresse I2C du module HMC5883L
#define HMC5883L_Addr 0x1E

#define ConfigRegisterA 0x00
#define ConfigRegisterB 0x01
#define ModeRegister 0x02

#define Measurement_Continuous 0x00
#define Measurement_SingleShot 0x01
#define Measurement_Idle 0x03

// Adresses de registres pour les données X Y et Z
#define reg_start 0x03 // = reg_X

struct RawValues {
    int XAxis;
    int YAxis;
    int ZAxis;
};

void Init_HMC5883L( void );
void HMC5883L_Read ( void ); // resultat dans rawVal
signed char HMC5883L_Gain( unsigned char gain ); // gain = 0 à 7

struct RawValues rawVal;
float m_Scale = 1.0; // milli-gauss par digit
float x_offset, y_offset, z_offset;

void setup() {
  Serial.begin( 115200 );
  Wire.begin();    // Initialisation de la livrairie Wire
  Serial.print("Boussole numerique GY-273 v");
  Serial.println(VERSION);
  Serial.println();
  Init_HMC5883L(); // Initialiser le module boussole
} // setup

void loop() {
  // lecture sur 3 axes et sortie sur le port série, en milli-Gauss
  HMC5883L_Read(); // Resultat dans rawVal
  float X_magnetic = ((float)rawVal.XAxis - x_offset) * m_Scale;
  float Y_magnetic = ((float)rawVal.YAxis - y_offset) * m_Scale;
  float Z_magnetic = ((float)rawVal.ZAxis - z_offset) * m_Scale;
  Serial.print (X_magnetic);
  Serial.print("\t");
  Serial.print (Y_magnetic);
  Serial.print("\t");
  Serial.print (Z_magnetic);

  // Module du champ, en milli-gauss
  float X_mag2 = (X_magnetic * X_magnetic);
  float Y_mag2 = (Y_magnetic * Y_magnetic);
  float Z_mag2 = (Z_magnetic * Z_magnetic);
  float Module_magnetic = sqrt( X_mag2 + Y_mag2 + Z_mag2 );
  Serial.print("\t  M=");
  Serial.print(Module_magnetic);
  Serial.print("mGa");

  // Calculer l'angle de la boussole à partir de X et Y (à plat), magnetic north
  float angle = atan2( Y_magnetic, X_magnetic ); // en radian
 /* Once you have your angle, you must then add your 'Declination Angle', which is
  * the 'Error' of the magnetic field in your location.
  * Find yours here: http://www.magnetic-declination.com/
  * La mienne est de : 0°24' EAST
  * Le calcul est : (deg + (min / 60)) / (180 : M_PI)
  * Note: D > 0 vers l'Est et < 0 vers l'ouest.
  * Pour avoir la direction du Nord Géographique il faut retrancher la déclinaison.
  */
  float declinationAngle = (0.0+(24.0/60.0))/(180/PI); // en radian
  angle -= declinationAngle; // true north, on soustrait la déclinaison.
  angle *= (180 / PI); // angle en degres
  if ( angle < 0 ) { angle += 360; }
  if ( angle > 360 ) { angle -= 360; } // if declination positive
  Serial.print("\t");
  Serial.print("Angle = "); // en degres
  Serial.print(angle);

  /* Inclinaison magnetique
   */
  float inclinaison = atan2( Z_magnetic, sqrt(X_mag2 + Y_mag2) );
  inclinaison *= (180 / PI); // inclinaison en degres
  Serial.print("\t");
  Serial.print("Inclinaison = "); // en degres
  Serial.print(inclinaison); 
 
  Serial.println();
  delay( 1000 );
} // loop

void Init_HMC5883L( void )
{
  /* Config register A ==> 0 A A DO2 DO1 DO0 MS1 MS2
  A A                      DO2 DO1 DO0      Sample Rate [Hz]   MS1 MS0    Measurment Mode
  0 0 = No Average          0   0   0   =   0.75                0   0   = Normal 
  0 1 = 2 Sample average    0   0   1   =   1.5                 0   1   = Positive Bias
  1 0 = 4 Sample Average    0   1   0   =   3                   1   0   = Negative Bais
  1 1 = 8 Sample Average    0   1   1   =   7.5                 1   1   = -
                            1   0   0   =   15 (Default)
                            1   0   1   =   30
                            1   1   0   =   75
                            1   1   1   =   -
   * Set the module to 8x averaging (0x60) MA[1..0] = b11
   * and 15Hz measurement rate (0x10) DO[2..0] = b100 , pas utilisé en "single shot"
   * and mesurement config bits MS[1..0] = b00
   */
  Wire.beginTransmission( HMC5883L_Addr );
  Wire.write( ConfigRegisterA ); // config register A
  Wire.write( 0x60 | 0x10 | 0x00 );
  Wire.endTransmission();

  /* Le champ magnetique terestre étant de l'ordre de 0.5 gauss
   * On peut mettre l'echelle à 1.3 gauss pour avoir une bonne précision de lecture.
   * sensor field range = +/- 1.3Ga (gain = 1)
   * Gain (Lsb/Gauss) = 1090
   * Digital resolution (mG/Lsb) = 0.92
   */
  if ( HMC5883L_Gain( 2 ) < 0 )
    Serial.println("! scale error.");
  // Pour étallonage éventuel, par rotation dans le plan horizontal et dans le plan vertical.
  x_offset = y_offset = z_offset = 0.0; 
} // Init_HMC5883L

signed char HMC5883L_Gain( unsigned char gain )
{
  switch ( gain ) {
    case 0 :
      m_Scale  = 0.73; // Field Range = 0.88Ga
      break;
    case 1 :
      m_Scale  = 0.92; // Field Range = 1.3Ga
      break;
    case 2 :
      m_Scale  = 1.22; // Field Range = 1.9Ga
      break;
    case 3 :
      m_Scale  = 1.52; // Field Range = 2.5Ga
      break;
    case 4 :
      m_Scale  = 2.27; // Field Range = 4.0Ga
      break;
    case 5 :
      m_Scale  = 2.56; // Field Range = 4.7Ga
      break;
    case 6 :
      m_Scale  = 3.03; // Field Range = 5.6Ga
      break;
    case 7 :
      m_Scale  = 4.35; // Field Range = 8.1Ga
      break;
    default :
      return -1;   
  }
  Wire.beginTransmission( HMC5883L_Addr );
  Wire.write( ConfigRegisterB ); // config register B
  Wire.write( gain << 5 ); // Règle le gain
  Wire.endTransmission();
  return 0;
}

/* Fonction qui lit les 3 axes de la boussole
 */
void HMC5883L_Read ( void )
{
   /* Initiate a single measurement */
  Wire.beginTransmission( HMC5883L_Addr );
  Wire.write( ModeRegister ); // Mode register
  Wire.write( Measurement_SingleShot );
  Wire.endTransmission();
  delay(6); // Wait 6mS

  /* Move modules the resiger pointer to one of the axis data registers */
  Wire.beginTransmission( HMC5883L_Addr );
  Wire.write( reg_start );
  Wire.endTransmission();
  
  /* Read the data from registers (there are two 8 bit registers for each axis) */
  Wire.requestFrom( HMC5883L_Addr, 6 );
  rawVal.XAxis = (Wire.read() << 8) | Wire.read();
  rawVal.ZAxis = (Wire.read() << 8) | Wire.read();
  rawVal.YAxis = (Wire.read() << 8) | Wire.read();
} // HMC5883L_Read


A+
JCV


--------------------
"Face à un problème complexe, il convient de commencer l’approche analytique par la solution la plus simple."
Expression dérivée du principe du Razoir d'occam. William d’Ockham - théologien Franciscain 1285-1349.
PMEmail Poster
Top
Ecrit le: Lundi 24 Août 2015 à 10h13 Posted since your last visit
Quote Post


Expert(e)
******

Groupe: Membres
Messages: 3939
Membre n°: 10047
Inscrit le: 07/11/2011



Très bonne idée que ces flashs tutaux JCV, bravo.


--------------------
« No matter where you are, Look for the brightest star, Believe it is true, My soul is smiling at you", FastWalkers
PM
Top
1 utilisateur(s) sur ce sujet (1 invités et 0 utilisateurs anonymes)
0 membres:

Topic Options Reply to this topicStart new topicStart Poll

 



[ Script Execution time: 0.0309 ]   [ 12 queries used ]   [ GZIP activé ]