接続はSPIで、普通にArduino側の11,12,13をMOSI,MISO,SCKに使い、10ピンをセレクトに使う。
Arduino | Akizuki LIS3DH | |||
---|---|---|---|---|
MOSI | DIGITAL 11 | --- | SDI | pin 4 |
MISO | DIGITAL 12 | --- | SDO | pin 5 |
SCK | DIGITAL 13 | --- | SPC | pin 3 |
SS | DIGITAL 10 | --- | CS | pin 6 |
電源 | 3.3V | --- | VDD | pin 1 |
GND | GND | --- | GND | pin 2 |
MOSIとSDI、MISOとSDO、SCKとSPC、そしてSSとして使うArduinoの10ピンをcsにつなぐ。
そして電源はArduinoの3.3Vピンをモジュール側の1、グランドは2につなぐ。
とりあえずこれで接続はOK。次はコードを書くだけ、SPIライブラリがあるから楽勝だろうと思ったのだけど、まあ、レジスタの設定だの読み出しの方法だの、試行錯誤をすることになった。参考にしたページはArduinoの圧力センサーとの接続、「LIS3DHとの接続がうまくいかない」というArduino Uno SPI Accelerometer Code Issueなど。
初期設定は、デフォルトの設定に従い、ビットオーダーをMSBFIRST、データモードはSPI_MODE3、クロック分割はSPI_CLOCK_DIV2をセット。コントロールレジスタ1には0x47をセットする。 コントロールレジスタ1の内容は、上位4ビットがサンプリングの周期で0100で50Hz。4ビット目がパワーモードでここは0にしてノーマル。下3ビットはXYZの有効/無効で、0111。つまり2進で01000111、16進で0x47、10進で71をセットする。 コントロールレジスタ1から6までの内容を設定することで、各種のモードや動作の設定ができる。データシート参照。
とりあえず下のようなコードを書いてみたところ、3軸とも加速度のデータは取れる。データの表現は2の補数。 ただ、気になるのはなぜか下位6ビットがゼロになっている。コントロールレジスタ4で感度の設定ができるので高感度モードにしたり、いろいろやってみたけど、やっぱり下位6ビットはゼロ。SPIの読み出しで何か間抜けなことをしてるのかもしれないけれど、とにかく加速度センサーが使える、ということで満足することにして、もう夜も更けたので今日はこのへんでおしまい。
10/29修正: コントロールレジスタ4での感度設定が間違っていたことに気がついた。4ビット目のフラグのHRを1にすると分解能12ビット、0にすると分解能10ビットになる。setupの所で
writeRegister(CTRL_REG4, 0x08);
を指定すれば12ビットの分解能で加速度を読み込める。「おかしーなー」と悩んでいた時は、3ビット目を立てたり降ろしたりしてたのでした。やっぱり間抜けなポカミスでした。#include
//Register Addresses: const int OUT_X_L = 0x28; //X-axis acceleration data const int OUT_X_H = 0x29; const int OUT_Y_L = 0x2A; //Y-axis acceleration data const int OUT_Y_H = 0x2B; const int OUT_Z_L = 0x2C; //Z-axis acceleration data const int OUT_Z_H = 0x2D; const int CTRL_REG1 = 0x20; //Register that can enable,disable axes const int CTRL_REG2 = 0x21; const int CTRL_REG3 = 0x22; const int CTRL_REG4 = 0x23; const int CTRL_REG5 = 0x24; const int CTRL_REG6 = 0x25; const int WHO_AM_I = 0x0F; //Dummy register const byte READ = 0b10000000; // LIS3DH's read command const byte WRITE = 0b00111111; // LIS3DH's write command const byte TEMP_CFG_REG = 0x1F; //Temperature sensor //Axis definitions int x_axis = 1; int y_axis = 2; int z_axis = 3; //Arduino ss pin10 const int ss = 10; void setup() { pinMode(ss, OUTPUT); // we use this for the SS at pin 10 SPI.begin(); //wake up the SPI bus SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE3); SPI.setClockDivider(SPI_CLOCK_DIV2); Serial.begin(115200); writeRegister(CTRL_REG1, 0x47); Serial.println(readRegister(WHO_AM_I)); delay(100); } int getValue(int axis) { int Val = 0; int h,l; if (axis == 1) { l = readRegister(OUT_X_L); h = readRegister(OUT_X_H); } else if (axis == 2) { l = readRegister(OUT_Y_L); h = readRegister(OUT_Y_H); } else if (axis == 3) { l = readRegister(OUT_Z_L); h = readRegister(OUT_Z_H); } Val = ((h << 8) | l); return Val; } unsigned int readRegister(byte thisRegister) { unsigned int result = 0; // result to return byte dataToSend = thisRegister | READ; digitalWrite(ss,LOW); SPI.transfer(dataToSend); result = SPI.transfer(0x00); digitalWrite(ss, HIGH); return result; } void writeRegister(byte thisRegister, byte thisValue) { byte dataToSend = thisRegister & WRITE; digitalWrite(ss,LOW); SPI.transfer(dataToSend); SPI.transfer(thisValue); digitalWrite(ss,HIGH); } void loop () { Serial.print(" x = "); Serial.print(getValue(x_axis)); Serial.print(" y = "); Serial.print(getValue(y_axis)); Serial.print(" z = "); Serial.println(getValue(z_axis)); delay(500); }
0 件のコメント:
コメントを投稿