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

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

In deze handleiding leer je de MPU6050 Accelerometer en Gyroscoop sensor gebruiken met Arduino. Eerst uitleg over werking en data uitlezen, daarna twee praktische voorbeelden.

Bekijk de video of lees de handleiding.

Overzicht

Voorbeeld 1: Met Processing IDE een 3D-visualisatie van de sensororiëntatie. Voorbeeld 2: Een zelfstabiliserend platform (DIY Gimbal) – op basis van MPU6050 oriëntatie en gefuseerde accelerometer/gyroscoop data besturen we drie servo's die het platform vlak houden.

Hoe het Werkt

De MPU6050 IMU heeft een 3-as accelerometer en 3-as gyroscoop geïntegreerd op één chip.

De gyroscoop meet rotatiesnelheid (graad/seconde) langs X, Y, Z. Het gebruikt MEMS-technologie en het Corioliseffect. Uitgang in °/s; voor hoek positioneren we de hoeksnelheid (integratie).

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

De accelerometer meet versnelling (zoals ADXL345). Meet zwaartekrachtversnelling langs 3 assen; met trigonometrie bereken je de hoek. Samen (sensor fusion) geven accelerometer en gyroscoop zeer nauwkeurige oriëntatie-informatie.

De MPU6050 heet ook 6-as motion tracking device of 6 DoF (6 Degrees of Freedom) door de 6 uitgangen (3 accel + 3 gyro).

Arduino en MPU6050

Communicatie via I2C → alleen 2 draden (+ 2 voor voeding).

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Componenten: MPU6050 IMU, Arduino Board, Breadboard en Jumper Draden.

MPU6050 Arduino Code

Code voor het uitlezen van MPU6050 data. Onder de code gedetailleerde uitleg.

/* Arduino en MPU6050 Accelerometer en Gyroscoop Tutorial
 * by Dejan, https://howtomechatronics.com
 */
#include <Wire.h>
const int MPU = 0x68; // MPU6050 I2C adres
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll, pitch, yaw;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;

void setup() {
  Serial.begin(19200);
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B); // Register 6B (PWR_MGMT_1)
  Wire.write(0x00); // Reset - 0 in register 6B
  Wire.endTransmission(true);
  /*
  // Optioneel: gevoeligheid instellen (standaard +/-2g, +/-250deg/s)
  Wire.beginTransmission(MPU);
  Wire.write(0x1C); // ACCEL_CONFIG
  Wire.write(0x10); // +/- 8g
  Wire.endTransmission(true);
  Wire.beginTransmission(MPU);
  Wire.write(0x1B); // GYRO_CONFIG
  Wire.write(0x10); // 1000deg/s
  Wire.endTransmission(true);
  delay(20);
  */
  calculate_IMU_error(); // Foutwaarden berekenen
  delay(20);
}

void loop() {
  // === Accelerometer data lezen ===
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start register ACCEL_XOUT_H
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // 6 registers (2 per as)
  // Voor +/-2g: raw / 16384 (volgens datasheet)
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0;
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0;
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0;

  // Roll en Pitch berekenen uit accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY

  // === Gyroscoop data lezen ===
  previousTime = currentTime;
  currentTime = millis();
  elapsedTime = (currentTime - previousTime) / 1000.0; // seconden

  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data start register 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // 6 registers
  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // Voor 250deg/s: /131
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;

  // Foutcorrectie toepassen
  GyroX = GyroX + 0.56;   // GyroErrorX ~(-0.56)
  GyroY = GyroY - 2;      // GyroErrorY ~(2)
  GyroZ = GyroZ + 0.79;   // GyroErrorZ ~(-0.8)

  // Integreren: deg/s * s = graden
  gyroAngleX = gyroAngleX + GyroX * elapsedTime;
  gyroAngleY = gyroAngleY + GyroY * elapsedTime;
  yaw = yaw + GyroZ * elapsedTime;

  // Complementair filter: fuseer accel en gyro
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;

  // Print op Serial Monitor
  Serial.print(roll);
  Serial.print("/");
  Serial.print(pitch);
  Serial.print("/");
  Serial.println(yaw);
}

void calculate_IMU_error() {
  // Roep aan in setup voor foutwaarden. Zet IMU vlak en stil.
  // Lees accelerometer 200x
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0;
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0;
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0;
    AccErrorX += atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI;
    AccErrorY += atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI;
    c++;
  }
  AccErrorX /= 200;
  AccErrorY /= 200;
  c = 0;

  // Lees gyroscoop 200x
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    GyroX = (Wire.read() << 8 | Wire.read()) / 131.0;
    GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
    GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
    GyroErrorX += GyroX;
    GyroErrorY += GyroY;
    GyroErrorZ += GyroZ;
    c++;
  }
  GyroErrorX /= 200;
  GyroErrorY /= 200;
  GyroErrorZ /= 200;

  // Print foutwaarden
  Serial.print("AccErrorX: "); Serial.println(AccErrorX);
  Serial.print("AccErrorY: "); Serial.println(AccErrorY);
  Serial.print("GyroErrorX: "); Serial.println(GyroErrorX);
  Serial.print("GyroErrorY: "); Serial.println(GyroErrorY);
  Serial.print("GyroErrorZ: "); Serial.println(GyroErrorZ);
}

Code Beschrijving: Include Wire.h voor I2C. Variabelen definieren. In setup(): Wire init, sensor reset via power management register (0x6B). Optioneel: gevoeligheid instellen via ACCEL_CONFIG (0x1C) en GYRO_CONFIG (0x1B). Standaard +/-2g en +/-250°/s gebruikt (code uitgecommentarieerd).

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

In loop(): accelerometer uitlezen. Data per as in 2 registers (adressen uit datasheet).

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Start bij register 0x3B, requestFrom() leest 6 registers. Bytes combineren (two's complement), delen door 16384 voor +/-2g → -1g tot +1g.

AccX = (Wire.read() << 8 | Wire.read()) / 16384.0;
AccY = (Wire.read() << 8 | Wire.read()) / 16384.0;
AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0;
MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Roll en Pitch uit accelerometer data:

accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58;
accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58;

Gyroscoop data uitlezen (registers 0x43–0x48):

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

6 registers lezen, combineren, delen door 131 (voor 250°/s) → °/s.

GyroX = (Wire.read() << 8 | Wire.read()) / 131.0;
GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Foutcorrectie toepassen (waarden uit calculate_IMU_error()). Integreren: °/s × s = °. Tijd via millis().

GyroX = GyroX + 0.56;
GyroY = GyroY - 2;
GyroZ = GyroZ + 0.79;
gyroAngleX = gyroAngleX + GyroX * elapsedTime;
gyroAngleY = gyroAngleY + GyroY * elapsedTime;
yaw = yaw + GyroZ * elapsedTime;

Complementair filter: 96% gyro (nauwkeurig, geen externe krachten), 4% accel (langetermijn correctie voor gyro drift). Yaw kan niet uit accelerometer → geen filter mogelijk.

roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;

Foutwaarden bepalen: roep calculate_IMU_error() aan in setup met sensor vlak en stil. 200 metingen, gemiddelde = fout. Implementeer in formules.

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Print Roll, Pitch, Yaw op Serial Monitor voor controle.

MPU6050 Oriëntatie Tracking – 3D Visualisatie

Voor 3D-visualisatie: Arduino seriële data ontvangen in Processing IDE. Complete Processing code:

/* Arduino en MPU6050 IMU - 3D Visualisatie
 * by Dejan, https://howtomechatronics.com
 */
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;

Serial myPort;
String data="";
float roll, pitch, yaw;

void setup() {
  size(2560, 1440, P3D);
  myPort = new Serial(this, "COM7", 19200);
  myPort.bufferUntil('\n');
}

void draw() {
  translate(width/2, height/2, 0);
  background(233);
  textSize(22);
  text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265);
  rotateX(radians(-pitch));
  rotateZ(radians(roll));
  rotateY(radians(yaw));
  textSize(30);
  fill(0, 76, 153);
  box(386, 40, 200);
  textSize(25);
  fill(255, 255, 255);
  text("www.HowToMechatronics.com", -183, 10, 101);
}

void serialEvent(Serial myPort) {
  data = myPort.readStringUntil('\n');
  if (data != null) {
    data = trim(data);
    String[] items = split(data, '/');
    if (items.length > 1) {
      roll = float(items[0]);
      pitch = float(items[1]);
      yaw = float(items[2]);
    }
  }
}

Data ontvangen via serialEvent(), in Roll/Pitch/Yaw variabelen. In draw() 3D-object (box) roteren.

Resultaat: 3D-object volgt sensororiëntatie nauwkeurig en responsief.

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Nadeel: Yaw drift (geen complementair filter mogelijk). Verbetering: magnetometer voor langetermijn Yaw-correctie. MPU6050 heeft ook Digital Motion Processor (DMP) voor onboard berekeningen en Yaw-drift eliminatie.

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Met DMP: zeer nauwkeurig, geen Yaw-drift. Onboard processor berekent quaternions (voor 3D-oriëntatie/rotaties, geen Gimbal-lock).

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

DMP-data uitlezen is complexer: extra interrupt-pin naar Arduino nodig.

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Code complexer → gebruik i2cdevlib bibliotheek van Jeff Rowberg (GitHub). Voorbeeld MPU6050_DMP6 uit bibliotheek (goed gedocumenteerd). Output selecteren: quaternions, Euler-hoeken, yaw/pitch/roll, versnellingen, of quaternions voor 3D-visualisatie. Bibliotheek bevat ook Processing sketch. Aangepast voor box-vorm:

/* Arduino en MPU6050 IMU - 3D Visualisatie (DMP)
 * by Dejan, https://howtomechatronics.com
 */
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;

Serial myPort;
String data="";
float roll, pitch, yaw;

void setup() {
  size(2560, 1440, P3D);
  myPort = new Serial(this, "COM7", 19200);
  myPort.bufferUntil('\n');
}

void draw() {
  translate(width/2, height/2, 0);
  background(233);
  textSize(22);
  text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265);
  rotateX(radians(-pitch));
  rotateZ(radians(roll));
  rotateY(radians(yaw));
  textSize(30);
  fill(0, 76, 153);
  box(386, 40, 200);
  textSize(25);
  fill(255, 255, 255);
  text("www.HowToMechatronics.com", -183, 10, 101);
}

void serialEvent(Serial myPort) {
  data = myPort.readStringUntil('\n');
  if (data != null) {
    data = trim(data);
    String[] items = split(data, '/');
    if (items.length > 1) {
      roll = float(items[0]);
      pitch = float(items[1]);
      yaw = float(items[2]);
    }
  }
}

Via serialEvent() quaternions ontvangen, in draw() 3D-object roteren. Quaternions zijn superieur voor 3D-rotaties.

Het tweede voorbeeld (DIY Arduino Gimbal / zelfstabiliserend platform) staat in een apart artikel.

MPU6050 Accelerometer & Gyroscoop Handleiding voor Arduino

Vragen? Reacties hieronder. Bekijk mijn Arduino Projecten Collectie.

Productieproces

  1. Maak een Veilige Arduino RFID Slot – Stapsgewijze Handleiding
  2. Bouw Boeiende LCD Animaties & Games met Arduino UNO
  3. Arduino & MPU6050: Precieze Servomotor Besturing met SG90 & MG996R
  4. Python 3 naar Arduino UNO: Eenvoudige Commando Besturing en LED Demo
  5. Bouw een compacte FM-radio met Arduino Nano en RDA5807M
  6. Kantelhoeken berekenen uit MPU6050 versnelling met Arduino Nano en Visuino
  7. Arduino Nano Vingerafdruksensor Project – Stapsgewijze Tutorial
  8. Bouw een Mini Piano met Arduino UNO – Stap-voor-Stap Handleiding
  9. Bouw een Raspberry Pi 3 & Arduino Laptop: Stap-voor-Stap Handleiding
  10. Gebarenherkenning met ESP32 en Arduino 101 Accelerometer – Eenvoudige DIY Tutorial
  11. Arduino Beginner Tutorial 01: Start met Je Eerste Project