こんにちは、ENGかぴです。
Seeeduino XIAOのWire(SPI)を使用すると加速度センサー(ADXL345)の加速度やタップ情報などを取得することができます。ADXL345のライブラリを流用しながら加速度センサーの情報を取得する方法をまとめました。
ADXL345モジュール(秋月電子)を使用して加速度を取得しています。ライブラリーは一部ソースコードを追加して使用しています。
Seeeduino XIAOで動作確認したことについてリンクをまとめています。
Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方
加速度センサーのライブラリを使用する
ADXL345の製造元のアナログデバイセズのHPに提供されているライブラリを使用してもよいのですが、今回はSeeeduino用に有志が提供している「Accelerometer ADXL345」を使用します。
ADXL345のライブラリをインストールする

Arduino IDEを使ってライブラリをインストールして追加します。Arduino IDEのスケッチ欄からライブラリをインクルードを選択するとライブラリを管理の項目が表示されるのでクリックしてライブラリマネージャに遷移します。
ライブラリマネージャの検索欄にADXLを入力すると候補としてADXLに関するライブラリが表示されます。「Accelerometer ADXL345」を選択してインストールします。
PR:わからないを放置せず、あなたにあった最低限のスキルを身に着けるコツを教える テックジム 「書けるが先で、理解が後」を体験しよう!
ADXL345のライブラリを使用
ADXL345のライブラリをインストールするとADXL345のスケッチ例としてADXL345_demo_codeが準備されます。このスケッチ例を引用しながら初期化処理と加速度センサーの情報を取得します。設定する項目について使用しているライブラリについては以下の通りです。
関数名 | 設定するレジスタ | 内容 |
---|---|---|
powerOn() | POWER_CTL(0x2d) | レジスタをクリアした後、AUTO_SLEEPとMeasureのビットをセットして測定モードにする。 |
setActivityTheshold(引数) | THRESH_ACT(0x24) | 引数は符号なしの8ビットを値を指定する。スケールは62.5mg/LSB。アクティブイベントでの加速度信号の絶対値を比較される。 |
setInactivityThreshold(引数) | THRESH_INACT(0x25) | 引数は符号なしの8ビットの値を指定する。スケールは62.5mg/LSB。インアクティブイベントでの加速度信号の絶対値と比較される。 |
setTimeInactivity(引数) | TIME_INACT(0x26) | 引数は符号なしの8ビットの値を指定する。スケールは1sec/LSB。加速度がTHRESH_INACT値を下回ったまま設定した時刻が経過するとインアクティブとなる。 |
setActivityX(引数) setActivityY(引数) setActivityZ(引数) setInactivityX(引数) setInactivityY(引数) setInactivityZ(引数) | ACT_INACT_CTL(0x27) | 引数に1または0を指定する。0を指定するとDCカップリング動作となり1を設定するとACカップリング動作が有効になります。 DCカップリング動作は現在の加速度の大きさをTHRESH_ACT及びTHRESH_INACTと比較して判定する。ACカップリング動作はアクティブ開始時の加速度を基準としてTHRESH_ACT値を上回るとアクティブをトリガする。THRESH_INACTは基準値を下回ったまま時間経過でインアクティブ判定となる。 |
setTapDetectionOnX(引数) setTapDetectionOnY(引数) setTapDetectionOnZ(引数) | TAP_AXES(0x2A) | 引数に1または0を指定する。タップ検出したい軸に対して1を指定するとタップ検出の対象となる。 |
setTapThreshold(引数) | THRESH_TAP(0x1D) | 引数は符号なしの8ビットの値を指定する。タップ検出するための閾値を設定する。最大g値が+16gの時のスケールは62.5mg/LSB。 |
setTapDuration(引数) | DUR(0x21) | 引数は符号なしの8ビットの値を指定する。スケールは625us/LSB。タップイベントの検出時に加速度信号がTHRESH_TAP閾値を超える最大時間を設定する。 |
setDoubleTapLatency(引数) | LATENT(0x22) | 引数は符号なしの8ビットの値を指定する。スケールは1.25ms/LSB。タップイベントが検出されてから時間ウィンドウの開始までの待ち時間を設定する。 |
setDoubleTapWindow(引数) | WINDOW(0x23) | 引数は符号なしの8ビットの値を指定する。スケールは1.25ms/LSB。ダブルタップ検出において待ち時間満了後2番目の有効なタップを検出できる時間幅を設定する。 |
setFreeFallThreshold(引数) | THRESH_FF(0x28) | 引数は符号なしの8ビットの値を指定する。自由落下イベントを判定するためすべての軸の加速度とレジスタ値を比較する。スケールは62.5mg/LSB。推奨値は300~600ms(0x05~0x09)。 |
setFreeFallDuration(引数) | TIME_FF(0x29) | 引数は符号なしの8ビットの値を指定する。スケールは5ms/LSB。全ての軸がTHRESH_FFの値を下回ったまま本レジスタの時間が経過すると自由落下割り込みとなる。推奨値は100~350ms(0x14~0x46)。 |
setInterruptMapping(引数1,引数2) | INT_MAP(0x2F) | 引数1は対応するビット番号、引数2は割り込みの対象とするINT番号。引数1で指定したビット番号に対して0を指定するとINT1の出力、1を指定するとINT2の出力となる。 |
setInterrupt(引数1,引数2) | INT_ENABLE(0x2E) | 引数1は対応するビット番号、引数2は割り込み対象のビットの割り込みを有効の有無。 |
getAcceleration(引数) | DATAX0(0x32)~DATAZ1(0x37) | 引数は計算後の加速度情報を格納したい変数。小数点以下がでるためdouble型でXYZのデータを格納する配列が必要。 |
ADXL345について詳細なデータを把握したい場合はデータシートを下記リンクからダウンロードしてください。
ADXL345のライブラリでは設定項目はビットで管理しているものが多いためバイトで操作したい場合はソースコードを追加する必要があります。
ライブラリの一部を追加する
ADXL345のライブラリはビット指定で作られているためバイトデータを取得したい場合には不便なことがあります。タップ又はアクティブイベントの種別をバイトデータを取得して表示するためにライブラリの一部を追加しています。(ライブラリの更新により下記は不要となる可能性があります)
//ADXL345.hに追加する内容
class ADXL345
{
public:
//既存の関数
byte isTapSourcebyte(); //add
private:
//既存の関数
void setRegisterByte(byte regAdress, byte val); //add
byte getRegisterByte(byte regAdress); //add
};
ADXL345.hの内容を表示するためにはVsCode上で関数にカーソルを合わせて右クリックしたときに表示される定義へ移動および宣言へ移動を選択すると表示できます。次にADXL345.cpp内に関数の処理を追加します。
//ADXL345.cppに追加する内容
//既存の関数
byte ADXL345::isTapSourcebyte(){
return getRegisterByte(ADXL345_ACT_TAP_STATUS);
}
void ADXL345::setRegisterByte(byte regAdress, byte val){
writeTo(regAdress, val);
}
byte ADXL345::getRegisterByte(byte regAdress){
byte val;
readFrom(regAdress, 1, &val);
return val;
}
追加関数のisTapSourcebyte()はpublic指定しているのでADXL345.cpp以外のファイルからでもアクセスできますが、setRegisterbyte()及びgetRegisterByte()はprivate指定しているのでADXL345.cpp内のみ使用できます。
外部のファイルからの読み込みが不要な関数についてはprivate指定することでアクセスできないようにして参照の区分を明確にすることは有効な方法です。
追加関数のisTapSourcebyte()の使用例はACT_TAP_STATUSレジスタをバイトデータで読み出し各ビットをマスクした値と論理積をとることでビットが立っているのを確認しています。
byte intsrc2; //アクティブまたはタップイベントの内容
void loop(){
if( digitalRead(PIN_DI1) ){ //INT1
intsrc2 = adxl.isTapSourcebyte();
if( intsrc2 & ACT_TAP_ACT_X ){
Serial.println("ACT X");
}
/* 追加した関数を使用しない場合
if( adxl.isActivitySourceOnX()){
Serial.println("SINGLE_TAP");
}
*/
}
}
比較のためライブラリをそのまま使用した場合の例も示しています。どちらの考え方でも同じ動作になります。
ライブラリをそのまま使用する場合は関数をコールするたびにレジスタの値を参照することになりますが、isTapSourcebyte()の場合は一度のみのレジスタ参照となります。
レジスタへのアクセスを減らしたい場合は追加関数のisTapSourcebyte()を使用し、特にこだわりが無いのならそのまま使用しても問題ありません。
【クリエイターズファクトリー】卒業がない!挫折する心配なし!Webスクール説明会申し込み
動作確認

Seeeduino XIAOのDIを2本使ってADXL345のINT1とINT2の割り込みを判定できるようにしています。Wireを使用する場合マイコン内蔵のプルアップ抵抗などがない場合は抵抗を実装する必要があります。ADXL345モジュールにプルアップ抵抗が実装されているため不要です。
Arduino IDEのシリアルモニタにはXYZの軸の加速度の表示するようにしています。DATA_READY割り込みでデータを取得しているのでシリアルモニタにはかなり多くの頻度(10ms毎)で表示されてしまうため、タップ情報などの確認する際は表示部分をコメントアウトして確認しました。

Arduino IDEのシリアルプロッタを使用して加速度の変化が分かるように表示しました。シリアルモニタとシリアルプロッタは同時には使用できないためシリアルプロッタを使用する場合はソースコード全体の#define MONITER_USEをコメントアウトすると表示できます。

シリアルプロッタによる結果を確認すると加速度センサーを動かしているとXYZ軸の値が変化していることが分かります。机において動かさないようにすると加速度の動きが安定していることからうまく検出できていることが分かりました。
ソースコード全体
ソースコードは記事作成時点において動作確認できていますが、使用しているライブラリの更新により動作が保証できなくなる可能性があります。また、ソースコードを使用したことによって生じた不利益などの一切の責任を負いかねます。参考資料としてお使いください。
リンクからZIPファイル形式のファイルをダウンロードし、任意の場所に展開していただくとテキストファイルが生成されます。
関連リンク
Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。
Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方
Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
最後まで、読んでいただきありがとうございました。
割り込みイベントでFREE_FALL(自由落下)を発生させようとするとXYZ軸すべての条件を満たす必要があるため頻繁に発生させることができませんでしたが、20cm程度の高さから落下させると発生することがありました。あまり衝撃を与えるとモジュールが傷つくので動作確認はほどほどにしています。