【Arduino】六軸センサMPU-6050を使ってみる
学生時代に所属していた研究室ではドローンに関する研究をしていたのだが,研究自体はもっぱらドローンに付随する周辺機器の開発であったためにドローンそのものを作ったことがなかった.(プラットフォームとしてのドローンなら何度かDJIのキットを組んで運用したことがある.)大学を卒業して一年経とうとしているが,このことがどうしても心残りなのでドローンを自作してみる.
どの程度の自作かといえば,ドローンのフレームはさすがに製作環境がないのでアマゾンに売ってるものを使うが,飛行制御に使うフライトコントローラやプログラム,電装系は基本的に自作する.
フライトコントローラに使うマイコンは“Arduino uno”を使う.
このブログはマイコンの勉強も兼ねるので,プログラムの内容はできる限り詳しく書いていきたい.
・6軸センサ動作テスト
というわけで,一番最初の準備段階としてドローンの制御に必要不可欠な六軸センサの動作テストを行う.六軸センサにはアマゾンで2個600円ほどと格安だった“MPU-6050”を使う.I2Cで通信するのでArduinoにつなげる線が少なくて済む.
写真のようにMPU-6050(下の方で光ってる小さい基盤)とArduino(上の基盤)を固定する台を製作した.MPU-6050からArduinoへはそれぞれVCC→3.3V,GND→GND,SCL→SCL,SDA→SDAと繋げるだけでよい.
https://garchiving.com/how-to-use-mpu6050-in-arduino/
↑この辺を参考にプログラムを組む.正直,setup()の中身は意味不明なので追々調べるとする.
(追記:MPU-6050のI2C通信設定について)
・スケッチ
以下,今回用いたスケッチ.
#include <Wire.h> int16_t axRaw, ayRaw, azRaw, gxRaw, gyRaw, gzRaw, temperature; //a:acceleration g:gyro(角加速度) float acc_x,acc_y,acc_z; float acc_angle_x,acc_angle_y,acc_angle_z; float gyr_x,gyr_y,gyr_z; void setup() { Serial.begin(9600); Wire.begin(); TWBR = 12; Wire.beginTransmission(0x68); Wire.write(0x6B); Wire.write(0x00); Wire.endTransmission(); //Gyro初期設定 Wire.beginTransmission(0x68); Wire.write(0x1C); Wire.write(0x10); Wire.endTransmission(); //加速度センサー初期設定 Wire.beginTransmission(0x68); Wire.write(0x1B); Wire.write(0x08); Wire.endTransmission(); //LPF設定 Wire.beginTransmission(0x68); Wire.write(0x1A); Wire.write(0x05); Wire.endTransmission(); } void loop() { Wire.beginTransmission(0x68); Wire.write(0x3B); Wire.endTransmission(); Wire.requestFrom(0x68, 14); while (Wire.available() < 14); axRaw = Wire.read() << 8 | Wire.read(); ayRaw = Wire.read() << 8 | Wire.read(); azRaw = Wire.read() << 8 | Wire.read(); temperature = Wire.read() << 8 | Wire.read(); gxRaw = Wire.read() << 8 | Wire.read(); gyRaw = Wire.read() << 8 | Wire.read(); gzRaw = Wire.read() << 8 | Wire.read(); // 取得した加速度値を分解能で割って加速度(G)に変換する acc_x = axRaw / 4096.0; //スケールファクタの設定(分解能?) acc_y = ayRaw / 4096.0; //FS_SEL_2 4096LSB/g (Least Significant Bit:量子化単位) acc_z = azRaw / 4096.0; // 加速度からセンサ対地角を求める acc_angle_x = atan2(acc_y, acc_z) * 360 / (2.0*PI); acc_angle_y = atan2(acc_x, acc_z) * 360 / (2.0*PI); acc_angle_z = atan2(acc_x, acc_y) * 360 / (2.0*PI); // 取得した角速度値を分解能で割って角速度(deg/s)に変換する gyr_x = gxRaw / 65.5; //スケールファクタの設定(分解能?) gyr_y = gyRaw / 65.5; //FS_SEL_1 65.5LSB/(deg/s) gyr_z = gzRaw / 65.5; Serial.print("acc_x:"); Serial.print(acc_x); Serial.print(","); Serial.print("acc_y:"); Serial.print(acc_y); Serial.print(","); Serial.print("acc_z:"); Serial.print(acc_z); Serial.print(","); Serial.print("gyr_x:"); Serial.print(gyr_x); Serial.print(","); Serial.print("gyr_y:"); Serial.print(gyr_y); Serial.print(","); Serial.print("gyr_z:"); Serial.print(gyr_z); Serial.print(","); //Serial.print("ang_x:"); Serial.print(acc_angle_x); Serial.print(","); Serial.print("\n");
}
・出力結果
加速度と角速度は簡単に出せたが,センサは机の上に置いているだけにかかわらず加速度が検出されてしまっている.いろいろ調べるとフィルタを使って補正を入れたり,角速度から加速度を算出した時のドリフトをなんとかしないといけなかったり一筋縄ではいかないみたい.
データの表示はスケッチモニタ上にしか表示してないので,センサの状態を把握するにはどこかにデータを保存できるようにしないといけない.今後のデバックを容易にするためにも.
今後,理解と改善が進み次第記事を追記していく.