LoginSignup
0
0

More than 3 years have passed since last update.

データシートを読んで、LIS331HH搭載三軸加速度センサモジュールを使いこなす

Posted at

この記事は、スイッチサイエンス社で販売されている、LIS331HH搭載3軸加速度センサモジュールをArduinoで使いこなすためのドキュメントです。
IMG_0403 2.jpg

Githubにあるサンプルコードを使って動作を確認したのち、測定レンジを切り替えるための作業を、データシートを参照しながら説明していきます。

サンプルコードを使って動かしてみる

この加速度センサは、Githubにサンプルコードがあるため、これでひとまずArduinoで動作を確認することができます。
ここでは、LIS331_I2C_Example.inoの方のコードを使ってみます。

このように配線を行い、プログラムを書き込むと、シリアルモニタから信号を確認できます。
アセット 1.png

ここでは、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ページ目に、このようなレジスタの説明が載っています。
Screenshot 2019-08-15_14-37-31-874.png
画像元:https://www.sparkfun.com/datasheets/Sensors/Accelerometer/LIS331HH.pdf

ここで、FS1、 FS0のところを読んでみると、デフォルトの値が00であり、FS1,FS0が01の時は±12g、11の時は±24gとなることがわかります。
つまり、このレジスタの値を新たに書き込んでしまえば、測定レンジを変更することができます。

ライブラリのファイルを読む

続いて、測定レンジを書き込むファイルの場所を探します。

cppファイルを見てみると、251行目から以下のようなコードが見つかります。

SparkFun_LIS331.cpp
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に変更したコードができました。完成したコードは以下になります。

LIS331_I2C_Example_acceralation.ino
#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");
  }
}
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0