3軸加速度センサー(ADXL345)の使い方 - I2C版 [Arduino]
XYZの3軸の加速度(m/s2)を取得できる「ADXL345」の使い方です。
加速度の単位は「m/s2」(メートル毎秒毎秒)で1秒間に1メートル毎秒(m/s)の加速度と定義されています。

最大分解能モード/±16gの実行結果

※プログラム上ではm/s2を「m/s^2」と表記しています。
地球の重力は「1G = 9.80665m/s2」です。ですので、Z軸には地球の重力が含まれています。
使用部品・材料
総額で約920円です。(Arduino本体の値段を除く)
部品/材料 | 値段 | 備考 |
---|---|---|
ブレッドボード | ¥270 | 秋月電子の通販コード(P-00315) |
3軸加速度センサモジュール ADXL345 | ¥450 | 秋月電子の通販コード(M-06724) |
I2Cバス用双方向電圧レベル変換モジュール(FXMA2102) | ¥200 | 秋月電子の通販コード(M-05825) |
配線図
Arduino UNOの動作電圧は5V。ADXL345の動作電圧は2.0-3.6Vですので、電圧レベル変換モジュールを使用して3.3Vで接続しています。

CSピンは必ずハイレベル接続する必要があります。この点の注意を怠るとデバイスとの通信ができなくなることがあります。
※SCL/SDAには基板(内部)で10kΩの抵抗が通してあります。
スケッチ(プログラム)
各XYZ軸の加速度(m/s2)をシリアルモニターへ出力します。
#include <Wire.h> // デバイスアドレス(スレーブ) uint8_t DEVICE_ADDRESS = 0x53; // XYZレジスタ用のテーブル(6byte) uint8_t RegTbl[6]; void setup() { Serial.begin(9600); // マスタとしてI2Cバスに接続する Wire.begin(); // DATA_FORMAT(データ形式の制御) Wire.beginTransmission(DEVICE_ADDRESS); // DATA_FORMATのアドレス Wire.write(0x31); // 「最大分解能モード」 及び 「±16g」 (0x0B == 1011) Wire.write(0x0B); // 「10bit固定分解能モード」 及び 「±16g」にする場合 (0x03 == 0011) // Wire.write(0x03); Wire.endTransmission(); // POWER_TCL(節電機能の制御) Wire.beginTransmission(DEVICE_ADDRESS); // POWER_CTLのアドレス Wire.write(0x2d); // 測定モードにする Wire.write(0x08); Wire.endTransmission(); } void loop() { // XYZの先頭アドレスに移動する Wire.beginTransmission(DEVICE_ADDRESS); Wire.write(0x32); Wire.endTransmission(); // デバイスへ6byteのレジスタデータを要求する Wire.requestFrom(DEVICE_ADDRESS, 6); // 6byteのデータを取得する int i; for (i=0; i< 6; i++){ while (Wire.available() == 0 ){} RegTbl[i] = Wire.read(); } // データを各XYZの値に変換する(LSB単位) int16_t x = (((int16_t)RegTbl[1]) << 8) | RegTbl[0]; int16_t y = (((int16_t)RegTbl[3]) << 8) | RegTbl[2]; int16_t z = (((int16_t)RegTbl[5]) << 8) | RegTbl[4]; // 各XYZ軸の加速度(m/s^2)を出力する Serial.print("X : "); Serial.print( x * 0.0392266 ); Serial.print(" Y : "); Serial.print( y * 0.0392266 ); Serial.print(" Z : "); Serial.print( z * 0.0392266 ); Serial.println(" m/s^2"); delay(100); }
「最大分解能モード」では各XYZの値に対してスケール係数(m/s2)の「0.0392266」を乗算すると加速度を取得する事ができます。
「10bit固定分解能モード」の場合は加速度を算出できない(?)ので係数は不要です。恐らく、各XYZの値をそのまま使用するものと思われます。(要確認)
スケール係数(m/s2)の求め方
データシートから引用(ADXL345_jp.pdf p29)
このビットが値 1 に設定されると、デバイスは最大分解能モードになり、出力分解能がレンジ・ビットによって設定された g レンジに従って増加して 4 mg/LSB のスケール係数を維持します。FULL_RES ビットが 0 に設定されると、デバイスは 10 ビット・モードになり、レンジ・ビットが最大の g レンジとスケール係数を決めます。
最大分解能モードの場合は「4mg/LSBのスケール係数を維持」とありますから「常に4mg/LSB」となります。
次に「4mg/LSB」の「LSB」です。
LSB(least significant bit)は一番右の最下位ビットの事です。なので十進数の1の位を指しています。よって、「LSB = 1」と解釈できます。すると、さきほどの単位は「4mg/1」で「4mg」だけが残ります。
地球の重力は「1G = 9.80665m/s2」です。それで、さきほどの4mgをG単位に変換すると
となります。
そして、スケール係数(m/s2)を求めるには地球の標準重力を乗算します。
となります。
参考リンク
https://github.com/adafruit/Adafruit_ADXL345
最後に
この「ADXL345」は「タップ/ダブル・タップの検出」や「アクティブ/インアクティブの検出 」「自由落下の検出」など多機能ですので、時間がある方は挑戦してみると良いと思います。
掲示板
ArduinoやRaspberry Piなどの電子工作の掲示板を作成しました。質問やわからない事は電子工作 (Arduino・ラズパイ等)でユーザー同士で情報を共有して下さい。