【Arduino】加速度センサ(MMA8452Q)で角度を算出する

 

加速度センサ(MMA8452Q)で角度を算出する

こんなこと、やります。

  • 重力加速度から姿勢角度を計算する
  • Arduinoで加速度センサMMA8452Qを使ってみる
  • Arduinoと加速度センサで姿勢角度を計算する

重力加速度から姿勢角度を計算する

重力加速度から姿勢角度を計算する
重力加速度から姿勢角度を計算する

加速度センサを使って姿勢角度を計算する方法を解説します。

ここで説明するのは、重力加速度から姿勢角度を計算する方法になります。また話を簡単にするため「重力方向のz軸」と、「前後方向のx軸」の2軸に絞って考えます。

加速度センサから角度を計算する方法

センサにおけるx軸方向の加速度を\(a_x\)、z軸方向の加速度を\(a_z\)とします。

ここでは以前にラズパイで作った倒立振子のようなモデルで姿勢角度を考えてみましょう。

加速度センサと倒立振子モデル
加速度センサと倒立振子モデル

倒立振子がθだけ傾いた時を考えてみます。ただし、この状態で静止しているものとします。

倒立振子がθだけ傾いている
倒立振子がθだけ傾いている

物体は静止しているので、重力\(a\)のみの加速度がかかってます。よって、センサで読み取った加速度\(a_x\)と\(a_z\)のベクトルの合成値が、そのまま重力加速度\(a\)になるはずです。

センサのx軸とz軸の加速度
センサのx軸とz軸の加速度

これを分かりやすく書き直すと、次の図のようになります。

加速度センサのベクトル合成
加速度センサのベクトル合成

つまり、θは加速度\(a_x\)と\(a_z\)を使って次の式で表すことができます。

$$tanθ=\frac{a_x}{a_z}$$

姿勢角度θを計算するために、逆三角関数のアークタンジェントを使います。姿勢角度θを、次式であらわすことができました。

$$θ=tan^{-1}\frac{a_x}{a_z}$$

Arduino言語(C++)でアークタンジェントを使う場合は、atan2関数使います。

atan2(ax, az)

また、Raspberry PiなどのPythonでアークタンジェントを使うには、numpyarctan2関数を使います。

np.arctan2(ax, az) 

Arduinoで加速度センサMMA8452Qの使い方

それでは実際にArduinoで加速度センサをつかってみましょう。

つかうもの

ここで使うものを紹介しておきます。

Arduino

Arduino Uno Rev3を使用しました。

▼ もちろん、ほかのArduinoをお使いになってもらっても構いません。

もしまだArduinoをお持ちでないようでしたら、オススメArduinoどれを選べばいい?Arduinoで電子工作をはじめる方へをご参考になさってみてください。

加速度センサ

ここでは、MMA8452Qを搭載した加速度センサモジュールを使用しました。MMA8452Qは、I2C通信対応で、12ビットもしくは8ビットの分解能をもつ加速度センサです。

その他の電子部品

ブレッドボードやジャンプワイヤをお持ちでない方は揃えておいてください。

開発環境

項目 バージョン
Arduino IDE 1.8.13
パソコン macOS Big Sur 11.0.1

ArduinoとMMA8452Qの配線

こちらが、ArduinoとMMA8452Qの配線図になります。

ArduinoとMMA8452Qの配線図
ArduinoとMMA8452Qの配線図

ArduinoとMMA8452Qの配線で注意があります。それは、330Ωの抵抗を通してSCLとSDAをつなぐことです。ArduinoのGPIOが5Vであるのに対し、MMA8452Qが3.3V基準なので破損を防ぐため、抵抗でレベルシフトさせる必要があります。お使いのArduinoのデジタルピンが3.3Vの場合は、レベルシフトの必要はありません。

Arduinoで加速度センサMMA8452Qの使い方

MMA8452Qライブラリのインストール

加速度センサからデータを読み取るには、SparkFunが公開しているMMA8452QのArduinoライブラリを使うと簡単です。

下記のGitHubページからzipファイルをダウンロードしてください。

zipファイルを解凍し、フォルダを~/Document/Arduino/libraries/へ移動します。そして、Arduino IDEを再起動します。

ライブラリのインストールができていれば、FileExamplesSparkFun MMA8452Q Accelerometer以下にMMA8452Qのサンプルプログラムが表示されるはずです。

もしくはライブラリマネージャから、「SparkFun MMA8452Q」でライブラリ検索してインストールしてください。

Platform IOでMMA8452Qライブラリ検索
Platform IOでMMA8452Qライブラリ検索

ソースコード

こんな感じのプログラムを作っていきます。

加速度をシリアルプロッターで表示
加速度をシリアルプロッターで表示

サンプルプログラムをそのまま使わせて頂きました。加速度センサで取得した値をシリアルモニタや、シリアルプロッターで表示させることができます。

#include <Wire.h>
#include "SparkFun_MMA8452Q.h"

MMA8452Q accel;

void setup() {
  Serial.begin(9600);
  Wire.begin();

  if (accel.begin() == false) {
    Serial.println("Not Connected. Please check connections and read the hookup guide.");
    while (1);
  }
}

void loop() {
  if (accel.available()) {
    Serial.print(accel.getCalculatedX(), 3);
    Serial.print("\t");
    Serial.print(accel.getCalculatedY(), 3);
    Serial.print("\t");
    Serial.print(accel.getCalculatedZ(), 3);
    Serial.println();
  }
}

ソースコードの解説

accel.getCalculatedXなどで取得される値は、重力加速度1gを単位としてます。また、Spark Funの MMA8452Qチュートリアル によれば、データの転送速度は800Hzで、±2gまで測ることができるそうです。

Arduinoと加速度センサで姿勢角度を計算

加速度センサの使い方が分かったところで、今度は実際に、Arduinoを使って加速度センサから角度を計算させてみます。

ソースコード

Arduinoと加速度センサで姿勢角度を計算させたプログラムがこちらです。冒頭で説明したように、アークタンジェントを使って姿勢角度を制御しています。

#include <Arduino.h>
#include <Wire.h>
#include "SparkFun_MMA8452Q.h"

MMA8452Q accel;

void setup() {
  Serial.begin(9600);
  Wire.begin();

  if (accel.begin() == false) {
    Serial.println("Not Connected. Please check connections and read the hookup guide.");
    while (1);
  }
}

void loop() {
  if (accel.available()) {
    float ax = accel.getCalculatedX();
    float az = accel.getCalculatedZ();
    float angle = atan2(ax, az) * 180.0 / PI;

    Serial.print(angle, 3);
    Serial.println();
  }
}

Processingで姿勢角度を図形とシンクロさせ、また、加速度センサのノイズをローパスフィルタで除去してみました。詳しくはProcessingでArduinoとシリアル通信、加速度センサとローパスフィルタで動きの視覚化をご参考になさってみてください。

いろんなローパスフィルタをかけてみた
いろんなローパスフィルタをかけてみた

記事に関するご質問などがあれば、お問い合わせ までご連絡ください。
人気のArduino互換機
Arduinoで人気の周辺パーツ
あると便利な道具
Arduinoのオススメ参考書

▼ Arduino初心者向きの内容となっています。ほかのArduino書籍と比べて図や説明がとてもていねいで、読みやすかったです。Arduinoで一通りのセンサーが扱えるようになります。

▼ 外国人が書いた本を翻訳したものです。この手の書籍は、目からうろこな発見をすることが多いです。

▼ Arduinoの入門書を既に読んでいる方で、次のステップを目指したい人向きの本です。C言語のプログラミングの内容が中心です。ESP32だけでなく、ふつうのArduinoにも役立つ内容でした。

関連記事