Arduinoのサンプルプログラム

Arduino-3軸加速度センサ「ADXL345」の使い方

当記事では、Arduinoで3軸加速度センサ「ADXL345」を使う方法を詳しく解説します。

3軸加速度センサ「ADXL345」はI2C/SPIで制御するため、ArduinoのWireライブラリ、SPIライブラリを使ったプログラムで、それぞれ動作させます。

なお、その他のArduino関数・ライブラリについては、以下の記事をご覧ください。

3軸加速度センサ「ADXL345」の基本スペック

「ADXL345」はI2C/SPI制御で、加速度を測定できるセンサです。

当記事では、基板にモジュール化された秋月電子通商の「3軸加速度センサモジュール ADXL345(SPI/IIC)」を使用して、サンプルプログラムを解説していきます。

基本スペック ADXL345
電源電圧 DC2.0~3.6V
I/O電圧 DC1.7V~Vs
通信方式 I2C/SPI
測定範囲 最大±16g
データビット数 最大13bit
消費電流 測定モード:23uA(Typ.)
スタンバイモード:0.1uA(Typ.)
※Vs=2.5V


ADXL345のより詳細なスペックを確認したい場合は、以下のリンク先にあるデータシートをご覧ください。

3軸加速度センサ「ADXL345」のコマンド

名称 説明 アドレス
DEVID デバイスID 0x00
Reserved 予約(アクセス不可) 0x01 to 0x1C
THRESH_TAP タップしきい値 0x1D
OFSX X軸オフセット 0x1E
OFSY Y軸オフセット 0x1F
OFSZ Z軸オフセット 0x20
DUR タップ期間 0x21
Latent タップ待ち時間 0x22
Window タップウィンドウ 0x23
THRESH_ACT アクティブしきい値 0x24
THRESH_INACT 非アクティブしきい値 0x25
TIME_INACT 非アクティブ時間 0x26
ACT_INACT_CTL 軸イネーブルコントロール
(アクティブ/非アクティブ検出)
0x27
THRESH_FF 自由落下しきい値 0x28
TIME_FF 自由落下時間 0x29
TAP_AXES シングルタップ/ダブルタップ・軸コントロール 0x2A
ACT_TAP_STATUS シングルタップ/ダブルタップ・ソース 0x2B
BW_RATE データレート/電力モードコントロール 0x2C
POWER_CTL 省電力機能コントロール 0x2D
INT_ENABLE 割り込みイネーブルコントロール 0x2E
INT_MAP 割り込みマッピングコントロール 0x2F
INT_SOURCE 割り込みソース 0x30
DATA_FORMAT データ・フォーマット・コントロール 0x31
DATAX0 X軸データ0 0x32
DATAX1 X軸データ1 0x33
DATAY0 Y軸データ0 0x34
DATAY1 Y軸データ1 0x35
DATAZ0 Z軸データ0 0x36
DATAZ1 Z軸データ1 0x37
FIFO_CTL FIFOコントロール 0x38
FIFO_STATUS FIFOステータス 0x39


ADXL345のより詳細なコマンド内容を確認したい場合は、以下のリンク先にあるデータシートをご覧ください。

サンプルプログラム(サンプルスケッチ)

加速度測定のサンプルプログラムをI2CとSPIでの方法にわけて紹介します。

I2Cでの加速度測定

用意するもの
  1. 3軸加速度センサモジュール ADXL345(SPI/IIC)
  2. I2Cバス用双方向電圧レベル変換モジュール(PCA9306)
  3. Arduino Uno
  4. USBケーブル
  5. ブレッドボード
  6. ジャンパ線
  7. PC(プログラム書き込み・シリアルモニタ表示)

#include <wire.h>

//アドレス指定
#define ADXL345_ADDR 0x53
#define DATA_FORMAT 0x31
#define POWER_CTL 0x2D
#define DATAX0 0x32
#define FULL_RES_16G 0x0B
#define BIT10_16G 0x03
#define MEASURE 0x08

void setup() {
  Serial.begin(9600);//シリアル通信を9600bpsで初期化
  Wire.begin();//I2Cを初期化
 
  Wire.beginTransmission(ADXL345_ADDR);//I2Cスレーブ「Arduino Uno」のデータ送信開始
  Wire.write(DATA_FORMAT);//データ・フォーマット・コントロール
  Wire.write(FULL_RES_16G);//「最大分解能モード」、「±16g」
  //Wire.write(BIT10_16G);//「10bit固定分解能モード」、「±16g」
  Wire.endTransmission();//I2Cスレーブ「Arduino Uno」のデータ送信終了
 
  Wire.beginTransmission(ADXL345_ADDR);//I2Cスレーブ「Arduino Uno」のデータ送信開始
  Wire.write(POWER_CTL);//省電力機能コントロール
  Wire.write(MEASURE);//測定モード
  Wire.endTransmission();//I2Cスレーブ「Arduino Uno」のデータ送信終了
}
 
void loop() {
  unsigned int dac[6];
  unsigned int i, x, y, z;
  float X_Axis, Y_Axis, Z_Axis;

  Wire.beginTransmission(ADXL345_ADDR);//I2Cスレーブ「Arduino Uno」のデータ送信開始
  Wire.write(DATAX0);//出力データバイトを「X軸データ0」のアドレスに指定
  Wire.endTransmission();//I2Cスレーブ「Arduino Uno」のデータ送信終了
  
  Wire.requestFrom(ADXL345_ADDR, 6);//I2Cデバイス「ADXL345」に6Byteのデータ要求
  for (i=0; i<6; i++){
    while (Wire.available() == 0 ){}
    dac[i] = Wire.read();//dacにI2Cデバイス「ADXL345」のデータ読み込み
  }

  x = (dac[1] << 8) | dac[0];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
  X_Axis = float(x) * 0.0392266;//加速度の計算、X_Axisに代入 ※0.0392266=(4/1000*9.80665)
  y = (dac[3] << 8) | dac[2];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
  Y_Axis = float(y) * 0.0392266;//加速度の計算、Y_Axisに代入
  z = (dac[5] << 8) | dac[4];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
  Z_Axis = float(z) * 0.0392266;//加速度の計算、Z_Axisに代入
  
  Serial.print("X-Axis:");//文字列「X-Axis:」をシリアルモニタに送信
  Serial.print(X_Axis);//「X_Axis」をシリアルモニタに送信
  Serial.print("m/s^2 ");//文字列「m/s^2」をシリアルモニタに送信
  Serial.print("Y-Axis:");//文字列「Y-Axis:」をシリアルモニタに送信
  Serial.print(Y_Axis);//「Y_Axis」をシリアルモニタに送信
  Serial.print("m/s^2 ");//文字列「m/s^2」をシリアルモニタに送信
  Serial.print("Z-Axis:");//文字列「Z-Axis:」をシリアルモニタに送信
  Serial.print(Z_Axis);//「Z_Axis」をシリアルモニタに送信
  Serial.println("m/s^2");//文字列「m/s^2」をシリアルモニタに送信、改行
   
  delay(1000);//1000msec待機(1秒待機)
}

サンプルプログラムでは、セットアップで「最大分解能モード・±16g」、「省電力機能コントロール・測定モード」を行い、ループでX軸、Y軸、Z軸の加速度を測定します。

読み出した加速度の13bitデータは、各軸ごとに加速度の値に換算して、シリアルモニタに表示させます。

SPIでの加速度測定

用意するもの
  1. 3軸加速度センサモジュール ADXL345(SPI/IIC)
  2. 4ビット双方向ロジックレベル変換モジュール BSS138使用
  3. Arduino Uno
  4. USBケーブル
  5. ブレッドボード
  6. ジャンパ線
  7. PC(プログラム書き込み・シリアルモニタ表示)

#include <SPI.h>

//アドレス指定
#define ADXL345_ADDR 0x53
#define DATA_FORMAT 0x31
#define POWER_CTL 0x2D
#define DATAX0 0x32
#define FULL_RES_16G 0x0B
#define BIT10_16G 0x03
#define MEASURE 0x08
 
void setup() {
  Serial.begin(9600);//シリアル通信を9600bpsで初期化
  SPI.begin();//SPIを初期化、SCK、MOSI、SSの各ピンの動作は出力、SCK、MOSIはLOW、SSはHIGH

  SPI.setDataMode(SPI_MODE3);//SPIモードを「3」に設定・CPOL(クロック位相)=1,CPHA(クロック極性)=0
  SPI.setBitOrder(MSBFIRST);//SPI送受信用のビットオーダーを「MSBFIRST」に設定
 
  digitalWrite(SS, LOW);//SSピンの出力をLOW(0V)に設定
  SPI.transfer(DATA_FORMAT);//データ・フォーマット・コントロール
  SPI.transfer(FULL_RES_16G);//「最大分解能モード」、「±16g」
  //SPI.transfer(BIT10_16G);//「10bit固定分解能モード」、「±16g」
  digitalWrite(SS, HIGH);//SSピンの出力をHIGH(5V)に設定
 
  digitalWrite(SS, LOW);//SSピンの出力をLOW(0V)に設定
  SPI.transfer(POWER_CTL);//省電力機能コントロール
  SPI.transfer(MEASURE);//測定モード
  digitalWrite(SS, HIGH);//SSピンの出力をHIGH(5V)に設定
}
 
void loop() {
  unsigned int dac[6];
  unsigned int i, x, y, z;
  float X_Axis, Y_Axis, Z_Axis;
 
  digitalWrite(SS, LOW);//SSピンの出力をLOW(0V)に設定
  SPI.transfer(DATAX0 | 0x80 | 0x40);//出力データバイトを「X軸データ0」のアドレスに指定、書き込みフラグ・複数バイトフラグを立てる
  for (i=0; i<6; i++){
    dac[i] = SPI.transfer(0x00);//dacにSPIデバイス「ADXL345」のデータ読み込み
  }
  digitalWrite(SS, HIGH);//SSピンの出力をHIGH(5V)に設定
 
  x = (dac[1] << 8) | dac[0];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
  X_Axis = float(x) * 0.0392266;//加速度の計算、X_Axisに代入 ※0.0392266=(4/1000*9.80665)
  y = (dac[3] << 8) | dac[2];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
  Y_Axis = float(y) * 0.0392266;//加速度の計算、Y_Axisに代入
  z = (dac[5] << 8) | dac[4];//2Byte目のデータを8bit左にシフト、OR演算子で1Byte目のデータを結合して、xに代入
  Z_Axis = float(z) * 0.0392266;//加速度の計算、Z_Axisに代入
  
  Serial.print("X-Axis:");//文字列「X-Axis:」をシリアルモニタに送信
  Serial.print(X_Axis);//「X_Axis」をシリアルモニタに送信
  Serial.print("m/s^2 ");//文字列「m/s^2」をシリアルモニタに送信
  Serial.print("Y-Axis:");//文字列「Y-Axis:」をシリアルモニタに送信
  Serial.print(Y_Axis);//「Y_Axis」をシリアルモニタに送信
  Serial.print("m/s^2 ");//文字列「m/s^2」をシリアルモニタに送信
  Serial.print("Z-Axis:");//文字列「Z-Axis:」をシリアルモニタに送信
  Serial.print(Z_Axis);//「Z_Axis」をシリアルモニタに送信
  Serial.println("m/s^2");//文字列「m/s^2」をシリアルモニタに送信、改行
   
  delay(1000);//1000msec待機(1秒待機)
}

サンプルプログラムでは、I2Cのサンプルプログラムと同様、セットアップで「最大分解能モード・±16g」、「省電力機能コントロール・測定モード」を行い、ループでX軸、Y軸、Z軸の加速度を測定します。

読み出した加速度の13bitデータは、各軸ごとに加速度の値に換算して、シリアルモニタに表示させます。

なお、SPIで使われる各端子の説明は以下にまとめました。サンプルプログラムのSPIライブラリでも端子名が使われています。

SPI 各端子の説明
  • SCK(Serial ClocK) :通信タイミング用のクロック
  • MISO(Master In Slave Out) :スレーブからマスターへのデータ送信
  • MOSI(Master Out Slave In) :マスターからスレーブへのデータ送信
  • SS(Slave Select pin) :制御対象にするデバイス選択
テキストのコピーはできません。