Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Explorer les capteurs MEMS : Accéléromètres, Gyroscopes et Magnétomètres pour projets Arduino

Introduction

Dans ce tutoriel, nous allons apprendre comment fonctionnent l'accéléromètre MEMS, le gyroscope et le magnétomètre, et comment les utiliser avec la carte Arduino. Aussi, avec l'IDE Processing, nous réaliserons quelques applications pratiques en utilisant ces capteurs. Vous pouvez regarder la vidéo suivante ou lire le tutoriel écrit ci-dessous.

Qu'est-ce que MEMS ?

Les MEMS (Micro-Electro-Mechanical Systems) sont des systèmes ou dispositifs très petits, composés de micro-composants dont la taille varie de 0,001 mm à 0,1 mm. Ces composants sont faits de silicium, polymères, métaux et/ou céramiques, et ils sont généralement combinés avec un CPU (microcontrôleur) pour compléter le système.

Nous allons maintenant expliquer brièvement comment fonctionne chacun de ces capteurs MEMS.

Accéléromètre MEMS

Il mesure l'accélération en mesurant le changement de capacité. Sa microstructure ressemble à ceci : il a une masse attachée à un ressort qui est contrainte à se déplacer dans une direction et des plaques externes fixes. Lorsqu'une accélération dans la direction particulière est appliquée, la masse se déplace et la capacité entre les plaques et la masse change. Ce changement de capacité est mesuré, traité et correspondra à une valeur d'accélération particulière.

Explorer les capteurs MEMS : Accéléromètres, Gyroscopes et Magnétomètres pour projets Arduino

Gyroscope MEMS

Le gyroscope mesure le taux de rotation angulaire en utilisant l'effet Coriolis. Lorsqu'une masse se déplace dans une direction particulière avec une vitesse particulière et qu'un taux de rotation angulaire externe est appliqué (comme montré par la flèche verte), une force se produit (comme montré par la flèche bleue/rouge), ce qui causera un déplacement perpendiculaire de la masse. Comme pour l'accéléromètre, ce déplacement causera un changement de capacité qui sera mesuré, traité et correspondra à un taux de rotation angulaire particulier.

Explorer les capteurs MEMS : Accéléromètres, Gyroscopes et Magnétomètres pour projets Arduino

La microstructure du gyroscope ressemble à ceci : une masse qui est constamment en mouvement, ou qui oscille, et lorsque le taux de rotation angulaire externe sera appliqué, une partie flexible de la masse se déplacera et fera le déplacement perpendiculaire.

Explorer les capteurs MEMS : Accéléromètres, Gyroscopes et Magnétomètres pour projets Arduino

Magnétomètre MEMS

Il mesure le champ magnétique terrestre en utilisant l'effet Hall ou l'effet magnéto-résistif. En fait, près de 90 % des capteurs sur le marché utilisent l'effet Hall et voici comment cela fonctionne.

Explorer les capteurs MEMS : Accéléromètres, Gyroscopes et Magnétomètres pour projets Arduino

Si nous avons une plaque conductrice comme montré sur la photo et que nous faisons circuler un courant à travers elle, les électrons circuleraient en ligne droite d'un côté à l'autre de la plaque. Maintenant, si nous approchons un champ magnétique près de la plaque, nous perturberions le flux rectiligne et les électrons se dévieraient vers un côté de la plaque et les pôles positifs vers l'autre côté. Cela signifie que si nous mettons un voltmètre maintenant entre ces deux côtés, nous obtiendrions une tension qui dépend de la force du champ magnétique et de sa direction.

Explorer les capteurs MEMS : Accéléromètres, Gyroscopes et Magnétomètres pour projets Arduino

Les autres 10 % des capteurs sur le marché utilisent l'effet magnéto-résistif. Ces capteurs utilisent des matériaux sensibles au champ magnétique, généralement composés de Fer (Fe) et de Nickel (Ni). Lorsque ces matériaux sont exposés à un champ magnétique, ils changent leur résistance.

Arduino et capteurs MEMS


OK, maintenant connectons ces capteurs à la carte Arduino et faisons-en bon usage. Comme exemple, j'utiliserai la carte de dérivation GY-80 qui possède les capteurs suivants : ADXL345 accéléromètre 3 axes, L3G4200D gyroscope 3 axes, MC5883L magnétomètre 3 axes, et aussi un baromètre et un thermomètre que nous n'utiliserons pas dans ce tutoriel.

Vous pouvez obtenir ces composants sur les sites ci-dessous :

Explorer les capteurs MEMS : Accéléromètres, Gyroscopes et Magnétomètres pour projets Arduino

Cette carte utilise le protocole de communication I2C, ce qui signifie que nous pouvons utiliser tous les capteurs avec seulement deux fils. Afin d'établir la communication entre l'Arduino et les capteurs, nous devons connaître leurs adresses de périphérique uniques et leurs adresses de registres internes pour récupérer les données. Ces adresses peuvent être trouvées dans les fiches techniques des capteurs :

Pour plus de détails sur le fonctionnement de la communication I2C, vous pouvez consulter mon autre tutoriel sur le protocole de communication I2C.

Code source

Voyons maintenant les codes pour récupérer les données des capteurs. Nous commencerons par l'accéléromètre et il y aura quelques explications avant chaque code, ainsi que des descriptions supplémentaires dans les commentaires du code.

Code Arduino Accéléromètre

Tout d'abord, nous devons inclure la bibliothèque Arduino Wire et définir les adresses des registres du capteur. Dans la section setup, nous devons initialiser la bibliothèque Wire et démarrer la communication série car nous utiliserons le moniteur série pour afficher les résultats. Aussi ici, nous devons activer le capteur, ou activer la mesure en envoyant l'octet approprié au registre Power_CTL et voici comment nous faisons cela. En utilisant la fonction Wire.beginTransmission(), nous sélectionnons à quel capteur nous allons parler, l'accéléromètre 3 axes dans ce cas. Ensuite, en utilisant la fonction Wire.write(), nous disons à quel registre interne nous allons parler. Après cela, nous enverrons l'octet approprié pour activer la mesure. En utilisant la fonction Wire.endTransmission(), nous terminerons la transmission et cela transmettra les données aux registres.

Dans la section loop, nous devons lire les données pour chaque axe. Nous commencerons avec l'axe X. Donc d'abord, nous sélectionnerons à quels registres nous allons parler, les deux registres internes de l'axe X dans ce cas. Ensuite, en utilisant la fonction Wire.requestFrom(), nous demanderons les données transmises ou les deux octets des deux registres. La fonction Wire.available() retournera le nombre d'octets disponibles pour la récupération et si ce nombre correspond à nos octets demandés, dans notre cas 2 octets, en utilisant la fonction Wire.read(), nous liront les octets des deux registres de l'axe X.

Les données de sortie des registres sont en complément à deux, avec X0 comme octet de poids faible et X1 comme octet de poids fort, donc nous devons convertir ces octets en valeurs float de -1 à +1 selon la direction de l'axe X par rapport à l'accélération terrestre ou la gravité. Nous répéterons cette procédure pour les deux autres axes et à la fin, nous afficherons ces valeurs sur le moniteur série.

#include <Wire.h>

//--- Adresses des registres de l'accéléromètre
#define Power_Register 0x2D
#define X_Axis_Register_DATAX0 0x32 // Adresse hexadécimale pour le registre interne DATAX0
#define X_Axis_Register_DATAX1 0x33 // Adresse hexadécimale pour le registre interne DATAX1
#define Y_Axis_Register_DATAY0 0x34
#define Y_Axis_Register_DATAY1 0x35
#define Z_Axis_Register_DATAZ0 0x36
#define Z_Axis_Register_DATAZ1 0x37

int ADXAddress = 0x53; // Adresse du périphérique incluant le 8ème bit pour sélectionner le mode, lecture dans ce cas
int X0,X1,X_out;
int Y0,Y1,Y_out;
int Z1,Z0,Z_out;
float Xa,Ya,Za;

void setup() {
  Wire.begin(); // Initialise la bibliothèque Wire
  Serial.begin(9600);
  delay(100);
  Wire.beginTransmission(ADXAddress);
  Wire.write(Power_Register); // Registre Power_CTL
  // Activer la mesure
  Wire.write(8); // Bit D3 High pour activer la mesure (0000 1000)
  Wire.endTransmission();
}

void loop() {
  // Axe X
  Wire.beginTransmission(ADXAddress); // Début de transmission au capteur
  // Demande les registres particuliers pour les données
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);
  Wire.endTransmission(); // Termine la transmission et transmet les données des deux registres
  Wire.requestFrom(ADXAddress,2); // Demande les deux octets transmis des deux registres
  if(Wire.available()<=2) {
    // X0 = Wire.read(); // Lit les données du registre
    X1 = Wire.read();
    /* Conversion des données brutes de l'axe X en accélération de l'axe X - Les données de sortie sont en complément à deux - X0 comme octet de poids faible - X1 comme octet de poids fort */
    X1=X1<<8;
    X_out =X0+X1;
    Xa=X_out/256.0; // Xa = valeur de sortie de -1 à +1, accélération de gravité agissant sur l'axe X
  }
  
  // Axe Y
  Wire.beginTransmission(ADXAddress);
  Wire.write(Y_Axis_Register_DATAY0);
  Wire.write(Y_Axis_Register_DATAY1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress,2);
  if(Wire.available()<=2) {
    Y0 = Wire.read();
    Y1 = Wire.read();
    Y1=Y1<<8;
    Y_out =Y0+Y1;
    Ya=Y_out/256.0;
  }
  
  // Axe Z
  Wire.beginTransmission(ADXAddress);
  Wire.write(Z_Axis_Register_DATAZ0);
  Wire.write(Z_Axis_Register_DATAZ1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress,2);
  if(Wire.available()<=2) {
    Z0 = Wire.read();
    Z1 = Wire.read();
    Z1=Z1<<8;
    Z_out =Z0+Z1;
    Za=Z_out/256.0;
  }
  
  // Affiche les données sur le moniteur série
  Serial.print("Xa= ");
  Serial.print(Xa);
  Serial.print(" Ya= ");
  Serial.print(Ya);
  Serial.print(" Za= ");
  Serial.println(Za);
}

Code Arduino Gyroscope

Pour récupérer les données du gyroscope, nous aurons un code similaire au précédent. Donc d'abord, nous devons définir les adresses des registres et quelques variables pour les données. Dans la section setup, nous devons réveiller et mettre le capteur en mode normal en utilisant le CTRL_REG1 et aussi sélectionner la sensibilité du capteur. Pour cet exemple, je sélectionnerai le mode de sensibilité 2000 dps.

Dans la section loop, similaire à l'accéléromètre, nous liront les données pour les axes X, Y et Z. Ensuite, les données brutes doivent être converties en valeurs d'angle. D'après la fiche technique du capteur, nous pouvons voir que pour le mode de sensibilité 2000 dps correspond une unité de 70 mdps/digit. Cela signifie que nous devons multiplier les données de sortie brutes par 0,07 afin d'obtenir le taux de rotation angulaire en degrés par seconde. Ensuite, si nous multiplions le taux de rotation angulaire par le temps, cela nous donnera la valeur de l'angle. Nous devons donc calculer l'intervalle de temps de chaque section de boucle et nous pouvons le faire en utilisant la fonction millis() au début et à la fin de la section loop, et nous stockerons sa valeur dans cette variable "dt". Ainsi, pour chaque boucle exécutée, nous calculerons l'angle et l'ajouterons à la valeur d'angle finale. Nous ferons la même chose pour les deux autres axes et à la fin, nous afficherons les résultats sur le moniteur série.

#include <Wire.h>

//--- Adresses des registres du gyroscope
#define Gyro_gX0 0x28
#define Gyro_gX1 0x29
#define Gyro_gY0 0x2A
#define Gyro_gY1 0x2B
#define Gyro_gZ0 0x2C
#define Gyro_gZ1 0x2D

int Gyro = 0x69; // Adresse du périphérique incluant le 8ème bit pour sélectionner le mode, lecture dans ce cas
int gX0, gX1, gX_out;
int gY0, gY1, gY_out;
int gZ0, gZ1, gZ_out;
float Xg,Yg,Zg;
float angleX,angleY,angleZ,angleXc,angleYc,angleZc;
unsigned long start, finished, elapsed;
float dt=0.015;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  delay(100);
  Wire.beginTransmission(Gyro);
  Wire.write(0x20); // CTRL_REG1 - Mode d'alimentation
  Wire.write(15); // Mode normal: 15d - 00001111b
  Wire.endTransmission();
  Wire.beginTransmission(Gyro);
  Wire.write(0x23); // CTRL_REG4 - Sensibilité, Sélection d'échelle
  Wire.write(48); // 2000dps: 48d - 00110000b
  Wire.endTransmission();
}

void loop() {
  start=millis();
  
  //---- Axe X
  Wire.beginTransmission(Gyro); // transmission au périphérique
  Wire.write(Gyro_gX0);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1);
  if(Wire.available()<=1) {
    gX0 = Wire.read();
  }
  Wire.beginTransmission(Gyro); // transmission au périphérique
  Wire.write(Gyro_gX1);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1);
  if(Wire.available()<=1) {
    gX1 = Wire.read();
  }
  
  //---- Axe Y
  Wire.beginTransmission(Gyro); // transmission au périphérique
  Wire.write(Gyro_gY0);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1);
  if(Wire.available()<=1) {
    gY0 = Wire.read();
  }
  Wire.beginTransmission(Gyro); // transmission au périphérique
  Wire.write(Gyro_gY1);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1);
  if(Wire.available()<=1) {
    gY1 = Wire.read();
  }
  
  //---- Axe Z
  Wire.beginTransmission(Gyro); // transmission au périphérique
  Wire.write(Gyro_gZ0);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1);
  if(Wire.available()<=1) {
    gZ0 = Wire.read();
  }
  Wire.beginTransmission(Gyro); // transmission au périphérique
  Wire.write(Gyro_gZ1);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1);
  if(Wire.available()<=1) {
    gZ1 = Wire.read();
  }
  
  //---------- Axe X
  // Données brutes
  gX1=gX1<<8;
  gX_out =gX0+gX1;
  // D'après la fiche technique : 70 mdps/digit
  Xg=gX_out*0.07; // Taux de rotation angulaire
  // Taux_angulaire * dt = angle
  angleXc = Xg*dt;
  angleX = angleX + angleXc;
  
  //---------- Axe Y
  gY1=gY1<<8;
  gY_out =gY0+gY1;
  Yg=gY_out*0.07;
  angleYc = Yg*dt;
  angleY = angleY + angleYc;
  
  //---------- Axe Z
  gZ1=gZ1<<8;
  gZ_out =gZ0+gZ1;
  Zg=gZ_out*0.07;
  angleZc = Zg*dt;
  angleZ = angleZ + angleZc;
  
  // Affiche les données sur le moniteur série
  Serial.print("angleX= ");
  Serial.print(angleX);
  Serial.print(" angleY= ");
  Serial.print(angleY);
  Serial.print(" angleZ= ");
  Serial.println(angleZ);
  delay(10);
  
  // Calcul de dt
  finished=millis();
  elapsed=finished-start;
  dt=elapsed/1000.0;
  start = elapsed = 0;
}

Code Arduino Magnétomètre

Encore une fois, nous utiliserons une technique similaire à la précédente. D'abord, nous devons définir les adresses des registres et dans la section setup, mettre le capteur en mode de mesure continue. Dans la section loop, nous récupérerons les données brutes pour chaque axe avec la même méthode que pour les capteurs précédents.

Ensuite, nous devons convertir les données brutes en valeur de champ magnétique ou en unités Gauss. D'après la fiche technique du capteur, nous pouvons voir que le mode de sensibilité par défaut est 0,92 mG/digit. Cela signifie que nous devons multiplier les données brutes par 0,00092 afin d'obtenir le champ magnétique terrestre en unités Gauss. À la fin, nous afficherons les valeurs sur le moniteur série.

#include <Wire.h> // Bibliothèque I2C Arduino
#define Magnetometer_mX0 0x03
#define Magnetometer_mX1 0x04
#define Magnetometer_mZ0 0x05
#define Magnetometer_mZ1 0x06
#define Magnetometer_mY0 0x07
#define Magnetometer_mY1 0x08

int mX0, mX1, mX_out;
int mY0, mY1, mY_out;
int mZ0, mZ1, mZ_out;
float Xm,Ym,Zm;

#define Magnetometer 0x1E // Adresse I2C 7 bits du HMC5883

void setup(){
  // Initialise les communications Série et I2C
  Serial.begin(9600);
  Wire.begin();
  delay(100);
  Wire.beginTransmission(Magnetometer);
  Wire.write(0x02); // Sélectionne le registre de mode
  Wire.write(0x00); // Mode de mesure continue
  Wire.endTransmission();
}

void loop(){
  //---- Axe X
  Wire.beginTransmission(Magnetometer); // transmission au périphérique
  Wire.write(Magnetometer_mX1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1) {
    mX0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmission au périphérique
  Wire.write(Magnetometer_mX0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1) {
    mX1 = Wire.read();
  }
  
  //---- Axe Y
  Wire.beginTransmission(Magnetometer); // transmission au périphérique
  Wire.write(Magnetometer_mY1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1) {
    mY0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmission au périphérique
  Wire.write(Magnetometer_mY0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1) {
    mY1 = Wire.read();
  }
  
  //---- Axe Z
  Wire.beginTransmission(Magnetometer); // transmission au périphérique
  Wire.write(Magnetometer_mZ1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1) {
    mZ0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmission au périphérique
  Wire.write(Magnetometer_mZ0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1) {
    mZ1 = Wire.read();
  }
  
  //---- Axe X
  mX1=mX1<<8;
  mX_out =mX0+mX1;
  // Données brutes
  // D'après la fiche technique : 0,92 mG/digit
  Xm = mX_out*0.00092; // Unité Gauss
  // * Le champ magnétique terrestre varie de 0,25 à 0,65 Gauss, ce sont donc les valeurs que nous devons obtenir approximativement.
  
  //---- Axe Y
  mY1=mY1<<8;
  mY_out =mY0+mY1;
  Ym = mY_out*0.00092;
  
  //---- Axe Z
  mZ1=mZ1<<8;
  mZ_out =mZ0+mZ1;
  Zm = mZ_out*0.00092;
  
  // Affiche les valeurs de chaque axe
  Serial.print("x: ");
  Serial.print(Xm);
  Serial.print(" y: ");
  Serial.print(Ym);
  Serial.print(" z: ");
  Serial.println(Zm);
  delay(50);
}

Voici une belle application du capteur, une boussole numérique MEMS, réalisée avec l'IDE Processing. Vous pouvez trouver plus de détails et le code source de cet exemple sur le lien suivant :

Explorer les capteurs MEMS : Accéléromètres, Gyroscopes et Magnétomètres pour projets Arduino

Processus de fabrication

  1. Qu'est-ce qu'un magnétomètre ? Fondamentaux, principes et applications réelles
  2. Exploiter les données dans l'Internet de la fiabilité : stratégies pour une gestion efficace
  3. Construire un jeu gyroscopique temps réel avec Arduino Nano et capteur MPU-6050
  4. Affichage LED Interactif Gyroscopique avec Anneau NeoPixel et Arduino
  5. Capteur CO2 K30 : Surveillance en temps réel de la qualité de l'air intérieur
  6. Faciliter la communication sourd-aveugle avec 1Sheeld et Arduino
  7. Construire une Tirelire Intelligente : Contrôler un Accepteur de Pièces avec Arduino Nano
  8. Contrôler une LED par Bluetooth avec Arduino et MIT App Inventor
  9. Intégrer un capteur d'empreintes capacitif DFRobot (ID809) avec Arduino ou ESP8266