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での加速度測定
- 3軸加速度センサモジュール ADXL345(SPI/IIC)
- I2Cバス用双方向電圧レベル変換モジュール(PCA9306)
- Arduino Uno
- USBケーブル
- ブレッドボード
- ジャンパ線
- 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秒待機)
}
X-Axis:0.08m/s^2 Y-Axis:0.20m/s^2 Z-Axis:9.38m/s^2
X-Axis:0.24m/s^2 Y-Axis:0.20m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.49m/s^2
X-Axis:0.08m/s^2 Y-Axis:0.31m/s^2 Z-Axis:9.49m/s^2
X-Axis:0.20m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.12m/s^2 Y-Axis:0.27m/s^2 Z-Axis:9.41m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.27m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.45m/s^2
サンプルプログラムでは、セットアップで「最大分解能モード・±16g」、「省電力機能コントロール・測定モード」を行い、ループでX軸、Y軸、Z軸の加速度を測定します。
読み出した加速度の13bitデータは、各軸ごとに加速度の値に換算して、シリアルモニタに表示させます。
SPIでの加速度測定
- 3軸加速度センサモジュール ADXL345(SPI/IIC)
- 4ビット双方向ロジックレベル変換モジュール BSS138使用
- Arduino Uno
- USBケーブル
- ブレッドボード
- ジャンパ線
- 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秒待機)
}
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.20m/s^2 Z-Axis:9.49m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.49m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.27m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.27m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.12m/s^2 Y-Axis:0.27m/s^2 Z-Axis:9.38m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.49m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.45m/s^2
X-Axis:0.16m/s^2 Y-Axis:0.24m/s^2 Z-Axis:9.49m/s^2
サンプルプログラムでは、I2Cのサンプルプログラムと同様、セットアップで「最大分解能モード・±16g」、「省電力機能コントロール・測定モード」を行い、ループでX軸、Y軸、Z軸の加速度を測定します。
読み出した加速度の13bitデータは、各軸ごとに加速度の値に換算して、シリアルモニタに表示させます。
なお、SPIで使われる各端子の説明は以下にまとめました。サンプルプログラムのSPIライブラリでも端子名が使われています。
- SCK(Serial ClocK) :通信タイミング用のクロック
- MISO(Master In Slave Out) :スレーブからマスターへのデータ送信
- MOSI(Master Out Slave In) :マスターからスレーブへのデータ送信
- SS(Slave Select pin) :制御対象にするデバイス選択
おすすめのArduinoボードはどれ?
当記事『Arduino-3軸加速度センサ「ADXL345」の使い方』では、Arduino Unoを使用したサンプルプログラムを解説してきました。
やはり、たくさんの種類のあるArduinoボードの中でも、最も基本的なエディションのArduino Unoがおすすめなのですが、Arduino Unoと電子部品を組み合わせたキットも存在します。
電子工作初心者にとっては、いちいち電子部品を別途購入する必要がないので非常に有用です。以下の記事で初心者でもわかりやすいように、ランキング形式でおすすめのArduino Unoを紹介しているので、ぜひご覧ください。
また、以下の記事で、安価でWi-Fi/Bluetoothに対応している「ESP32開発ボード」についてもまとめてみました。
このボードは、Arduinoボードではありませんが、Arduino IDEでソフト開発ができるため、電子工作でIoTを実現したい方におすすめです。