Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Was ist MEMS? Beschleunigungssensor, Gyroskop und Magnetometer mit Arduino

In diesem Tutorial erfahren wir, wie der MEMS-Beschleunigungsmesser, das Gyroskop und das Magnetometer funktionieren und wie sie mit dem Arduino-Board verwendet werden. Auch mit der Processing IDE werden wir einige praktische Anwendungen mit den Sensoren machen. Sie können sich das folgende Video ansehen oder das schriftliche Tutorial unten lesen.

Was ist MEMS?

Die MEMS sind sehr kleine Systeme oder Geräte, die aus Mikrokomponenten mit einer Größe von 0,001 mm bis 0,1 mm bestehen. Diese Komponenten bestehen aus Silizium, Polymeren, Metallen und/oder Keramiken und werden normalerweise mit einer CPU (Mikrocontroller) kombiniert, um das System zu vervollständigen.

Nun werden wir kurz erklären, wie jeder dieser Mikro-Elektromechanischen-System (MEMS)-Sensoren funktioniert.

MEMS-Beschleunigungsmesser

Es misst die Beschleunigung durch Messung der Kapazitätsänderung. Seine Mikrostruktur sieht etwa so aus. Es hat eine Masse, die an einer Feder befestigt ist, die sich in eine Richtung bewegen kann, und feste Außenplatten. Wenn also eine Beschleunigung in die bestimmte Richtung ausgeübt wird, bewegt sich die Masse und die Kapazität zwischen den Platten und der Masse ändert sich. Diese Kapazitätsänderung wird gemessen, verarbeitet und entspricht einem bestimmten Beschleunigungswert.

MEMS-Gyroskop

Das Gyroskop misst die Winkelgeschwindigkeit mithilfe des Coriolis-Effekts. Wenn sich eine Masse mit einer bestimmten Geschwindigkeit in eine bestimmte Richtung bewegt und wenn eine externe Winkelgeschwindigkeit angewendet wird, wie mit dem grünen Pfeil gezeigt, tritt eine Kraft auf, wie mit dem blauen roten Pfeil gezeigt, die eine senkrechte Verschiebung der Masse verursacht. Ähnlich wie beim Beschleunigungsmesser bewirkt diese Verschiebung eine Kapazitätsänderung, die gemessen und verarbeitet wird und einer bestimmten Winkelgeschwindigkeit entspricht.

Die Mikrostruktur des Kreisels sieht ungefähr so ​​aus. Eine Masse, die sich ständig bewegt oder oszilliert, und wenn die externe Winkelgeschwindigkeit angewendet wird, würde sich ein flexibler Teil der Masse bewegen und die senkrechte Verschiebung ausführen.

MEMS-Magnetometer

Es misst das Erdmagnetfeld mithilfe des Hall-Effekts oder des magnetoresistiven Effekts. Tatsächlich nutzen fast 90 % der Sensoren auf dem Markt den Hall-Effekt und so funktioniert er.

Wenn wir eine leitfähige Platte wie auf dem Foto gezeigt haben und Strom durch sie fließen lassen, würden die Elektronen direkt von einer Seite der Platte zur anderen fließen. Wenn wir nun ein Magnetfeld in die Nähe der Platte bringen, würden wir den geraden Fluss stören und die Elektronen würden auf eine Seite der Platte und die positiven Pole auf die andere Seite der Platte abgelenkt. Das heißt, wenn wir jetzt einen Meter zwischen diese beiden Seiten legen, erhalten wir eine Spannung, die von der Stärke des Magnetfelds und seiner Richtung abhängt.


Die anderen 10 % der Sensoren auf dem Markt nutzen den magnetoresistiven Effekt. Diese Sensoren verwenden Materialien, die empfindlich auf das Magnetfeld reagieren und normalerweise aus Eisen (Fe) und Nickel (Ne) bestehen. Wenn diese Materialien also einem Magnetfeld ausgesetzt werden, ändern sie ihren Widerstand.

Arduino- und MEMs-Sensoren


Ok, jetzt verbinden wir diese Sensoren mit dem Arduino Board und nutzen sie. Als Beispiel werde ich das Breakout-Board GY-80 verwenden, das über die folgenden Sensoren verfügt:ADXL345 3-Achsen-Beschleunigungsmesser, L3G4200D 3-Achsen-Gyroskop, MC5883L 3-Achsen-Magnetometer sowie ein Barometer und ein Thermometer, die wir in diesem Tutorial nicht verwenden werden.

Sie können diese Komponenten von einer der folgenden Websites beziehen:

  • ADXL345 3-Achsen-Beschleuniger………………………………………………………
  • 2 in 1:MPU6050 6-Achsen-Gyroskop &Beschleunigungsmesser …………………
  • 3 in 1:GY-80 9-Achsen-Magnetfeld-Beschleunigungsgyroskop……… Amazon 
  • 3 in 1: GY-86 10DOF MS5611 HMC5883L MPU6050-Modul ………Banggood  / AliExpress

Dieses Board verwendet das I2C-Kommunikationsprotokoll, was bedeutet, dass wir alle Sensoren mit nur zwei Drähten verwenden können. Um also die Kommunikation zwischen dem Arduino und den Sensoren herzustellen, müssen wir ihre eindeutigen Geräteadressen und ihre internen Registeradressen kennen, um die Daten aus ihnen herauszuholen. Diese Adressen können den Datenblättern der Sensoren entnommen werden:

  • ADXL345  Beschleunigungsmesser         Datenblatt
  • L3G4200D  Gyroskop              Datenblatt
  • MC5883L  Magnetometer        Datenblatt

Weitere Einzelheiten zur Funktionsweise der I2C-Kommunikation finden Sie in meinem anderen I2C-Kommunikationsprotokoll-Tutorial.

Quellcode

Sehen wir uns nun die Codes zum Abrufen der Daten von den Sensoren an. Wir beginnen mit dem Beschleunigungsmesser und vor jedem Code gibt es einige Erläuterungen sowie einige zusätzliche Beschreibungen in den Kommentaren des Codes .

Arduino-Beschleunigungsmessercode

Zuerst müssen wir die Arduino Wire Library einbinden und die Registeradressen des Sensors definieren. Im Setup-Bereich müssen wir die Wire Library initiieren und die serielle Kommunikation starten, da wir den seriellen Monitor zum Anzeigen der Ergebnisse verwenden werden. Auch hier müssen wir den Sensor aktivieren oder die Messung aktivieren, indem wir das entsprechende Byte an das Power_CTL-Register senden, und so machen wir das. Mit der Funktion Wire.beginTransmission() wählen wir aus, mit welchem ​​Sensor wir sprechen, in diesem Fall dem 3-Achsen-Beschleunigungsmesser. Dann teilen wir mit der Funktion Wire.write() mit, mit welchem ​​internen Register wir sprechen werden. Danach senden wir das entsprechende Byte zum Aktivieren der Messung. Mit der Funktion Wire.endTransmission() beenden wir die Übertragung und übertragen die Daten an die Register.

Im Schleifenabschnitt müssen wir die Daten für jede Achse lesen. Wir beginnen mit der X – Achse. Also wählen wir zuerst aus, mit welchen Registern wir sprechen werden, in diesem Fall die beiden internen Register der X-Achse. Dann fordern wir mit der Funktion Wire.requestFrom() die übertragenen Daten bzw. die zwei Bytes aus den beiden Registern an. Die Wire.available() Die Funktion gibt die Anzahl der für den Abruf verfügbaren Bytes zurück, und wenn diese Anzahl mit unseren angeforderten Bytes übereinstimmt, in unserem Fall 2 Bytes, wird die Wire.read() verwendet Funktion lesen wir die Bytes aus den beiden Registern der X-Achse.

Die Ausgangsdaten aus den Registern sind Zweierkomplemente, wobei X0 das niedrigstwertige Byte und X1 das höchstwertige Byte ist, also müssen wir diese Bytes in Float-Werte von -1 bis +1 umwandeln, abhängig von der Richtung der relativen X-Achse auf die Erdbeschleunigung oder die Schwerkraft. Wir werden diesen Vorgang für die beiden anderen Achsen wiederholen und am Ende diese Werte auf dem seriellen Monitor ausgeben.

#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); } Codesprache:Arduino (arduino)

Arduino-Gyroskop-Code

Um die Daten vom Gyroskop zu erhalten, haben wir einen ähnlichen Code wie der vorherige. Also müssen wir zuerst die Registeradressen und einige Variablen für die Daten definieren. Im Setup-Bereich müssen wir den Sensor mit CTRL_REG1 aufwecken und in den Normalmodus versetzen und auch die Empfindlichkeit des Sensors auswählen. Für dieses Beispiel wähle ich den Empfindlichkeitsmodus 2000 dps.

Im Schleifenabschnitt ähnlich dem Beschleunigungsmesser lesen wir die Daten für die X-, Y- und Z-Achse. Anschließend müssen die Rohdaten in Winkelwerte umgerechnet werden. Aus dem Datenblatt des Sensors können wir entnehmen, dass der Empfindlichkeitsmodus 2000 dps einer Einheit von 70 mdps/Digit entspricht. Das bedeutet, dass wir die Ausgangsrohdaten mit 0,07 multiplizieren müssen, um die Winkelgeschwindigkeit in Grad pro Sekunde zu erhalten. Wenn Sie dann die Winkelgeschwindigkeit mit der Zeit multiplizieren, erhalten wir den Winkelwert. Wir müssen also das Zeitintervall jedes Schleifenabschnitts berechnen, und wir können dies tun, indem wir die Funktion millis() oben und unten im Schleifenabschnitt verwenden, und wir speichern ihren Wert in dieser „dt“-Variablen. Für jede ausgeführte Schleife berechnen wir also den Winkel und addieren ihn zum endgültigen Winkelwert. Dasselbe machen wir mit den beiden anderen Achsen und drucken am Ende die Ergebnisse im seriellen Monitor aus.

#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;
  
} Codesprache:Arduino (arduino) 

Arduino-Magnetometer-Code

Wieder werden wir eine ähnliche Technik wie die vorherige verwenden. Zuerst müssen wir die Registeradressen definieren und im Setup-Bereich den Sensor in den kontinuierlichen Messmodus versetzen. Im Schleifenabschnitt erhalten wir die Rohdaten für jede Achse mit der gleichen Methode wie für die vorherigen Sensoren.

Dann müssen wir die Rohdaten in Magnetfeldwerte oder Gauß-Einheiten umwandeln. Aus dem Datenblatt des Sensors können wir ersehen, dass der Standard-Empfindlichkeitsmodus 0,92 mG/Digit ist. Das heißt, wir müssen die Rohdaten mit 0,00092 multiplizieren, um das Erdmagnetfeld in Gauß-Einheiten zu erhalten. Am Ende drucken wir die Werte auf dem seriellen Monitor aus.

#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);
} Codesprache:Arduino (arduino) 

Hier ist eine cool aussehende Anwendung des Sensors, ein digitaler MEMS-Kompass, der mit der Processing IDE erstellt wurde. Weitere Details und den Quellcode dieses Beispiels finden Sie unter  dem folgenden Link:


Herstellungsprozess

  1. Was ist ein Magnetometer?
  2. Was mache ich mit den Daten?!
  3. Arduino-Gyroskop-Spiel mit MPU-6050
  4. Gyroskop-Spaß mit NeoPixel-Ring
  5. CO2-Überwachung mit K30-Sensor
  6. taubblinde Kommunikation mit 1Sheeld/Arduino
  7. Münzprüfer mit Arduino steuern
  8. Arduino mit Bluetooth zur Steuerung einer LED!
  9. Kapazitiver Fingerabdrucksensor mit einem Arduino oder ESP8266
  10. Mit Nextion Display spielen