Arduino'da MPU6050 Kullanarak İvmeölçer ve Jiroskop Yapımı

Pikachu

Administrator
Yönetici
20 Şub 2019
1,287
47
48
Ankara
Arduino'da MPU6050 Kullanarak İvmeölçer ve Jiroskop Yapımı

Bu derste MPU6050 İvmeölçer ve Jiroskop sensörünün Arduino ile nasıl kullanılacağını öğreneceğiz. İlk önce MPU6050'nin nasıl çalıştığını ve ondan verileri nasıl okuyacağımı açıklayacağız ve sonra iki pratik örnek yapacağız.

- Genel Bakış

İlk olarak, İşleme geliştirme ortamını kullanarak sensör oryantasyonunun 3 boyutlu bir görselleştirmesini yapacağız ve ikinci örnekte basit bir kendinden stabilize edici platform veya bir DIY Gimbal yapacağız. MPU6050 yönelimine ve kaynaşmış ivmeölçer ve jiroskop verilerine dayanarak, platform seviyesini koruyan üç servoyu kontrol edeceğiz.

- Nasıl Çalışacak?

MPU6050 IMU'da hem 3 Eksenli ivmeölçer hem de tek bir çip üzerine entegre edilmiş 3 Eksenli jiroskop bulunmaktadır.

Jiroskop, X, Y ve Z ekseni boyunca, zaman içindeki açısal pozisyonun dönme hızını veya değişim hızını ölçer. Ölçüm için MEMS teknolojisini ve Coriolis Efektini kullanır, ancak daha ayrıntılı bilgi için, özel MEMS Sensörleri Nasıl Çalışır eğitimini kontrol edebilirsiniz. Jiroskopun çıktıları saniyede derece cinsindendir, bu nedenle açısal konumu elde etmek için sadece açısal hızı birleştirmemiz gerekmektedir.

154

Öte yandan, MPU6050 ivmeölçer, ADXL345 ivmeölçer sensörü için önceki videoda açıklandığı şekilde ivmeyi ölçer. Kısaca, 3 eksen boyunca yerçekimi ivmesini ölçebilir ve bazı trigonometri matematiğini kullanarak sensörün yerleştirildiği açıyı hesaplayabiliriz. Bu yüzden, eğer ivmeölçer ve jiroskop verilerini birleştirir veya birleştirirsek, sensör yönelimi hakkında çok doğru bilgiler alabiliriz.

MPU6050 IMU, 6 çıkışı veya 3 ivmeölçer çıkışı ve 3 jiroskop çıkışı nedeniyle altı eksenli hareket izleme cihazı veya 6 DoF (altı Serbestlik Derecesi) cihazı olarak da adlandırılır.

- Arduino ve MPU6050

Arduino'yu kullanarak MPU6050 sensöründen verileri nasıl bağlayıp okuyabildiğimize bir göz atalım. Arduino ile iletişim için I2C protokolünü kullanıyoruz, bu yüzden bağlamak için sadece iki kabloya ve ayrıca güç sağlamak için iki kabloya ihtiyacımız var.

155

Bu Arduino Eğitimi için gerekli bileşenleri aşağıdaki linklerden satın alabilirsiniz:

direnc.net
robotistan.com
yada diğer n11, gittigidiyor tarafından satılan e-ticaret sitelerinden.

- MPU6050 Arduino Kodu

MPU6050 sensöründen verileri okumak için Arduino kodu. Kodun altında, bunun ayrıntılı bir açıklamasını aşağıda bulabilirsiniz.

Kod:
#include <Wire.h>
const int MPU = 0x68; // MPU6050 I2C address
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();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        //end the transmission
  /*
  // Configure Accelerometer Sensitivity - Full Scale Range (default +/- 2g)
  Wire.beginTransmission(MPU);
  Wire.write(0x1C);                  //Talk to the ACCEL_CONFIG register (1C hex)
  Wire.write(0x10);                  //Set the register bits as 00010000 (+/- 8g full scale range)
  Wire.endTransmission(true);
  // Configure Gyro Sensitivity - Full Scale Range (default +/- 250deg/s)
  Wire.beginTransmission(MPU);
  Wire.write(0x1B);                   // Talk to the GYRO_CONFIG register (1B hex)
  Wire.write(0x10);                   // Set the register bits as 00010000 (1000deg/s full scale)
  Wire.endTransmission(true);
  delay(20);
  */
  // Call this function if you need to get the IMU error values for your module
  calculate_IMU_error();
  delay(20);
}
void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
  // Calculating Roll and Pitch from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more details
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58)
  // === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 4 registers total, each axis value is stored in 2 registers
  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
  // Correct the outputs with the calculated error values
  GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56)
  GyroY = GyroY - 2; // GyroErrorY ~(2)
  GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8)
  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg
  gyroAngleY = gyroAngleY + GyroY * elapsedTime;
  yaw =  yaw + GyroZ * elapsedTime;
  // Complementary filter - combine acceleromter and gyro angle values
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;

  // Print the values on the serial monitor
  Serial.print(roll);
  Serial.print("/");
  Serial.print(pitch);
  Serial.print("/");
  Serial.println(yaw);
}
void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gyro data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 200 times
  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 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
    c++;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 200;
  AccErrorY = AccErrorY / 200;
  c = 0;
  // Read gyro values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();
    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 131.0);
    GyroErrorY = GyroErrorY + (GyroY / 131.0);
    GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);
    c++;
  }
  //Divide the sum by 200 to get the error value
  GyroErrorX = GyroErrorX / 200;
  GyroErrorY = GyroErrorY / 200;
  GyroErrorZ = GyroErrorZ / 200;
  // Print the error values on the Serial Monitor
  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);
}
Kod İçin Açıklama: İlk önce I2C iletişimi için kullanılan Wire.h kütüphanesini eklememiz ve verileri depolamak için gereken bazı değişkenleri tanımlamamız gerekir.

Kurulum bölümünde, tel kütüphanesini başlatmalı ve sensörü güç yönetimi kaydı aracılığıyla sıfırlamalıyız. Bunu yapmak için, kayıt adresini görebileceğimiz yerdeki sensörün veri sayfasına bakmamız gerekmektedir.

156

Ayrıca, istersek, yapılandırma kayıtlarını kullanarak ivmeölçer ve jiroskop için Tam Ölçekli Aralığı seçebiliriz. Bu örnekte, ivmeölçer için varsayılan + - 2g aralığını ve jiroskop için 250 derece / s aralığını kullanacağız, bu yüzden kodun bu bölümünü yorumlanmış olarak bırakıyoruz.

Kod:
// Configure Accelerometer Sensitivity - Full Scale Range (default +/- 2g)
  Wire.beginTransmission(MPU);
  Wire.write(0x1C);                  //Talk to the ACCEL_CONFIG register (1C hex)
  Wire.write(0x10);                  //Set the register bits as 00010000 (+/- 8g full scale range)
  Wire.endTransmission(true);
  // Configure Gyro Sensitivity - Full Scale Range (default +/- 250deg/s)
  Wire.beginTransmission(MPU);
  Wire.write(0x1B);                   // Talk to the GYRO_CONFIG register (1B hex)
  Wire.write(0x10);                   // Set the register bits as 00010000 (1000deg/s full scale)
  Wire.endTransmission(true);
  */
Döngü bölümünde ivmeölçer verilerini okuyarak başlarız. Her eksene ait veriler iki bayt veya yazmaçta saklanır ve bu kayıtların adreslerini sensörün veri sayfasından görebiliriz.

157

Hepsini okumak için ilk register ile başlıyoruz ve requiestFrom () fonksiyonunu kullanarak X, Y ve Z eksenleri için 6 registerın tümünü okumak istiyoruz. Daha sonra her bir kayıt cihazından gelen verileri okuduk ve çıktılar iki tamamlayıcı olduğundan, doğru değerleri elde etmek için bunları uygun şekilde birleştiriyoruz.

Kod:
// === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
Son olarak, bu iki formülü kullanarak, ivmeölçer verilerinden dönüş ve dönüş açılarını hesaplıyoruz.

Kod:
// Calculating Roll and Pitch from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more details
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58)
Sonra, aynı yöntemi kullanarak jiroskop verilerini alıyoruz.

158

Altı jiroskop kaydını okur, verilerini uygun şekilde birleştirir ve çıktıyı saniyede derece cinsinden elde etmek için önceden seçilen hassasiyete böleriz.

Kod:
// === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 4 registers total, each axis value is stored in 2 registers
  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
159

Burada çıktı değerlerini bazı küçük hesaplanmış hata değerleri ile düzelttiğimi fark edersiniz, bu da bir dakika içinde nasıl elde edeceğimizi açıklayacağım. Bu yüzden çıktılar saniyede derece cinsinden olduğu için, şimdi sadece derece almak için onları zamanla çarpmamız gerekiyor. Zaman değeri, millis () işlevini kullanarak her okuma yinelemesinden önce yakalanır.

Kod:
// Correct the outputs with the calculated error values
  GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56)
  GyroY = GyroY - 2; // GyroErrorY ~(2)
  GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8)
  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg
  gyroAngleY = gyroAngleY + GyroY * elapsedTime;
  yaw =  yaw + GyroZ * elapsedTime;
Son olarak, tamamlayıcı bir filtre kullanarak ivmeölçer ve jiroskop verilerini birleştiriyoruz. Burada jiroskop verilerinin% 96'sını alıyoruz çünkü çok doğru ve dış kuvvetlerden muzdarip değil. Jiroskopun aşağı tarafı, sürüklenmesidir ya da zaman geçtikçe çıkışta hata meydana getirir. Bu nedenle, uzun vadede, jiroskop sapma hatasını ortadan kaldıracak kadar, bu durumda% 4, ivmeölçer verilerini kullanırız.

Kod:
// Complementary filter - combine acceleromter and gyro angle values
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;
Ancak, Yaw'ı ivmeölçer verilerinden hesaplayamadığımız için tamamlayıcı filtreyi bunun üzerine uygulayamayız.

Sonuçlara bakmadan önce, hata düzeltme değerlerinin nasıl alınacağını hızlıca açıklamama izin verin. Bu hataları hesaplamak için, sensör düz pozisyondayken hesapla_IMU_error () özel fonksiyonunu çağırabiliriz. Burada tüm çıktılar için 200 okuma yapıyoruz, toplamları topladık ve 200'e böldük. Sensörü sabit pozisyonda tuttuğumuzda beklenen çıkış değerleri 0 olmalıdır. Bu hesaplama ile sensörün ortalama hatasını alabiliriz. yapar.

Kod:
void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gyro data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 200 times
  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 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
    c++;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 200;
  AccErrorY = AccErrorY / 200;
  c = 0;
  // Read gyro values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();
    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 131.0);
    GyroErrorY = GyroErrorY + (GyroY / 131.0);
    GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);
    c++;
  }
  //Divide the sum by 200 to get the error value
  GyroErrorX = GyroErrorX / 200;
  GyroErrorY = GyroErrorY / 200;
  GyroErrorZ = GyroErrorZ / 200;
  // Print the error values on the Serial Monitor
  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);
}
Değerleri seri monitöre basarız ve bunları bir kez öğrendiğimizde, bunları hem rulo hem de perde hesaplaması için ve aynı zamanda 3 jiroskop çıkışı için daha önce gösterildiği şekilde uygulayabiliriz.

160

Son olarak, Serial.print işlevini kullanarak, seri monitörde Roll, Pitch ve Yaw değerlerini yazdırabilir ve sensörün düzgün çalışıp çalışmadığını görebiliriz.

- MPU6050 Oryantasyon İzleme - 3D Görselleştirme

Daha sonra, 3D görselleştirme örneğini yapmak için Arduino'nun İşleme geliştirme ortamında seri port üzerinden gönderdiği bu verileri kabul etmemiz yeterli. İşlem kodunun tamamı burada:

Kod:
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); // starts the serial communication
  myPort.bufferUntil('\n');
}
void draw() {
  translate(width/2, height/2, 0);
  background(233);
  textSize(22);
  text("Roll: " + int(roll) + "     Pitch: " + int(pitch), -100, 265);
  // Rotate the object
  rotateX(radians(-pitch));
  rotateZ(radians(roll));
  rotateY(radians(yaw));

  // 3D 0bject
  textSize(30);
  fill(0, 76, 153);
  box (386, 40, 200); // Draw box
  textSize(25);
  fill(255, 255, 255);
  text("www.HowToMechatronics.com", -183, 10, 101);
  //delay(10);
  //println("ypr:\t" + angleX + "\t" + angleY); // Print the values to check whether we are getting proper values
}
// Read data from the Serial Port
void serialEvent (Serial myPort) {
  // reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
  data = myPort.readStringUntil('\n');
  // if you got any bytes other than the linefeed:
  if (data != null) {
    data = trim(data);
    // split the string at "/"
    String items[] = split(data, '/');
    if (items.length > 1) {
      //--- Roll,Pitch in degrees
      roll = float(items[0]);
      pitch = float(items[1]);
      yaw = float(items[2]);
    }
  }
}
Burada Arduino'dan gelen verileri okuyup uygun Roll, Pitch ve Yaw değişkenlerine koyduk. Ana çizim döngüsünde, bu değerleri 3B nesneyi döndürmek için kullanırız, bu durumda üzerinde belirli bir renk ve metin içeren basit bir kutu vardır.

Krokiyi çalıştırırsak, MPU6050 sensörünün izleme oryantasyonu için ne kadar iyi olduğunu görebiliriz. 3B nesne sensörün yönünü oldukça doğru izler ve aynı zamanda çok duyarlıdır.

161

Bahsettiğim gibi, sadece aşağı taraf, Yaw'ın zamanla kayması, çünkü bunun için tamamlayıcı filtreyi kullanamayız. Bunu geliştirmek için ek bir sensör kullanmamız gerekir. Bu genellikle Yaw drift jiroskopu için uzun vadeli bir düzeltme olarak kullanılabilecek bir manyetometredir. Bununla birlikte, MPU6050 aslında verilerin yerleşik hesaplamaları için kullanılan ve Yaw sürüklenmesini ortadan kaldırabilen Dijital Hareket İşlemcisi adı verilen bir özelliğe sahiptir.

162

İşte kullanılan Dijital Hareket İşlemcisi ile aynı 3B örneği. Oryantasyon izlemenin ne kadar hassas olduğunu, Yaw sapması olmadan görebiliriz. Bütünleşik işlemci ayrıca, nesnelerin yönlerini ve rotasyonlarını üç boyutlu olarak göstermek için kullanılan Kuaterniyonları hesaplayabilir ve çıkarabilir. Bu örnekte, aslında Euler açıları kullanılırken ortaya çıkan Gimbal kilidinden muzdarip olmayan yönelimi temsil etmek için kuaterniyonlar kullanıyoruz.

163

Bununla birlikte, bu verileri sensörden almak, daha önce açıkladığımızdan biraz daha karmaşıktır. Her şeyden önce, bir Arduino dijital pinine bağlanmalı ve ek kablo kullanmamız gerekir. Bu, bu veri türünü MPU6050'den okumak için kullanılan bir kesme pimidir.

164

Bu kod biraz daha karmaşık, bu yüzden i2cdevlib kütüphanesini Jeff Rowberg tarafından kullanacağız. Bu kütüphane GitHub'dan indirilebilir ve web sitesindeki yazıya bir link ekleyeceğim.

Kütüphaneyi kurduğumuzda, kütüphaneden MPU6050_DMP6 örneğini açabiliriz. Bu örnek, her satır için yorumlarla iyi açıklanmıştır.

165

Burada ne tür bir çıktı istediğimizi seçebiliriz, kuaterniyonlar, Euler açıları, yalpalama, eğim ve yuvarlama, ivme değerleri veya 3D görselleştirme için kuaterniyonlar. Bu kütüphane ayrıca 3D görselleştirme örneği için bir İşleme taslağını da içerir. Sadece önceki örnekte olduğu gibi kutu şeklini almak için değiştirdim. İşte seçilen “OUTPUT_TEAPOT” çıkışı için MPU6050_DPM6 örneğiyle çalışan 3D görselleştirme İşleme kodu:

Kod:
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); // starts the serial communication
  myPort.bufferUntil('\n');
}
void draw() {
  translate(width/2, height/2, 0);
  background(233);
  textSize(22);
  text("Roll: " + int(roll) + "     Pitch: " + int(pitch), -100, 265);
  // Rotate the object
  rotateX(radians(-pitch));
  rotateZ(radians(roll));
  rotateY(radians(yaw));

  // 3D 0bject
  textSize(30);
  fill(0, 76, 153);
  box (386, 40, 200); // Draw box
  textSize(25);
  fill(255, 255, 255);
  text("www.HowToMechatronics.com", -183, 10, 101);
  //delay(10);
  //println("ypr:\t" + angleX + "\t" + angleY); // Print the values to check whether we are getting proper values
}
// Read data from the Serial Port
void serialEvent (Serial myPort) {
  // reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
  data = myPort.readStringUntil('\n');
  // if you got any bytes other than the linefeed:
  if (data != null) {
    data = trim(data);
    // split the string at "/"
    String items[] = split(data, '/');
    if (items.length > 1) {
      //--- Roll,Pitch in degrees
      roll = float(items[0]);
      pitch = float(items[1]);
      yaw = float(items[2]);
    }
  }
}
Burada serialEvent () işlevini kullanarak Arduino'dan gelen kuaterniyonları alırız ve ana beraberlik döngüsünde onları 3B nesneyi döndürmek için kullanırız. Krokiyi çalıştırırsak, kuaterniyonların nesneleri üç boyutlu döndürmek için ne kadar iyi olduğunu görebiliriz.