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

Qu'est-ce que le MEMS ? Accéléromètre, Gyroscope et Magnétomètre avec Arduino

Dans ce didacticiel, nous apprendrons comment fonctionnent l'accéléromètre, le gyroscope et le magnétomètre MEMS et comment les utiliser avec la carte Arduino. De plus, avec l'IDE de traitement, nous réaliserons des applications pratiques à l'aide des capteurs. Vous pouvez regarder la vidéo suivante ou lire le didacticiel écrit ci-dessous.

Qu'est-ce que MEMS ?

Les MEMS sont de très petits systèmes ou dispositifs, composés de microcomposants dont la taille varie de 0,001 mm à 0,1 mm. Ces composants sont constitués de silicium, de polymères, de métaux et/ou de céramique, et ils sont généralement associés à un CPU (microcontrôleur) pour compléter le système.

Nous allons maintenant expliquer brièvement le fonctionnement de chacun de ces capteurs de systèmes micro-électro-mécaniques (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 confiné pour se déplacer le long d'une direction et des plaques extérieures fixes. Ainsi, lorsqu'une accélération dans la direction particulière sera appliquée, la masse se déplacera et la capacité entre les plaques et la masse changera. Ce changement de capacité sera mesuré, traité et il correspondra à une valeur d'accélération particulière.

Gyroscope MEMS

Le gyroscope mesure la vitesse angulaire à l'aide de l'effet Coriolis. Lorsqu'une masse se déplace dans une direction particulière avec une vitesse particulière et lorsqu'une vitesse angulaire externe sera appliquée comme le montre la flèche verte, une force se produira, comme le montre la flèche rouge bleue, qui provoquera un déplacement perpendiculaire de la masse. Donc similaire à l'accéléromètre, ce déplacement va provoquer un changement de capacité qui va être mesuré, traité et il va correspondre à une vitesse angulaire particulière.

La microstructure du gyroscope ressemble à ceci. Une masse qui bouge constamment, ou oscille, et lorsque la vitesse angulaire externe sera appliquée, une partie flexible de la masse se déplacera et fera le déplacement perpendiculaire.

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.

Si nous avons une plaque conductrice comme sur la photo et que nous laissons passer le courant, les électrons passeront directement de l'un à l'autre côté de la plaque. Maintenant, si nous amenons un champ magnétique près de la plaque, nous perturberions le flux rectiligne et les électrons seraient déviés d'un côté de la plaque et les pôles positifs de l'autre côté de la plaque. Cela signifie que si nous mettons maintenant un mètre entre ces deux côtés, nous obtiendrons une tension qui dépend de l'intensité du champ magnétique et de sa direction.


Les 10 % restants 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 (Ne). Ainsi, lorsque ces matériaux sont exposés à un champ magnétique, leur résistance change.

Capteurs Arduino et MEMs


Ok maintenant, connectons ces capteurs à la carte Arduino et utilisons-les. À titre d'exemple, j'utiliserai la carte de dérivation GY-80 qui possède les capteurs suivants :accéléromètre à 3 axes ADXL345, gyroscope à 3 axes L3G4200D, magnétomètre à 3 axes MC5883L ainsi qu'un baromètre et un thermomètre que nous n'utiliserons pas dans ce tutoriel.

Vous pouvez obtenir ces composants sur l'un des sites ci-dessous :

  • Accélérateur 3 axes ADXL345………………………………………………………
  • 2 en 1 :Gyroscope et accéléromètre à 6 axes MPU6050 …………………
  • 3 en 1 :Gyroscope d'accélération de champ magnétique GY-80 à 9 axes……… Amazon 
  • 3 en 1 : Module GY-86 10DOF MS5611 HMC5883L MPU6050……… Banggood  /AliExpress

Cette carte utilise le protocole de communication I2C, ce qui signifie que nous pouvons utiliser tous les capteurs avec seulement deux fils. Donc, pour établir la communication entre l'Arduino et les capteurs, nous devons connaître leurs adresses de périphérique uniques et leurs adresses de registre internes pour en extraire les données. Ces adresses se trouvent dans les fiches techniques des capteurs :

  • ADXL345  Accéléromètre         Fiche technique
  • L3G4200D  Gyroscope              Fiche technique
  • MC5883L  Magnétomètre        Fiche technique

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

Code source

Voyons maintenant les codes pour obtenir les données des capteurs. Nous allons commencer par l'accéléromètre et il y aura des explications avant chaque code, ainsi qu'une description supplémentaire dans les commentaires du code.

Code de l'accéléromètre Arduino

Nous devons d'abord inclure la bibliothèque de câbles Arduino et définir les adresses des registres du capteur. Dans la section de configuration, nous devons lancer la bibliothèque de fils et démarrer la communication série car nous utiliserons le moniteur série pour afficher les résultats. Ici aussi, nous devons activer le capteur ou activer la mesure en envoyant l'octet approprié au registre Power_CTL et voici comment nous procédons. En utilisant la fonction Wire.beginTransmission(), nous sélectionnons le capteur auquel nous allons parler, l'accéléromètre 3 axes dans ce cas. Ensuite, en utilisant la fonction Wire.write(), nous indiquons à 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 mettrons fin à la transmission et cela transmettra les données aux registres.

Dans la section de boucle, nous devons lire les données pour chaque axe. Nous allons commencer par l'axe X. Nous allons donc d'abord sélectionner les registres auxquels 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. Le Wire.available() La fonction renverra 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 le Wire.read() fonction nous allons lire les octets des deux registres de l'axe X.

Les données de sortie des registres sont un complément à deux, avec X0 comme octet le moins significatif et X1 comme octet le plus significatif, nous devons donc convertir ces octets en valeurs flottantes de -1 à +1 en fonction de la direction de l'axe X relatif. à l'accélération terrestre ou à la gravité. Nous répéterons cette procédure pour les deux autres axes et à la fin nous imprimerons ces valeurs sur le moniteur série.

#include <Wire.h>

//--- Accelerometer Register Addresses
#define Power_Register 0x2D
#define X_Axis_Register_DATAX0 0x32 // Hexadecima address for the DATAX0 internal register.
#define X_Axis_Register_DATAX1 0x33 // Hexadecima address for the DATAX1 internal register.
#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;  //Device address in which is also included the 8th bit for selecting the mode, read in this case.

int X0,X1,X_out;
int Y0,Y1,Y_out;
int Z1,Z0,Z_out;
float Xa,Ya,Za;

void setup() {
  Wire.begin(); // Initiate the Wire library    
  Serial.begin(9600);    
  delay(100);
  
  Wire.beginTransmission(ADXAddress);
  Wire.write(Power_Register); // Power_CTL Register
  // Enable measurement
  Wire.write(8); // Bit D3 High for measuring enable (0000 1000)
  Wire.endTransmission();
}

void loop() {
  // X-axis
  Wire.beginTransmission(ADXAddress); // Begin transmission to the Sensor 
  //Ask the particular registers for data
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);  
  Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers
  Wire.requestFrom(ADXAddress,2); // Request the transmitted two bytes from the two registers
  if(Wire.available()<=2) {  // 
    X0 = Wire.read(); // Reads the data from the register
    X1 = Wire.read();
    /* Converting the raw data of the X-Axis into X-Axis Acceleration
     - The output data is Two's complement 
     - X0 as the least significant byte
     - X1 as the most significant byte */ 
    X1=X1<<8;
    X_out =X0+X1;
    Xa=X_out/256.0; // Xa = output value from -1 to +1, Gravity acceleration acting on the X-Axis
  }
  // Y-Axis
  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;
  }
  // Z-Axis
  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;
  }
  // Prints the data on the Serial Monitor
  Serial.print("Xa= ");
  Serial.print(Xa);
  Serial.print("   Ya= ");
  Serial.print(Ya);
  Serial.print("   Za= ");
  Serial.println(Za);
}
Code language: Arduino (arduino)

Code du gyroscope Arduino

Pour obtenir les données du gyroscope, nous aurons un code similaire au précédent. Nous devons donc d'abord définir les adresses de registre et certaines variables pour les données. Dans la section de configuration, nous devons réveiller et mettre le capteur en mode normal à l'aide de CTRL_REG1 et également sélectionner la sensibilité du capteur. Pour cet exemple, je sélectionnerai le mode de sensibilité 2000dps.

Dans la section de boucle similaire à l'accéléromètre, nous lirons 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 qu'au mode de sensibilité 2000dps correspond une unité de 70 mdps/chiffre. Cela signifie que nous devons multiplier les données de sortie brutes par 0,07 afin d'obtenir la vitesse angulaire en degrés par seconde. Ensuite, si vous multipliez la vitesse 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() en haut et en bas de la section de boucle, 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 finale de l'angle. Nous ferons de même pour les deux autres axes et à la fin nous imprimerons les résultats dans le moniteur série.

#include <Wire.h>

//--- Gyro Register Addresses
#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; //Device address in which is also included the 8th bit for selecting the mode, read in this case.

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 - Power Mode
  Wire.write(15);   // Normal mode: 15d - 00001111b   
  Wire.endTransmission();
  
  Wire.beginTransmission(Gyro);
  Wire.write(0x23); // CTRL_REG4 - Sensitivity, Scale Selection
  Wire.write(48);   // 2000dps: 48d - 00110000b
  Wire.endTransmission();
}

void loop()
{
  start=millis();
  //---- X-Axis
  Wire.beginTransmission(Gyro); // transmit to device
  Wire.write(Gyro_gX0);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1); 
  if(Wire.available()<=1)   
  {
    gX0 = Wire.read();
  }
  Wire.beginTransmission(Gyro); // transmit to device
  Wire.write(Gyro_gX1);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1); 
  if(Wire.available()<=1)   
  {
    gX1 = Wire.read();
  }

  //---- Y-Axis
  Wire.beginTransmission(Gyro); // transmit to device
  Wire.write(Gyro_gY0);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1); 
  if(Wire.available()<=1)   
  {
    gY0 = Wire.read();
  }
  Wire.beginTransmission(Gyro); // transmit to device
  Wire.write(Gyro_gY1);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1); 
  if(Wire.available()<=1)   
  {
    gY1 = Wire.read();
  }
  
  //---- Z-Axis
  Wire.beginTransmission(Gyro); // transmit to device
  Wire.write(Gyro_gZ0);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1); 
  if(Wire.available()<=1)   
  {
    gZ0 = Wire.read();
  }
  Wire.beginTransmission(Gyro); // transmit to device
  Wire.write(Gyro_gZ1);
  Wire.endTransmission();
  Wire.requestFrom(Gyro,1); 
  if(Wire.available()<=1)   
  {
    gZ1 = Wire.read();
  }
  
  //---------- X - Axis
  
  // Raw Data
  gX1=gX1<<8;
  gX_out =gX0+gX1;
  
  // From the datasheet: 70 mdps/digit
  Xg=gX_out*0.07; // Angular rate
  // Angular_rate * dt = angle
  angleXc = Xg*dt;
  angleX = angleX + angleXc;

  //---------- Y - Axis
  gY1=gY1<<8;
  gY_out =gY0+gY1;
  Yg=gY_out*0.07;
  angleYc = Yg*dt;
  angleY = angleY + angleYc;
  
  //---------- Z - Axis
  gZ1=gZ1<<8;
  gZ_out =gZ0+gZ1;
  Zg=gZ_out*0.07;
  angleZc = Zg*dt;
  angleZ = angleZ + angleZc;

  
  // Prints the data on the Serial Monitor
  Serial.print("angleX= ");
  Serial.print(angleX);
  Serial.print("   angleY= ");
  Serial.print(angleY);
  Serial.print("   angleZ= ");
  Serial.println(angleZ);
  
  delay(10);
  // Calculating dt
  finished=millis();
  elapsed=finished-start;
  dt=elapsed/1000.0;
  start = elapsed = 0;
  
}Code language: Arduino (arduino)

Code du magnétomètre Arduino

Encore une fois, nous utiliserons une technique similaire à la précédente. Nous devons d'abord définir les adresses des registres et la section de configuration définit le capteur en mode de mesure continue. Dans la section boucle, nous obtiendrons 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 de 0,92 mG/chiffre. 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 imprimerons les valeurs sur le moniteur série.

#include <Wire.h> //I2C Arduino Library

#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 //I2C 7bit address of HMC5883

void setup(){
  //Initialize Serial and I2C communications
  Serial.begin(9600);
  Wire.begin();
  delay(100);
  
  Wire.beginTransmission(Magnetometer); 
  Wire.write(0x02); // Select mode register
  Wire.write(0x00); // Continuous measurement mode
  Wire.endTransmission();
}

void loop(){
 
  //---- X-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mX1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mX0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mX0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mX1 = Wire.read();
  }

  //---- Y-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mY1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mY0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mY0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mY1 = Wire.read();
  }
  
  //---- Z-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mZ1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mZ0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mZ0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mZ1 = Wire.read();
  }
  
  //---- X-Axis
  mX1=mX1<<8;
  mX_out =mX0+mX1; // Raw data
  // From the datasheet: 0.92 mG/digit
  Xm = mX_out*0.00092; // Gauss unit
  //* Earth magnetic field ranges from 0.25 to 0.65 Gauss, so these are the values that we need to get approximately.

  //---- Y-Axis
  mY1=mY1<<8;
  mY_out =mY0+mY1;
  Ym = mY_out*0.00092;

  //---- Z-Axis
  mZ1=mZ1<<8;
  mZ_out =mZ0+mZ1;
  Zm = mZ_out*0.00092;
 
  //Print out values of each axis
  Serial.print("x: ");
  Serial.print(Xm);
  Serial.print("  y: ");
  Serial.print(Ym);
  Serial.print("  z: ");
  Serial.println(Zm);
  
  delay(50);
}Code language: Arduino (arduino)

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


Processus de fabrication

  1. Qu'est-ce qu'un magnétomètre ?
  2. Que dois-je faire avec les données ? !
  3. Jeu de gyroscope Arduino avec MPU-6050
  4. Gyroscope amusant avec l'anneau NeoPixel
  5. Surveillance du CO2 avec le capteur K30
  6. Communication sourds-aveugles avec 1Sheeld/Arduino
  7. Contrôler l'accepteur de pièces avec Arduino
  8. Arduino avec Bluetooth pour contrôler une LED !
  9. Capteur d'empreintes digitales capacitif avec un Arduino ou ESP8266