概要
前回は気圧計でした。今回は3軸加速度センサーになります。
加速度センサーとは?
どちらの方向に動いているのかを計測するセンサーになります。ただし、静止している場合には下方向の重力で引っ張られていることになります。この重力を1Gとしての計測になります。自由落下するぐらいの速度が1Gなので、結構動かさないとだめです。
また、静止している場合にどの軸に向かって1Gがかかっているのかを調べることで、どっちの面が下に置かれているのかを判定することができます。斜めの場合なども、計算をすることでどれぐらいの角度かを求めることができます。ただし、静止している場合であり、動いている場合には重力の力なのか、移動している力なのかの判定が難しくなります。
3軸とは?
基本的には加速度はX軸、Y軸、Z軸の3軸センサーになります。なのになぜ3軸加速度センサーと呼ばれるかですが、加速度の他に軸がどの方向に回転しているかを測定するジャイロセンサーを組み合わせることが多いです。この場合には加速度の3軸と、ジャイロの3軸をあわせて6軸センサーとも呼びます。
さらに、コンパスと呼ばれる地磁気センサーを使って、北極(正確には北磁極)の方向を3軸で測定して、9軸センサーなどもあります。実は地磁気センサーのみあれば、北磁極との相対的な角度がわかるのでこれだけあれば良さそうに思えます。ただし、コンパスって割と適当なので、周りの磁気の影響などでかんたんに狂ってしまいます。そのため、素早い動きは加速度とジャイロセンサーで直接計測し、大まかにどっちの方角を向いているのかをジャイロセンサーで補正する使い方が主なようです。
ライブラリのインストール

LIS3DHTRセンサーの名前で検索したところ、Seeed社のものしかありませんでした。これは結構珍しいことで、マイナーなセンサーを採用したってことですね。
スケッチ例
LIS3DHTR_IICを動かしてみますが、「LIS3DHTR didn’t connect.」と表示され、そのままだと動きません。
過去のI2Cスキャナを実行していたと思います。
Scanning...
I2C device found at address 0x19 !
I2C device found at address 0x3C !
I2C device found at address 0x77 !
done
上記がその結果です。
LIS.begin(WIRE); //IIC init dafault :0x18
//LIS.begin(WIRE, 0x19); //IIC init
スケッチ例を見てみると上記の行がありました。デフォルトは0x18ですが、0x19のセンサーの場合には変更する必要があるようでした。このキットに採用されているのはI2Cスキャナからみて0x19ですね。
// This example use I2C.
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
void setup()
{
Serial.begin(115200);
while (!Serial)
{
};
//LIS.begin(WIRE); //IIC init dafault :0x18
LIS.begin(WIRE, 0x19); //IIC init
LIS.openTemp(); //If ADC3 is used, the temperature detection needs to be turned off.
// LIS.closeTemp();//default
delay(100);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
// LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_10HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_100HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_200HZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KHZ);
// LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
LIS.setHighSolution(true); //High solution enable
}
void loop()
{
if (!LIS)
{
Serial.println("LIS3DHTR didn't connect.");
while (1)
;
return;
}
//3 axis
// Serial.print("x:"); Serial.print(LIS.getAccelerationX()); Serial.print(" ");
// Serial.print("y:"); Serial.print(LIS.getAccelerationY()); Serial.print(" ");
// Serial.print("z:"); Serial.println(LIS.getAccelerationZ());
//ADC
// Serial.print("adc1:"); Serial.println(LIS.readbitADC1());
// Serial.print("adc2:"); Serial.println(LIS.readbitADC2());
// Serial.print("adc3:"); Serial.println(LIS.readbitADC3());
//temperature
Serial.print("temp:");
Serial.println(LIS.getTemperature());
delay(500);
}
これで動くようになりました。ただし、実行結果は温度だけ表示されていますね。実際の加速度部分はコメントアウトされています。
スケッチ例2
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; //IIC
#define WIRE Wire
void setup()
{
Serial.begin(115200);
while (!Serial)
{
};
LIS.begin(WIRE, 0x19); //IIC init
delay(100);
LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
LIS.setHighSolution(true); //High solution enable
}
void loop()
{
if (!LIS){
Serial.println("LIS3DHTR didn't connect.");
while (1)
;
return;
}
//3 axis
Serial.print("x:"); Serial.print(LIS.getAccelerationX()); Serial.print(" ");
Serial.print("y:"); Serial.print(LIS.getAccelerationY()); Serial.print(" ");
Serial.print("z:"); Serial.print(LIS.getAccelerationZ()); Serial.print(" ");
Serial.println();
delay(20);
}
必要最低限なものに編集してみました。

上記がシリアルプロッタで確認した図になります。いろいろ動かすと波形が変化するのがわかると思います。机においているときはZが1ですので、地面に向かっている重力はZ軸で下がプラスなのがわかります。その後にボードを回転してみると各軸がわかってくると思います。
加速度計は実際のみためと、センサーの軸がずれていることがあるので注意してください。例えば縦に基板が入っている場合には、重力の軸がZ軸ではなくX軸やY軸になることも考えられます。
どの方向においた場合に、どんな値になるのかを確認してから数値を取り扱う必要があります。回転して置かれる場合には、軸の入れ替えなどをして想定している数値になるような調整が必要です。
また、センサーによってどっちがプラスなのかも違う場合がありますので、複数のセンサーを組み合わせた場合、軸がそもそも違う場合があることに注意して利用してください。
設定値にレンジとデータレートがあります。こちらも重要でレンジは必要な加速度範囲に一番近いものを使うと精度が高いです。たとえば2Gに設定すると2Gまでしか測定ができませんが、一番精度が高い加速度になります。ただし、2G以上の加速度が取得できません。6Gにすると、2Gに比べて範囲が3倍になるので精度も3分の1になります。ちょっとしか動かない場合には2Gで問題ないと思います。ただし、重力の1G分があるので、重力1G+実際の加速度の1Gになってしまう可能性があります。これは実際にセンサーを動かしながら、シリアルプロッタでどれぐらいの数値が出力されるかを確認しながら調整をする必要があります。
データレートもかなり重要で、実際にはなるべく早いレートで取得したほうがよいです。そして一定間隔で取得しないとデータ精度が悪くなります。とはいえArduino UNOだと高精度の加速度センサーは扱えきれないと思うので、そこまで気にしなくてもよいかもしれません。
まとめ
とりあえずすべての部品を触ってみました。公式Wikiだと複数の部品を組み合わせたものを扱っていたので、こちらのブログでももう少し紹介したいと思っています。
コメント