この記事は、スイッチサイエンス社で販売されている、LIS331HH搭載3軸加速度センサモジュールをArduinoで使いこなすためのドキュメントです。
Githubにあるサンプルコードを使って動作を確認したのち、測定レンジを切り替えるための作業を、データシートを参照しながら説明していきます。
サンプルコードを使って動かしてみる
この加速度センサは、Githubにサンプルコードがあるため、これでひとまずArduinoで動作を確認することができます。
ここでは、LIS331_I2C_Example.inoの方のコードを使ってみます。
このように配線を行い、プログラムを書き込むと、シリアルモニタから信号を確認できます。
ここでは、xl.convertToG(6,x)がx軸方向の加速度、yl.convertToG(6,y)がy軸方向の加速度、zl.convertToG(6,z)がz軸方向の加速度となり、単位はG(m/s^2)となります。
データシートを読む
この加速度センサはHPで、プログラムで測定レンジを切り替え可能(±6g/±12g/±24g)と書かれていますが、デフォルト値は±6gとなっています。
この値を変更するために、データシートを参照します。
pdfファイル内でFull-scaleと検索すると、27ページ目に、このようなレジスタの説明が載っています。
画像元:https://www.sparkfun.com/datasheets/Sensors/Accelerometer/LIS331HH.pdf
ここで、FS1、 FS0のところを読んでみると、デフォルトの値が00であり、FS1,FS0が01の時は±12g、11の時は±24gとなることがわかります。
つまり、このレジスタの値を新たに書き込んでしまえば、測定レンジを変更することができます。
ライブラリのファイルを読む
続いて、測定レンジを書き込むファイルの場所を探します。
cppファイルを見てみると、251行目から以下のようなコードが見つかります。
void LIS331::setFullScale(fs_range range)
{
uint8_t data;
LIS331_read(CTRL_REG4, &data, 1);
data &= ~0xcf;
data |= range<<4;
LIS331_write(CTRL_REG4, &data, 1);
}
0xcfを2進数表示すると110011111、つまり、FS1とFS0の値は共にゼロに設定されていることがわかります。
そして、 data |= range<<4; という式が示すように、
rangeの値を入力することで、4つビットシフトされてdataの値に加算される、すなわち、FS1とFS0の値を設定することができます。
ヘッダーファイルを見てみると、40行目に、
typedef enum {LOW_RANGE, MED_RANGE, NO_RANGE, HIGH_RANGE} fs_range;
と書かれています。これはつまり、rangeの値として、LOW_RANGEと入力すると0、MED_RANGEを入力すると1、NO_RANGEを入力すると2、HIGH_RANGEを入力すると3となるということです。
実際、LOW_RANGE0は2進数で00となり、FS1=0 FS0=0に一致、MED_RANGEは01でFS1=0 FS0=1に一致、HIGH_RANGEは11でFS1=1 FS0=1に一致します。
サンプルコードを書き換える
いよいよ、Arduinoのサンプルコードを書き換えていきます。今回は測定レンジを±24gに変更します。
±24gはHIGH_RANGEに当たるので、void setup()内でxl.setFullScale(HIGH_RANGE); と書けば測定レンジは切り替わります。
書き換える場所はもう一点あります。加速度を単位Gで表示するxl.convertToG(6,x)らの中にある6は測定レンジを示すものであるため、24に変更します。
これで測定レンジを±24gに変更したコードができました。完成したコードは以下になります。
#include "SparkFun_LIS331.h"
#include <Wire.h>
LIS331 xl;
void setup()
{
// put your setup code here, to run once:
pinMode(9, INPUT); // Interrupt pin input
Wire.begin();
xl.setI2CAddr(0x19); // This MUST be called BEFORE .begin() so
// .begin() can communicate with the chip
xl.begin(LIS331::USE_I2C); // Selects the bus to be used and sets
// the power up bit on the accelerometer.
// Also zeroes out all accelerometer
// registers that are user writable.
// This next section configures an interrupt. It will cause pin
// INT1 on the accelerometer to go high when the absolute value
// of the reading on the Z-axis exceeds a certain level for a
// certain number of samples.
xl.intSrcConfig(LIS331::INT_SRC, 1); // Select the source of the
// signal which appears on pin INT1. In
// this case, we want the corresponding
// interrupt's status to appear.
xl.setIntDuration(50, 1); // Number of samples a value must meet
// the interrupt condition before an
// interrupt signal is issued. At the
// default rate of 50Hz, this is one sec.
xl.setIntThreshold(2, 1); // Threshold for an interrupt. This is
// not actual counts, but rather, actual
// counts divided by 16.
xl.enableInterrupt(LIS331::Z_AXIS, LIS331::TRIG_ON_HIGH, 1, true);
// Enable the interrupt. Parameters indicate
// w which interrupt source we're configuring,
//hich axis to sample, when to trigger
// (in this case, when the absolute mag
// of the signal exceeds the threshold),
// and whether to enable (true) or disable
// (false) the interrupt.
xl.setFullScale(HIGH_RANGE);
Serial.begin(115200);
}
void loop()
{
static long loopTimer = 0;
int16_t x, y, z;
if (millis() - loopTimer > 0)
{
loopTimer = millis();
xl.readAxes(x, y, z); // The readAxes() function transfers the
// current axis readings into the three
// parameter variables passed to it.
// Serial.println(x);
// Serial.println(y);
// Serial.println(z);
// Serial.println(xl.convertToG(6,x)); // The convertToG() function
// Serial.println(xl.convertToG(6,y)); // accepts as parameters the
// Serial.println(xl.convertToG(6,z)); // raw value and the current
// Serial.println(" "); // maximum g-rating.
Serial.println(sqrt(pow(xl.convertToG(24, x), 2) + pow(xl.convertToG(24, y), 2) + pow(xl.convertToG(24, z), 2)));
Serial.println("\n");
}
if (digitalRead(9) == HIGH)
{
Serial.println("Interrupt");
}
}