MPU6050 ので速度と距離を測定するため、MPU6050 の Digital Motion Processor (DMP) がどの程度の精度が出るのか性能を測定をして見ることにしました。





DMPで取れる座標には REAL ACCEL とWORLD ACCEL の2種類あります。REAL ACCEL と WORLD ACCES の違いはこちらを参照してください。どちらがいいのか調べてみたら、下記のスレッドのやりとりで、WORLD ACCEL は精度が低いからやめろとありました。

MPU-6050 Accelerometer Calibration and DMP
http://www.i2cdevlib.com/forums/topic/75-mpu-6050-accelerometer-calibration-and-dmp/

ということで、静止状態でリセットした時の REAL ACCEL の出力データの様子を、下記のスケッチで試すことにしてみました。


#include &ltWire.h>
#include "I2Cdev.h"
#include "MPU6050DMP.h"
extern "C" {
#include "user_interface.h"
}

#define INT_PIN 4

MPU6050DMP mpu6050;
bool dmpReady = false;
uint16_t packetSize = 0;

volatile bool mpuInterrupt = false;
void dmpDataReady() {
mpuInterrupt = true;
}

unsigned long getCurrentTimeMS() {
return ESP.getCycleCount() / 80000L;
}

void setup() {

Wire.begin(12, 14);
Wire.setClock(400000);
Serial.begin(115200);
pinMode(INT_PIN, INPUT);

if (mpu6050.testConnection()) {
Serial.println("MPU6050 OK");
attachInterrupt(INT_PIN, dmpDataReady, RISING);
} else {
Serial.println("MPU6050 NG");
return;
}

mpu6050.initialize();
mpu6050.setXGyroOffset(220);
mpu6050.setYGyroOffset(76);
mpu6050.setZGyroOffset(-85);
mpu6050.setZAccelOffset(1688);

if (mpu6050.dmpInitialize() == 0) {
Serial.println("MPU6050DMP OK");
mpu6050.setDMPEnabled(true);
packetSize = mpu6050.dmpGetFIFOPacketSize();
dmpReady = true;
} else {
Serial.println("MPU6050DMP NG");
}
}

uint16_t fifoCount = 0;
uint8_t fifoBuffer[64];
unsigned long preTime = 0;

void loop() {

if (!dmpReady) return;

while (!mpuInterrupt);
mpuInterrupt = false;

while (fifoCount < packetSize) {
fifoCount = mpu6050.getFIFOCount();
}

uint8_t mpuIntStatus = mpu6050.getIntStatus();

if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
mpu6050.resetFIFO();
return;
} else if ((mpuIntStatus & 0x02) == false) {
return;
}

mpu6050.getFIFOBytes(fifoBuffer, packetSize);
fifoCount -= packetSize;

unsigned long curTime = getCurrentTimeMS();
unsigned long duration = curTime - preTime;

Quaternion q;
VectorInt16 aa;
VectorInt16 aaReal;
VectorFloat gravity;

mpu6050.dmpGetQuaternion(&q, fifoBuffer);
mpu6050.dmpGetAccel(&aa, fifoBuffer);
mpu6050.dmpGetGravity(&gravity, &q);
mpu6050.dmpGetLinearAccel(&aaReal, &aa, &gravity);
Serial.print("areal\t");
Serial.print(aaReal.x);
Serial.print("\t");
Serial.print(aaReal.y);
Serial.print("\t");
Serial.print(aaReal.z);
Serial.print("\t");
Serial.print(duration);
Serial.println("");
preTime = curTime;
}



4回データを測定をしてみました。縦軸の単位は G(9.8m/s^2) になります。0.5 は0.5G の意味です。











だいたいの傾向が見えてきました。データの間隔は10msecなので、17秒くらいで収束をしているようです。20秒静止していれば問題ないでしょう。

XYZ軸いずれもノイズ成分は Peak to Peak で 0.1G 程度あるようです。結構大きいですね。またZ軸(グレー)はオフセットがかかっているようなので調整が必要そうです。

次は斜め静止状態でどのようなデータが取れるか試してみたいと思います。
(^_^)/~









ESPr Developer(ESP-WROOM-02開発ボード)

  • 出版社/メーカー: スイッチサイエンス
  • メディア: エレクトロニクス



Make: Sensors: Projects and Experiments to Measure the World with Arduino and Raspberry Pi

  • 作者: Tero Karvinen
  • 出版社/メーカー: Maker Media, Inc
  • 発売日: 2014/06/02
  • メディア: ペーパーバック