加速度計+Arduinoで、「特定エリアの振動」だけを感知できる

加速度計+Arduinoで、「特定エリアの振動」だけを感知できる

今回の「技術情報」は、加速度計やArduinoの活用・適用方法についてリサーチしているエンジニアの皆様に、お役立ていただけそうな話題です。
「広いエリア内の、ある場所に、何らかの振動が加わった時、その場所を特定できないか・・・?」。先日、社内のとあるプロジェクトで、こんな課題が持ち上がりました。そこで、安価に入手できる加速度計を用いた実現方法を考えてみたのです。開発環境やデータ取得の方法をご紹介しつつ、いかなる成果が得られたのかを記載します。

by Tadaharu Inoue  2014/03/10

加速度計+Arduinoで、「特定エリアの振動」だけを感知できる

「広いエリアの中の、とある場所に何らかの振動が加わった時、その場所を特定できないものか・・・?」。先日、社内のプロジェクトでこんな課題が持ち上がったので、実現方法を考えてみました。
最初に思いついたのは、赤外線などを枠外からメッシュ状に出して、「赤外線が遮断されたポイント(つまり、何かにぶつかったところ)」=「振動の加わった場所」である・・・という判定方法。しかし、こんなシステムを自作しようとすると、かなりの金額になってしまいそう・・・。
そこで、次に思いついたのが、加速度計を使った実現方法でした。

加速度計&Arduinoで、実験を開始

加速度計であれば単価が安いし、過去のプロジェクトで取り扱ったことがあるので、技術的なハードルも低そうだと考えました。しかし、広いエリアのどこかに振動が加わったときに、本当にその場所を、加速度計で特定できるものなのでしょうか・・・? まずは、振動を感知する対象となるエリアを、何らかの手段で限定できるようにする必要がありそうです。そのために、次のような装置を作って実験してみました。

使用デバイス

図 1 加速度計ADXL345
図 2 Arduino UNO

配線図

Arudinoと加速度計は、以下のように配線しました。写真のようにブレッドボードを使って簡易的に作成しています。

図 3 Arduino、加速度計配線図
図 4 配線した結果

Arduino開発環境

Arduinoの開発環境は、以下のサイトからダウンロードしました。また、プログラムの書き込みや、シリアル通信でのデバッグ出力を利用するためのドライバも、このサイトからインストールする必要があります。
Arduino開発環境、及び、ドライバのダウンロード

使用デバイス実験用ソースコード

データ取得用のソースコードを、以下に示します。加速度計の「ADXL345」が加速度データを更新したら取得して、デバッグ用のシリアルポートから出力するだけのプログラムです。


#include

// ピンアサイン
int CS=10;
int LED_OUT=7;

//ADXL345 レジスタアドレス
#define BW_RATE 0x2C //Data rate and power mode control
#define POWER_CTL 0x2D //Power Control Register
#define INT_SOURCE 0x30 //Source of interrupts
#define DATA_FORMAT 0x31 //Data format control
#define DATAX0 0x32 //X-Axis Data 0

// ADXL345データ更新割り込み
#define DATA_READY 0x80

char values[10];
int x,y,z;
double xg, yg, zg;

void setup(){
SPI.begin();
SPI.setDataMode(SPI_MODE3);
Serial.begin(9600);

pinMode(CS, OUTPUT);
pinMode(LED_OUT, OUTPUT);

digitalWrite(CS, HIGH);
digitalWrite(LED_OUT, LOW);

// ADXL345初期化
writeRegister(DATA_FORMAT, 0x03); // +-16g 10bit
writeRegister(BW_RATE, 0x19); // サンプリングレート50Hz、省電力モード
writeRegister(POWER_CTL, 0x08); //Measurement mode
readRegister(INT_SOURCE, 1, values); // 念のため割り込み発生レジスタを読み込んでおく
}

void loop()
{
// 値が更新されたらサンプリングする
readRegister(INT_SOURCE, 1, values);
if(values[0] & DATA_READY)
{
readRegister(DATAX0, 6, values);

x = ((int)values[1]<<8)|(int)values[0];
y = ((int)values[3]<<8)|(int)values[2];
z = ((int)values[5]<<8)|(int)values[4];

// 0.03125 = (16*2)/(2^10)
xg = x * 0.03125;
yg = y * 0.03125;
zg = z * 0.03125;

Serial.print(xg);
Serial.print("¥t');
Serial.print(yg);
Serial.print('¥t');
Serial.println(zg);
}
}
void writeRegister(char registerAddress, char value){
// SPI開始時にCSをLOWにする
digitalWrite(CS, LOW);
// レジスタアドレス送信
SPI.transfer(registerAddress);
// レジスタに設定する値送信 SPI.transfer(value);
// SPI終了時にCSをHIGHにする
digitalWrite(CS, HIGH);
}

void readRegister(char registerAddress, int numBytes, char * values){
// 複数バイト読み出し
char address = 0x80 | registerAddress;
if(numBytes > 1)address = address | 0x40;
// SPI開始時にCSをLOWにする
digitalWrite(CS, LOW);
// 読み出し先レジスタのアドレスを送信
SPI.transfer(address);
// 値の読み出し
for(int i=0; i<numBytes; i++){
values[i] = SPI.transfer(0x00);
}
// SPI終了時にCSをHIGHにする
digitalWrite(CS, HIGH);
}

Arduinoのソースはこちらからダウンロードいただけます

振動実験の準備

今回の実験では、振動を感知する対象となるエリアを設けるために、こんなセンサ装置を作りました!木枠に塩ビ製の布を貼ってあります。

裏側には、ぶら下げた木板の中央に、加速度計付きのArduinoを貼り付けてあります。このように、木版に加速度計を取り付けて設置することで、振動を感知するエリアを限定できないかと考えたわけです。この木版の範囲にボールが当たったときと、木版が無いところにボールが当たったときで、取得できる加速度データに違いがあるのかどうかを確かめます。木版に当たった場合は、瞬間的に激しい加速度が発生し、木版から外れた場合は、塩ビ布が振動を吸収してくれて加速度は感知されない・・・という結果を期待しています。

データ取得方法

加速度データはTeraTermなどで出力させることができます(Arduino IDEでも出力を見ることは可能です)。ドライバがインストールされているPCにArduinoをUSB接続すると、シリアルポートの選択肢にArduinoが出てきます。

接続を開始すると、現在の3軸加速度データが出力されます。

この出力結果を全選択してコピーすれば、結果をそのままExcelに貼り付けることができます。Excel上でグラフ化することで、加速度の時間遷移を可視化します。

取得したデータと、その考察

以上で、実験のための準備は整いました。
では、標的に向かってボールを投げることで取得できた興味深い結果を、以下のグラフに示します。

左列のグラフが「木版にボールが当たった場合」、右列は「木版からは外れたが塩ビ布には当たった場合」の結果です。上から順に、X,Y,Z方向の加速度を表しています。ボールが木版に当たった場合を見てみると、ボールが当たった瞬間に大きな加速度を感知していることがわかります。それに対してボールが木版から外れた場合は、若干の加速度を感知しているものの、木版に当たった場合とは明らかに結果に差があることがわかります。このほかにも、「木版にボールを強め/弱めに当てた場合」、「木版の近いところ/遠いところで外れた場合」などのデータを取得しましたが、見事に木版に当たったときだけ瞬間的な強い加速度を感知することができました。
また、ボールが当たったときのデータ特性として、瞬間的に大きな加速度を感知した後にすぐに定常状態に戻っていることが分かります。木版は4本の紐で固定しているだけなのでボールが当たった後も多少ゆらゆら揺れているのですが、その揺れが及ぼす加速度計への影響は小さいようです(他の加速度計だとまた違う結果になるかもしれません)。この結果から、振動感知後に何かしらのトリガーを引きたい場合は、ADXL345のActivity割り込み(※)が使えそうだということがわかりました。

※「ADXL345のActivity割り込み」:一定のしきい値を超えた加速度を感知した場合に、割り込みを入れることができます。しきい値と対象の軸を設定することが可能です。

まとめ

今回の実験結果から、加速度計と木版を組み合わせることで、特定エリアに限定した振動センサとして使えそうだということがわかりました。この加速度計+木版のセンサ装置を、特定エリアの中に複数セット設置することで、どこに振動が加わったのかを特定することができそうです。振動を感知したいエリアを狭めたい場合は、木版のサイズを小さくしてやれば良さそうですね。また、今回取得したデータの特性から、加速度計のActivity割り込みを使用すれば、振動を感知したときにプロセッサ側で何かしらのトリガーを引くことができそうです。

以上のような結果が得られたことで、この実験は大成功でした!今回使用したArduinoのソースコードは、以下からダウンロードして下さい。

Arduinoのソースはこちらからダウンロードいただけます