基本構成
- 電源電圧:DC3.3V(動作範囲:DC2.4V~DC3.6V)
- 消費電流:6.1mA(Vdd 3V カタログ値)
- インターフェース:I2C、SPIのどちらかを選択できます
PIN配置
PIN No. | I2C | SPI |
1 | VDD 電源入力 DC2.4V~3.6V | |
2 | SCL シリアルクロック | SPC シリアルポートクロック |
3 | SDA シリアルデータ | SDI シリアルデータインプット |
4 | SA0 スレーブアドレスの下位ビット選択 | SDO シリアルデータアウトプット |
5 | VDDに接続するとI2Cモードになる | CS チップセレクト |
6 | インターラプト2 | |
7 | インターラプト1 | |
8 | GND |
I2CモードでArduinoと接続
以下説明書からの引用です。
- CS(5ピン)をVDDに接続すると、I2Cモードになります。
- SA0(4ピン)は、スレーブアドレスの下位ビット選択です。(この機能により2台まで使えます)
VDD(1ピン)に接続すると1101011x(0x6B)、GND(8ピン)に接続すると1101010x(0x6A)になります。(x:readの時1、writeの時0)
I2Cの場合、必ずどちらかに接続してください。
※ここではGNDに接続しています。 - SCL、SDAは外部抵抗でプルアップしてください。
使用しているArduino UNOでは、AREFの隣2つのSDA、SCLピンと、汎用のA4ピンがSDA、A5ピンがSCLがあります。
どちらかをL3GD20の3(SDA)、2(SCL)番ピンとそれぞれ接続します。
プルアップはI2C接続用にWireライブラリを使用するとArduinoの内部でプルアップされるので問題ありません。
とりあえずは、通信出来ているか調べてみましょう。
#include <Wire.h>
const byte L3GD20_WHOAMI = 0x0f;
void setup() {
Wire.begin();
Serial.begin(9600);
}
void loop() {
Wire.beginTransmission(L3GD20_ADDR);
Wire.write(L3GD20_WHOAMI);
Wire.endTransmission();
Wire.requestFrom(L3GD20_ADDR, 1);
Serial.println(Wire.read(), HEX);
delay(500);
}
シリアルモニタに0xD4が表示されていれば通信成功です。
次に実際にジャイロセンサの値を取得してみます。
#include <Wire.h>
const byte L3GD20_ADDR = 0x6a;
const byte L3GD20_WHOAMI = 0x0f;
const byte L3GD20_CTRL_REG1 = 0x20;
const byte L3GD20_OUT_X_L = 0x28;
const byte L3GD20_OUT_X_H = 0x29;
const byte L3GD20_OUT_Y_L = 0x2A;
const byte L3GD20_OUT_Y_H = 0x2B;
const byte L3GD20_OUT_Z_L = 0x2C;
const byte L3GD20_OUT_Z_H = 0x2D;
byte L3GD20_read(byte reg) {
Wire.beginTransmission(L3GD20_ADDR);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(L3GD20_ADDR, 1);
return Wire.read();
}
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println(L3GD20_read(L3GD20_WHOAMI), HEX);
Wire.beginTransmission(L3GD20_ADDR);
Wire.write(L3GD20_CTRL_REG1);
Wire.write(0x0f);
Wire.endTransmission();
}
void loop() {
int x, y, z;
int h, l;
l = L3GD20_read(L3GD20_OUT_X_L);
h = L3GD20_read(L3GD20_OUT_X_H);
x = (h << 8) | l;
l = L3GD20_read(L3GD20_OUT_Y_L);
h = L3GD20_read(L3GD20_OUT_Y_H);
y = (h << 8) | l;
l = L3GD20_read(L3GD20_OUT_Z_L);
h = L3GD20_read(L3GD20_OUT_Z_H);
z = (h << 8) | l;
Serial.print(x);
Serial.print("(");
Serial.print(x*0.00875);
Serial.print("),\t");
Serial.print(y);
Serial.print("(");
Serial.print(y*0.00875);
Serial.print("),\t");
Serial.print(z);
Serial.print("(");
Serial.print(z*0.00875);
Serial.println(")");
delay(500);
}
const byte L3GD20_ADDR = 0x6a;
const byte L3GD20_WHOAMI = 0x0f;
const byte L3GD20_CTRL_REG1 = 0x20;
const byte L3GD20_OUT_X_L = 0x28;
const byte L3GD20_OUT_X_H = 0x29;
const byte L3GD20_OUT_Y_L = 0x2A;
const byte L3GD20_OUT_Y_H = 0x2B;
const byte L3GD20_OUT_Z_L = 0x2C;
const byte L3GD20_OUT_Z_H = 0x2D;
byte L3GD20_read(byte reg) {
Wire.beginTransmission(L3GD20_ADDR);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(L3GD20_ADDR, 1);
return Wire.read();
}
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println(L3GD20_read(L3GD20_WHOAMI), HEX);
Wire.beginTransmission(L3GD20_ADDR);
Wire.write(L3GD20_CTRL_REG1);
Wire.write(0x0f);
Wire.endTransmission();
}
void loop() {
int x, y, z;
int h, l;
l = L3GD20_read(L3GD20_OUT_X_L);
h = L3GD20_read(L3GD20_OUT_X_H);
x = (h << 8) | l;
l = L3GD20_read(L3GD20_OUT_Y_L);
h = L3GD20_read(L3GD20_OUT_Y_H);
y = (h << 8) | l;
l = L3GD20_read(L3GD20_OUT_Z_L);
h = L3GD20_read(L3GD20_OUT_Z_H);
z = (h << 8) | l;
Serial.print(x);
Serial.print("(");
Serial.print(x*0.00875);
Serial.print("),\t");
Serial.print(y);
Serial.print("(");
Serial.print(y*0.00875);
Serial.print("),\t");
Serial.print(z);
Serial.print("(");
Serial.print(z*0.00875);
Serial.println(")");
delay(500);
}
実行するとX、Y、Zの取得値が表示されるかと思います。
MPU-6050の時と比べると何だか値がよくわからないのですが。。一応完了としておきます。
SPIモードでArduinoと接続
以下説明書からの引用です。
- SPC(2ピン)、SDI(3ピン)、SDO(4ピン)、CS(5ピン)の4線で接続します。
- 2:SPC - 13:SCK
- 3:SDI - 11:MOSI
- 4:SDO - 12:MISO
- 5:CS - 10:SS
- CS=Lでアクテイブ、クロックアイドル時=H、クロック立ち上がりでデータ読み込みです。
#include
const int L3GD20_CS = SS;
const byte L3GD20_ADDR = 0x6a;
const byte L3GD20_WHOAMI = 0x0f;
const byte L3GD20_CTRL_REG1 = 0x20;
const byte L3GD20_OUT_X_L = 0x28;
const byte L3GD20_OUT_X_H = 0x29;
const byte L3GD20_OUT_Y_L = 0x2A;
const byte L3GD20_OUT_Y_H = 0x2B;
const byte L3GD20_OUT_Z_L = 0x2C;
const byte L3GD20_OUT_Z_H = 0x2D;
const byte L3GD20_RW = 0x80;
const byte L3GD20_MS = 0x40;
byte L3GD20_read(byte reg) {
byte ret = 0;
digitalWrite(L3GD20_CS, LOW);
SPI.transfer(reg | L3GD20_RW);
ret = SPI.transfer(0);
digitalWrite(L3GD20_CS, HIGH);
return ret;
}
void setup() {
digitalWrite(SS, HIGH);
pinMode(SS, OUTPUT);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV8);
Serial.begin(9600);
while (!Serial) {}
Serial.println(L3GD20_read(L3GD20_WHOAMI), HEX);
digitalWrite(L3GD20_CS, LOW);
SPI.transfer(L3GD20_CTRL_REG1);
SPI.transfer(B00001111);
digitalWrite(L3GD20_CS, HIGH);
}
void loop() {
short h, l;
float x, y, z;
l = L3GD20_read(L3GD20_OUT_X_L);
h = L3GD20_read(L3GD20_OUT_X_H);
x = (h << 8) | l;
l = L3GD20_read(L3GD20_OUT_Y_L);
h = L3GD20_read(L3GD20_OUT_Y_H);
y = (h << 8) | l;
l = L3GD20_read(L3GD20_OUT_Z_L);
h = L3GD20_read(L3GD20_OUT_Z_H);
z = (h << 8) | l;
Serial.print(x);
Serial.print("(");
Serial.print(x*0.00875);
Serial.print("),\t");
Serial.print(y);
Serial.print("(");
Serial.print(y*0.00875);
Serial.print("),\t");
Serial.print(z);
Serial.print("(");
Serial.print(z*0.00875);
Serial.println(")");
delay(500);
}
const int L3GD20_CS = SS;
const byte L3GD20_ADDR = 0x6a;
const byte L3GD20_WHOAMI = 0x0f;
const byte L3GD20_CTRL_REG1 = 0x20;
const byte L3GD20_OUT_X_L = 0x28;
const byte L3GD20_OUT_X_H = 0x29;
const byte L3GD20_OUT_Y_L = 0x2A;
const byte L3GD20_OUT_Y_H = 0x2B;
const byte L3GD20_OUT_Z_L = 0x2C;
const byte L3GD20_OUT_Z_H = 0x2D;
const byte L3GD20_RW = 0x80;
const byte L3GD20_MS = 0x40;
byte L3GD20_read(byte reg) {
byte ret = 0;
digitalWrite(L3GD20_CS, LOW);
SPI.transfer(reg | L3GD20_RW);
ret = SPI.transfer(0);
digitalWrite(L3GD20_CS, HIGH);
return ret;
}
void setup() {
digitalWrite(SS, HIGH);
pinMode(SS, OUTPUT);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV8);
Serial.begin(9600);
while (!Serial) {}
Serial.println(L3GD20_read(L3GD20_WHOAMI), HEX);
digitalWrite(L3GD20_CS, LOW);
SPI.transfer(L3GD20_CTRL_REG1);
SPI.transfer(B00001111);
digitalWrite(L3GD20_CS, HIGH);
}
void loop() {
short h, l;
float x, y, z;
l = L3GD20_read(L3GD20_OUT_X_L);
h = L3GD20_read(L3GD20_OUT_X_H);
x = (h << 8) | l;
l = L3GD20_read(L3GD20_OUT_Y_L);
h = L3GD20_read(L3GD20_OUT_Y_H);
y = (h << 8) | l;
l = L3GD20_read(L3GD20_OUT_Z_L);
h = L3GD20_read(L3GD20_OUT_Z_H);
z = (h << 8) | l;
Serial.print(x);
Serial.print("(");
Serial.print(x*0.00875);
Serial.print("),\t");
Serial.print(y);
Serial.print("(");
Serial.print(y*0.00875);
Serial.print("),\t");
Serial.print(z);
Serial.print("(");
Serial.print(z*0.00875);
Serial.println(")");
delay(500);
}
実行してみるとI2Cと同じようにX、Y、Zの取得値が表示されますが、何故かしらSPIの値の方が想定値っぽい気が。。I2Cのソース何か間違ってるかも。
何にせよ、L3GD20を用いたI2C、SPIの両モードの使い方でした。
0 件のコメント:
コメントを投稿