加速度センサー MMA8452Q の値を Seeeduino で読み取る

 なんとなく興味があったので、加速度センサーを買ってみました。

www.switch-science.com

 Raspberry Pi や BLE Nano から使ってみようかとも思ったのですが、公式のチュートリアルでは Arduino での使い方が書いてあり、ライブラリもあるようだったので今回は Arduino Uno 互換の Seeeduino で加速度センサーの値を読み取ってみます。

チュートリアル
MMA8452Q Accelerometer Breakout Hookup Guide - learn.sparkfun.com

ピンヘッダの実装

 今回買った MMA8452Q の Breakout Board にはピンヘッダが実装されていません。

f:id:akanuma-hiroaki:20180428091145j:plain

 ブレッドボードで色々試してみるにはやはりピンヘッダがあった方が便利なので、自分で半田付けして実装しました。

f:id:akanuma-hiroaki:20180428091206j:plain

動作電圧

 MMA8452Q の動作電圧は 3.3V です。電源供給についてはマイコン側のピンで選べるようになっていることが多いかと思いますが、電源以外のピンの電圧も 3.3V に調整する必要があります。 Arduino Uno だと 5V なので、抵抗をかませるなどで 3.3V に調整しなくてはなりませんが、 Seeeduino は動作電圧を 5V にするか 3.3V にするかをスイッチで選べるようになっています。デフォルトでは 5V になっているので、 3.3V 側にスイッチを切り替えておきます。

f:id:akanuma-hiroaki:20180428093446j:plain

フックアップ

 MMA8452Q の出力インタフェースは I2C なので、 Seeeduino の SCL/SDA をそれぞれ MMA8452Q の SCL/SDA に接続します。 3.3V ピンと GND ピンもそれぞれ接続します。

f:id:akanuma-hiroaki:20180428091310j:plain

ファームウェア実装

 MMA8452Q の Arduino 用ライブラリが下記リポジトリで公開されています。

github.com

 IDE にライブラリをインポートするため、下記 URL からライブラリをダウンロードします。

https://github.com/sparkfun/SparkFun_MMA8452Q_Arduino_Library/archive/master.zip

 今回は IDE に Arduino Web Editor を使用します。 Web Editor の使い方の詳細は割愛しますが、左側メニューの「Libraries」の画面から先ほどダウンロードしたライブラリをインポートします。成功すると下記のような画面が表示されます。

f:id:akanuma-hiroaki:20180428091537p:plain

 コードについてはまずはサンプルをそのまま動かしてみます。ライブラリのリポジトリの下記 URL にてサンプルが公開されていますので、これをそのまま Web Editor でコピペします。

SparkFun_MMA8452Q_Arduino_Library/SparkFun_MMA8452Q_Basic.ino at master · sparkfun/SparkFun_MMA8452Q_Arduino_Library · GitHub

 コピペ後の画面は下記のような感じになります。 Seeeduino を USB で接続して正しく認識されていれば、対象のボードが表示されているかと思います。

f:id:akanuma-hiroaki:20180428091711p:plain

動作確認

 サンプルをそのまま動かすだけであればここまでで準備完了です。 Web Editor で Verify して問題なければ Seeeduino にファームウェアを Upload します。正しく動作すれば、 Web Editor の Serial Monitor に加速度センサーの値と、センサーの向きの情報が表示されていきます。

f:id:akanuma-hiroaki:20180428091743p:plain

傾きに応じて LED を点灯させる

 サンプルにちょっとだけ手を加えて、センサーの傾きに応じて LED を点灯させてみたいと思います。サンプルコードからコメントを削除して、 LED を動作させるようにしたコードを下記に載せておきます。やっていることは単純で、 LED を4つ配置し、サンプルコードで判定しているセンサーの向きに応じて対応する LED を点灯させているだけです。

#include <Wire.h> // Must include Wire library for I2C
#include <SparkFun_MMA8452Q.h> // Includes the SFE_MMA8452Q library

MMA8452Q accel;

const int ledPortraitUp = 13;
const int ledPortraitDown = 12;
const int ledLandscapeRight = 10;
const int ledLandscapeLeft = 11;

void setup()
{
  Serial.begin(9600);
  Serial.println("MMA8452Q Test Code!");
  
  accel.init();
  
  pinMode(ledPortraitUp, OUTPUT);
  pinMode(ledPortraitDown, OUTPUT);
  pinMode(ledLandscapeRight, OUTPUT);
  pinMode(ledLandscapeLeft, OUTPUT);
}

void loop()
{
  if (accel.available())
  {
    accel.read();
    
    printCalculatedAccels();
    
    printOrientation();
    
    Serial.println(); // Print new line every time.
  }
}

void printAccels()
{
  Serial.print(accel.x, 3);
  Serial.print("\t");
  Serial.print(accel.y, 3);
  Serial.print("\t");
  Serial.print(accel.z, 3);
  Serial.print("\t");
}

void printCalculatedAccels()
{ 
  Serial.print(accel.cx, 3);
  Serial.print("\t");
  Serial.print(accel.cy, 3);
  Serial.print("\t");
  Serial.print(accel.cz, 3);
  Serial.print("\t");
}

void printOrientation()
{
  byte pl = accel.readPL();
  switch (pl)
  {
  case PORTRAIT_U:
    digitalWrite(ledPortraitUp, HIGH);
    digitalWrite(ledPortraitDown, LOW);
    digitalWrite(ledLandscapeRight, LOW);
    digitalWrite(ledLandscapeLeft, LOW);
    Serial.print("Portrait Up");
    break;
  case PORTRAIT_D:
    digitalWrite(ledPortraitUp, LOW);
    digitalWrite(ledPortraitDown, HIGH);
    digitalWrite(ledLandscapeRight, LOW);
    digitalWrite(ledLandscapeLeft, LOW);
    Serial.print("Portrait Down");
    break;
  case LANDSCAPE_R:
    digitalWrite(ledPortraitUp, LOW);
    digitalWrite(ledPortraitDown, LOW);
    digitalWrite(ledLandscapeRight, HIGH);
    digitalWrite(ledLandscapeLeft, LOW);
    Serial.print("Landscape Right");
    break;
  case LANDSCAPE_L:
    digitalWrite(ledPortraitUp, LOW);
    digitalWrite(ledPortraitDown, LOW);
    digitalWrite(ledLandscapeRight, LOW);
    digitalWrite(ledLandscapeLeft, HIGH);
    Serial.print("Landscape Left");
    break;
  case LOCKOUT:
    digitalWrite(ledPortraitUp, LOW);
    digitalWrite(ledPortraitDown, LOW);
    digitalWrite(ledLandscapeRight, LOW);
    digitalWrite(ledLandscapeLeft, LOW);
    Serial.print("Flat");
    break;
  }
}

 動作させた時の様子は下記のようになります。傾きに応じて持ち上がっている側の LED が点灯するようになっています。

まとめ

 Arduino 用のライブラリが公開されているおかげで値の読み取りはとても簡単にできてしまいました。 Raspberry Pi 等で扱う場合はどうすれば良いのかも気になるところなので、今後調べてみようと思います。