工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ArduinoとMPU6050加速度計とジャイロスコープのチュートリアル

このチュートリアルでは、ArduinoでMPU6050加速度計とジャイロスコープセンサーを使用する方法を学習します。最初に、MPU6050がどのように機能し、そこからデータを読み取る方法を説明し、次に2つの実用的な例を示します。

次のビデオを見るか、以下のチュートリアルを読むことができます。

概要

最初の例では、Processing開発環境を使用して、センサーの向きを3Dで視覚化し、2番目の例では、単純な自己安定化プラットフォームまたはDIYジンバルを作成します。 MPU6050の向きと、その融合した加速度計とジャイロスコープのデータに基づいて、プラットフォームを水平に保つ3つのサーボを制御します。

仕組み

MPU6050 IMUには、3軸加速度計と3軸ジャイロスコープの両方が1つのチップに統合されています。

ジャイロスコープは、X、Y、Z軸に沿って、回転速度または角位置の経時変化率を測定します。測定にはMEMSテクノロジーとコリオリ効果を使用していますが、詳細については、私の特定のMEMSセンサーの仕組みのチュートリアルを確認してください。ジャイロスコープの出力は1秒あたりの度数であるため、角度位置を取得するには、角速度を積分する必要があります。

一方、MPU6050加速度計は、ADXL345加速度センサーの前のビデオで説明したのと同じ方法で加速度を測定します。簡単に言うと、3つの軸に沿った重力加速度を測定でき、三角法の計算を使用して、センサーが配置されている角度を計算できます。したがって、加速度計とジャイロスコープのデータを融合または組み合わせると、センサーの向きに関する非常に正確な情報を取得できます。

MPU6050 IMUは、6つの出力、または3つの加速度計出力と3つのジャイロスコープ出力があるため、6軸モーショントラッキングデバイスまたは6 DoF(6自由度)デバイスとも呼ばれます。

ArduinoとMPU6050

Arduinoを使用してMPU6050センサーからデータを接続して読み取る方法を見てみましょう。 Arduinoとの通信にはI2Cプロトコルを使用しているため、Arduinoを接続するために必要なのは2本のワイヤーと、電源を供給するための2本のワイヤーだけです。

このArduinoチュートリアルに必要なコンポーネントは、以下のリンクから入手できます。

  • MPU6050IMU…………………………..…。 アマゾン /バンググッド /AliExpress
  • Arduinoボード…………………………。…..
  • ブレッドボードとジャンパー線…………

MPU6050Arduinoコード

MPU6050センサーからデータを読み取るためのArduinoコードは次のとおりです。コードの下に、その詳細な説明があります。

/*
   Arduino and MPU6050 Accelerometer and Gyroscope Sensor Tutorial
   by Dejan, https://howtomechatronics.com
*/
#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);
}Code language: Arduino (arduino)

コードの説明: したがって、最初に、I2C通信に使用されるWire.hライブラリを含め、データの保存に必要ないくつかの変数を定義する必要があります。

セットアップセクションでは、ワイヤライブラリを初期化し、電力管理レジスタを介してセンサーをリセットする必要があります。そのためには、レジスタアドレスを確認できるセンサーのデータシートを確認する必要があります。

また、必要に応じて、構成レジスタを使用して、加速度計とジャイロスコープのフルスケール範囲を選択できます。この例では、加速度計にデフォルトの±2gの範囲を使用し、ジャイロスコープに250度/秒の範囲を使用するため、コードのこの部分はコメントのままにしておきます。

// 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);
  */Code language: Arduino (arduino)

ループセクションでは、加速度計のデータを読み取ることから始めます。各軸のデータは2バイトまたはレジスタに格納されており、センサーのデータシートからこれらのレジスタのアドレスを確認できます。

それらすべてを読み取るために、最初のレジスタから開始し、requiestFrom()関数を使用して、X、Y、およびZ軸の6つのレジスタすべてを読み取るように要求します。次に、各レジスタからデータを読み取ります。出力は2の補数であるため、適切に組み合わせて正しい値を取得します。

// === 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 valueCode language: Arduino (arduino)

角度の計算に適した-1gから+1gの出力値を取得するために、出力を以前に選択した感度で除算します。

最後に、これら2つの式を使用して、加速度計のデータからロール角とピッチ角を計算します。

// 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)Code language: Arduino (arduino)

次に、同じ方法を使用して、ジャイロスコープのデータを取得します。

6つのジャイロスコープレジスタを読み取り、それらのデータを適切に結合し、以前に選択した感度で除算して、1秒あたりの度数で出力を取得します。

// === 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;Code language: Arduino (arduino)

ここで、いくつかの小さな計算されたエラー値を使用して出力値を修正していることに気付くことができます。これについては、すぐに取得する方法を説明します。したがって、出力は1秒あたりの度数であるため、度を取得するには、それらに時間を掛ける必要があります。時間値は、millis()関数を使用して各読み取り反復の前にキャプチャされます。

// 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;Code language: Arduino (arduino)

最後に、補完的なフィルターを使用して、加速度計とジャイロスコープのデータを融合します。ここでは、ジャイロスコープのデータの96%を取得しています。これは、非常に正確で、外力の影響を受けないためです。ジャイロスコープの欠点は、ドリフトしたり、時間が経つにつれて出力にエラーが発生したりすることです。したがって、長期的には、加速度計からのデータ(この場合は4%)を使用して、ジャイロスコープのドリフトエラーを排除するのに十分です。

// Complementary filter - combine acceleromter and gyro angle values
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;Code language: Arduino (arduino)

ただし、加速度計のデータからヨーを計算できないため、補完的なフィルターを実装することはできません。

結果を確認する前に、エラー訂正値を取得する方法について簡単に説明します。これらのエラーを計算するために、センサーがフラットな静止位置にあるときに、calculate_IMU_error()カスタム関数を呼び出すことができます。ここでは、すべての出力に対して200の読み取りを行い、それらを合計して200で除算します。センサーを平らな静止位置に保持しているため、期待される出力値は0になります。したがって、この計算により、センサーの平均誤差を取得できます。作る。

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);
}Code language: Arduino (arduino)

シリアルモニターに値を印刷するだけで、値がわかったら、ロールとピッチの両方の計算、および3つのジャイロスコープ出力に対して、前に示したコードに値を実装できます。

最後に、Serial.print関数を使用して、ロール、ピッチ、ヨーの値をシリアルモニターに印刷し、センサーが正しく機能するかどうかを確認できます。

MPU6050方向追跡–3D視覚化

次に、3D視覚化の例を作成するには、ArduinoがProcessing開発環境のシリアルポートを介して送信しているこのデータを受け入れる必要があります。完全な処理コードは次のとおりです。

/*
    Arduino and MPU6050 IMU - 3D Visualization Example 
     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); // 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]);
    }
  }
}Code language: Arduino (arduino)

ここでは、Arduinoからの受信データを読み取り、それを適切なRoll、Pitch、およびYaw変数に入れます。メインの描画ループでは、これらの値を使用して3Dオブジェクトを回転させます。この場合は、特定の色とテキストが表示された単純なボックスです。

スケッチを実行すると、MPU6050センサーが方向を追跡するのにどれほど優れているかがわかります。 3Dオブジェクトは、センサーの向きを非常に正確に追跡し、応答性も非常に高くなっています。

先に述べたように、唯一の欠点は、ヨーが補完フィルターを使用できないため、時間の経過とともにドリフトすることです。これを改善するには、追加のセンサーを使用する必要があります。これは通常、ジャイロスコープのヨードリフトの長期補正として使用できる磁力計です。ただし、MPU6050には実際には、データのオンボード計算に使用されるデジタルモーションプロセッサと呼ばれる機能があり、ヨードリフトを排除することができます。

これは、デジタルモーションプロセッサを使用した同じ3Dの例です。ヨードリフトがなくても、方向追跡がどれほど正確であるかがわかります。オンボードプロセッサは、オブジェクトの方向と回転を3次元で表すために使用されるクォータニオンを計算して出力することもできます。この例では、実際には、オイラー角を使用するときに発生するジンバルロックの影響を受けない方向を表すためにクォータニオンを使用しています。

それでも、センサーからこのデータを取得することは、前に説明したものよりも少し複雑です。まず、Arduinoデジタルピンに接続して追加のワイヤを接続する必要があります。これは、MPU6050からこのデータタイプを読み取るために使用される割り込みピンです。

コードも少し複雑なので、JeffRowbergによるi2cdevlibライブラリを使用します。このライブラリはGitHubからダウンロードでき、ウェブサイトの記事にへのリンクを含めます。

ライブラリをインストールしたら、ライブラリからMPU6050_DMP6の例を開くことができます。この例は、各行のコメントでよく説明されています。

ここでは、必要な出力の種類、クォータニオン、オイラー角、ヨー、ピッチアンドロール、加速度値、または3Dビジュアライゼーションのクォータニオンを選択できます。このライブラリには、3D視覚化の例の処理スケッチも含まれています。前の例のようにボックスの形状を取得するように変更しました。選択した「OUTPUT_TEAPOT」出力に対して、MPU6050_DPM6の例で機能する3D視覚化処理コードを次に示します。

/*
    Arduino and MPU6050 IMU - 3D Visualization Example 
     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); // 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]);
    }
  }
}Code language: Arduino (arduino)

したがって、ここではserialEvent()関数を使用して、Arduinoからのクォータニオンを受け取り、メインの描画ループでそれらを使用して3Dオブジェクトを回転させます。スケッチを実行すると、オブジェクトを3次元で回転させるのにクォータニオンがどれほど優れているかがわかります。

このチュートリアルを過負荷にしないために、2番目の例であるDIYArduinoジンバルまたは自己安定化プラットフォームを別の記事に配置しました。

以下のコメントセクションで、このチュートリアルに関連する質問をしてください。また、Arduinoプロジェクトのコレクションを確認することを忘れないでください。


製造プロセス

  1. ArduinoRFIDロックチュートリアル
  2. LCDアニメーションとゲーム
  3. ArduinoとMPU6050によるサーボモーターの制御
  4. Python3とArduinoコミュニケーション
  5. ArduinoとRDA8057Mを使用したFMラジオ
  6. MPU6050I2Cセンサーから加速度を角度に変換
  7. Arduino指紋センサーチュートリアル
  8. Arduinoチュートリアル:ミニピアノ
  9. RaspberryPiとArduinoラップトップ
  10. 加速度計とESPを使用したジェスチャ認識
  11. Arduinoチュートリアル01:はじめに