Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

MEMS Sensoren Ontdekken: Versnellingsmeters, Gyroscopen en Magnetometers voor Arduino Projecten

In deze tutorial leer je hoe MEMS versnellingsmeters, gyroscopen en magnetometers werken en hoe je ze met een Arduino-board kunt gebruiken. Ook maken we met de Processing IDE enkele praktische toepassingen met de sensoren. Bekijk de video of lees de tutorial hieronder.

Wat is MEMS?

MEMS (Micro-Electro-Mechanical Systems) zijn zeer kleine systemen of apparaten, samengesteld uit microcomponenten van 0,001 mm tot 0,1 mm. Deze componenten zijn gemaakt van silicium, polymeren, metalen en/of keramiek, en worden meestal gecombineerd met een CPU (microcontroller) om het systeem compleet te maken.

Nu leggen we kort uit hoe elk van deze MEMS-sensoren werkt.

MEMS Versnellingsmeter

Een versnellingsmeter meet versnelling door veranderingen in capaciteit te meten. De microstructuur ziet er ongeveer zo uit: een massa bevestigd aan een veer die zich in één richting kan bewegen, en vaste buitenplaten. Wanneer versnelling in die richting wordt toegepast, beweegt de massa en verandert de capaciteit tussen de platen en de massa. Deze capaciteitsverandering wordt gemeten, verwerkt en vertaald naar een specifieke versnellingswaarde.

MEMS Sensoren Ontdekken: Versnellingsmeters, Gyroscopen en Magnetometers voor Arduino Projecten

MEMS Gyroscoop

De gyroscoop meet de hoeksnelheid met behulp van het Corioliseffect. Wanneer een massa in een bepaalde richting met een bepaalde snelheid beweegt en er een externe hoeksnelheid wordt toegepast (groene pijl), ontstaat een kracht (blauw/rode pijl) die een loodrechte verplaatsing van de massa veroorzaakt. Net als bij de versnellingsmeter leidt deze verplaatsing tot een capaciteitsverandering die wordt gemeten en verwerkt tot een hoeksnelheidswaarde.

MEMS Sensoren Ontdekken: Versnellingsmeters, Gyroscopen en Magnetometers voor Arduino Projecten

De microstructuur van de gyroscoop bestaat uit een constant bewegende (oscillerende) massa. Bij een externe hoeksnelheid beweegt een flexibel deel van de massa en ontstaat de loodrechte verplaatsing.

MEMS Sensoren Ontdekken: Versnellingsmeters, Gyroscopen en Magnetometers voor Arduino Projecten

MEMS Magnetometer

Een magnetometer meet het aardmagnetisch veld met behulp van het Halleffect of het magnetoweerstandseffect. Ongeveer 90% van de sensoren op de markt gebruikt het Halleffect. Hier is hoe dat werkt:

MEMS Sensoren Ontdekken: Versnellingsmeters, Gyroscopen en Magnetometers voor Arduino Projecten

Als we een geleidende plaat hebben en er stroom doorheen laten lopen, vloeien de elektronen in een rechte lijn. Brengen we een magneetveld in de buurt, wordt de rechte stroom verstoren: elektronen buigen naar één kant, positieve ladingen naar de andere. Als we nu een meetapparaat tussen deze twee kanten plaatsen, meten we een spanning die afhangt van de sterkte en richting van het magneetveld.

MEMS Sensoren Ontdekken: Versnellingsmeters, Gyroscopen en Magnetometers voor Arduino Projecten

De overige 10% gebruikt het magnetoweerstandseffect. Deze sensoren gebruiken materialen gevoelig voor magneetvelden, meestal samengesteld uit ijzer (Fe) en nikkel (Ni). Bij blootstelling aan een magneetveld verandert hun weerstand.

Arduino en MEMS Sensoren


Nu sluiten we deze sensoren aan op de Arduino en maken we er iets van. Als voorbeeld gebruik ik het GY-80 breakout-board met de volgende sensoren: ADXL345 3-as versnellingsmeter, L3G4200D 3-as gyroscoop, MC5883L 3-as magnetometer, plus een barometer en thermometer (die we in deze tutorial niet gebruiken).

Je kunt deze componenten verkrijgen via:

  • ADXL345 3-As Versnellingsmeter
  • 2 in 1: MPU6050 6-As Gyroscoop & Versnellingsmeter
  • 3 in 1: GY-80 9-As Magnetisch Veld Versnelling Gyroscoop Amazon
  • 3 in 1: GY-86 10DOF MS5611 HMC5883L MPU6050 Module Banggood / AliExpress
MEMS Sensoren Ontdekken: Versnellingsmeters, Gyroscopen en Magnetometers voor Arduino Projecten

Dit board gebruikt het I2C communicatieprotocol, wat betekent dat we alle sensoren met slechts twee draden kunnen aansluiten. Om te communiceren met de Arduino hebben we de unieke apparaatadressen en de interne registeradressen nodig om data uit te lezen. Deze adressen vind je in de datasheets van de sensoren:

  • ADXL345 Versnellingsmeter Datasheet
  • L3G4200D Gyroscoop Datasheet
  • MC5883L Magnetometer Datasheet

Voor meer details over I2C communicatie, zie mijn I2C Communicatieprotocol Tutorial.

Broncode

Nu bekijken we de code om data van de sensoren uit te lezen. We beginnen met de versnellingsmeter, met uitleg voor elke code en commentaar in de code.

Arduino Versnellingsmeter Code

Eerst includeren we de Arduino Wire Library en definiëren we de registeradressen van de sensor. In de setup initiëren we de Wire Library en starten de seriële communicatie voor de seriële monitor. We activeren de sensor door een specifieke byte naar het Power_CTL register te sturen. Met Wire.beginTransmission() selecteren we de sensor, met Wire.write() kiezen we het interne register, en met Wire.endTransmission() sturen we de data.

In de loop lezen we de data voor elke as. We beginnen met de X-as: we selecteren de twee X-as registers, vragen de data op met Wire.requestFrom(), en lezen de bytes met Wire.read(). De output is two's complement (X0 = least significant byte, X1 = most significant byte). We converteren dit naar float waarden van -1 tot +1, afhankelijk van de richting van de X-as ten opzichte van de zwaartekracht. Hetzelfde doen we voor Y en Z as, en printen de waarden op de seriële monitor.

#include <Wire.h>
//--- Versnellingsmeter Register Adressen
#define Power_Register 0x2D
#define X_Axis_Register_DATAX0 0x32
#define X_Axis_Register_DATAX1 0x33
#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; // Apparaatadres (met 8e bit voor read mode)
int X0,X1,X_out; int Y0,Y1,Y_out; int Z1,Z0,Z_out;
float Xa,Ya,Za;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  delay(100);
  Wire.beginTransmission(ADXAddress);
  Wire.write(Power_Register);
  Wire.write(8); // Bit D3 hoog voor meetenable (0000 1000)
  Wire.endTransmission();
}

void loop() {
  // X-as
  Wire.beginTransmission(ADXAddress);
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress,2);
  if(Wire.available()<=2) {
    X0 = Wire.read();
    X1 = Wire.read();
    X1=X1<<8;
    X_out =X0+X1;
    Xa=X_out/256.0; // Waarde -1 tot +1, zwaartekracht op X-as
  }
  // Y-as
  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-as
  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;
  }
  // Print op seriële monitor
  Serial.print("Xa= "); Serial.print(Xa);
  Serial.print(" Ya= "); Serial.print(Ya);
  Serial.print(" Za= "); Serial.println(Za);
}

Arduino Gyroscoop Code

Voor de gyroscoop gebruiken we een vergelijkbare code. We definiëren registeradressen en variabelen. In de setup wakken we de sensor op en zetten in normale modus via CTRL_REG1, en selecteren we de gevoeligheid (2000 dps voor dit voorbeeld).

In de loop lezen we X, Y, Z as data. De rauwe data moet worden omgerekend naar hoekwaarden. Uit de datasheet: voor 2000 dps gevoeligheid geldt 70 mdps/digit. We vermenigvuldigen de rauwe data met 0,07 voor graden per seconde. Vermenigvuldigd met tijd (dt) geeft de hoek. We berekenen dt met millis() boven en onder in de loop. Voor elke loop berekenen we de hoek en tellen we op bij de totale hoek. Hetzelfde voor de andere assen, en printen de resultaten.

#include <Wire.h>
//--- Gyroscoop Register Adressen
#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;
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);   // Normale modus: 15d - 00001111b
  Wire.endTransmission();
  Wire.beginTransmission(Gyro);
  Wire.write(0x23); // CTRL_REG4 - Gevoeligheid
  Wire.write(48);   // 2000dps: 48d - 00110000b
  Wire.endTransmission();
}

void loop() {
  start=millis();
  // X-as
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gX0); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) gX0 = Wire.read();
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gX1); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) gX1 = Wire.read();
  // Y-as
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gY0); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) gY0 = Wire.read();
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gY1); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) gY1 = Wire.read();
  // Z-as
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gZ0); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) gZ0 = Wire.read();
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gZ1); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) gZ1 = Wire.read();

  // X-as berekening
  gX1=gX1<<8; gX_out =gX0+gX1; Xg=gX_out*0.07; // Hoeksnelheid
  angleXc = Xg*dt; angleX = angleX + angleXc;
  // Y-as
  gY1=gY1<<8; gY_out =gY0+gY1; Yg=gY_out*0.07;
  angleYc = Yg*dt; angleY = angleY + angleYc;
  // Z-as
  gZ1=gZ1<<8; gZ_out =gZ0+gZ1; Zg=gZ_out*0.07;
  angleZc = Zg*dt; angleZ = angleZ + angleZc;

  Serial.print("angleX= "); Serial.print(angleX);
  Serial.print(" angleY= "); Serial.print(angleY);
  Serial.print(" angleZ= "); Serial.println(angleZ);
  delay(10);
  finished=millis(); elapsed=finished-start; dt=elapsed/1000.0; start = elapsed = 0;
}

Arduino Magnetometer Code

Opnieuw een vergelijkbare techniek. We definiëren registeradressen en zetten in de setup de sensor in continue meetmodus. In de loop halen we rauwe data per as op.

Dan converteren we naar magneetveldwaarden (Gauss). Uit de datasheet: standaard gevoeligheid is 0,92 mG/digit. We vermenigvuldigen rauwe data met 0,00092 voor Gauss. Het aardmagnetisch veld ligt tussen 0,25 en 0,65 Gauss. Tenslotte printen we de waarden.

#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 7-bit adres van HMC5883

void setup(){
  Serial.begin(9600); Wire.begin(); delay(100);
  Wire.beginTransmission(Magnetometer);
  Wire.write(0x02); // Modus register selecteren
  Wire.write(0x00); // Continue meetmodus
  Wire.endTransmission();
}

void loop(){
  // X-as
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mX1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) mX0 = Wire.read();
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mX0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) mX1 = Wire.read();
  // Y-as
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mY1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) mY0 = Wire.read();
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mY0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) mY1 = Wire.read();
  // Z-as
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mZ1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) mZ0 = Wire.read();
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mZ0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) mZ1 = Wire.read();

  // Conversie
  mX1=mX1<<8; mX_out =mX0+mX1; Xm = mX_out*0.00092; // Gauss
  mY1=mY1<<8; mY_out =mY0+mY1; Ym = mY_out*0.00092;
  mZ1=mZ1<<8; mZ_out =mZ0+mZ1; Zm = mZ_out*0.00092;

  Serial.print("x: "); Serial.print(Xm);
  Serial.print(" y: "); Serial.print(Ym);
  Serial.print(" z: "); Serial.println(Zm);
  delay(50);
}

Hier is een leuke toepassing: een MEMS digitale kompas, gemaakt met de Processing IDE. Meer details en broncode vind je via de link:

MEMS Sensoren Ontdekken: Versnellingsmeters, Gyroscopen en Magnetometers voor Arduino Projecten

Productieproces

  1. Bouw een real-time gyroscoop-spel met Arduino Nano & MPU-6050 sensor
  2. Interactieve gyroscoop LED-display met NeoPixel-ring en Arduino
  3. K30 CO2-sensor: Real-time binnenluchtkwaliteitmonitoring met Arduino
  4. Communicatie voor doofblinden vergemakkelijken met 1Sheeld en Arduino
  5. Slimme spaarpot bouwen: Muntenacceptor besturen met Arduino Nano
  6. Een LED bedienen via Bluetooth met Arduino – Eenvoudige DIY Handleiding
  7. Een DFRobot Capacitieve Vingerafdruksensor integreren met Arduino of ESP8266
  8. Interactief Nextion HMI-weerstation met Arduino Mega en sensoren
  9. Arduino-gebaseerde 6-DoF Robotarm Gestoeerd met Wii Nunchuk
  10. Wat Is Een Magnetometer? Fundamenten, Principes en Toepassingen
  11. Data benutten in het Internet of Reliability: Strategieën voor effectief beheer