3軸ジャイロ L3GD20 をArduino で動かしてみる
◆まえがき
ちょっとやって見たいことがあるので、昔買ったL3GD20という3軸ジャイロセンサーを、Arduino NANOで動かしてみました。
◆3軸ジャイロ L3GD20

STマイクロのセンサーを秋月の接続カードに実装した物です。なお、現在ではこの部品は廃版になっていて、L3GD20Hと言う型番に変わっています。
◆回路図

Arduino NANOに接続した状態です。このジャイロは3.3V動作なので、NANOから出ている3.3V電源を使って動かします。
インターフェイスはI2Cで動かし、そのバスのレベルは3.3Vにします(3.3Vに4.7kΩでプルアップ)。実はこういう接続方法にすると、NANO側の入力のHighレベルが十分確保出来ていないのですが、まあちょっと試すくらいなら大丈夫です。詳しくは、こちらの記事で解説しています。
◆I2Cの波形
ちょっと面白い話があるのでI2Cの波形を見ながら説明します。
・プルアップ抵抗4.7kΩの場合

下がクロック(SCL)、上がデーター(SDA)です。バススピード100kHzで動いていて、当然ですが振幅は3.3Vです。記事に掲載した回路図通りに作るとこの波形になっています。
・プルアップ抵抗無しの場合

実は4.7kΩのプルアップ抵抗を外しても回路は正常に動き、その時の波形は上の写真のようになります。
プルアップ抵抗無しにするとバスが動かなくなるかと思ったら、実は大丈夫です。ArduinoのI2C(Wire.h)のライブラリは、I2Cのピン(A4とA5)のCPU内蔵のプルアップ抵抗を有効にするので、約35kΩで5Vへプルアップされた状態になります。つまり弱くプルアップされるので、100kHzくらいの速度なら何とか動きます。
上の波形の立ち上がり部のなまりは、プルアップ抵抗が高いために発生しています。あと、波形の振幅を良く見ると、一つ上の波形より少し大きくなっていますが、これは5Vにプルアップされているためです。(一つ上の波形は3.3Vに4.7kΩでプルアップされています。)
◆ブレッドボード

◆プログラム
ジャイロの測定結果にオフセットが100くらいあったので、起動時にzeroCalib関数でオフセット量を測定して補正するようにしました。
◆動作例

手でジャイロを持っていろいろな向きに傾け、出力をシリアルプロッタで見たものです。動きを3軸に分離して検出出来ています。
◆まとめ
とりあえずこれで動作確認できました。このセンサーはArduinoいじりを始めた頃に倒立振子を作るために買った物で、5-6年ぶりに動かしてみた訳ですが、ちゃんと動いて良かったです。
ジャイロの出力波形がギザギザしているような感じで少し気になるのですが、あまり高い精度が必要なことに使う予定では無いので無視することにします。
これで動き(回転角)の検出ができるようになりました。次は、画面に顔を表示しているプログラム(Arduino NANO アバター)と組み合わせてみたいと思います。触ると表情が変わるような物が作れるはずです。
ちょっとやって見たいことがあるので、昔買ったL3GD20という3軸ジャイロセンサーを、Arduino NANOで動かしてみました。
◆3軸ジャイロ L3GD20

STマイクロのセンサーを秋月の接続カードに実装した物です。なお、現在ではこの部品は廃版になっていて、L3GD20Hと言う型番に変わっています。
◆回路図

Arduino NANOに接続した状態です。このジャイロは3.3V動作なので、NANOから出ている3.3V電源を使って動かします。
インターフェイスはI2Cで動かし、そのバスのレベルは3.3Vにします(3.3Vに4.7kΩでプルアップ)。実はこういう接続方法にすると、NANO側の入力のHighレベルが十分確保出来ていないのですが、まあちょっと試すくらいなら大丈夫です。詳しくは、こちらの記事で解説しています。
◆I2Cの波形
ちょっと面白い話があるのでI2Cの波形を見ながら説明します。
・プルアップ抵抗4.7kΩの場合

下がクロック(SCL)、上がデーター(SDA)です。バススピード100kHzで動いていて、当然ですが振幅は3.3Vです。記事に掲載した回路図通りに作るとこの波形になっています。
・プルアップ抵抗無しの場合

実は4.7kΩのプルアップ抵抗を外しても回路は正常に動き、その時の波形は上の写真のようになります。
プルアップ抵抗無しにするとバスが動かなくなるかと思ったら、実は大丈夫です。ArduinoのI2C(Wire.h)のライブラリは、I2Cのピン(A4とA5)のCPU内蔵のプルアップ抵抗を有効にするので、約35kΩで5Vへプルアップされた状態になります。つまり弱くプルアップされるので、100kHzくらいの速度なら何とか動きます。
上の波形の立ち上がり部のなまりは、プルアップ抵抗が高いために発生しています。あと、波形の振幅を良く見ると、一つ上の波形より少し大きくなっていますが、これは5Vにプルアップされているためです。(一つ上の波形は3.3Vに4.7kΩでプルアップされています。)
◆ブレッドボード

◆プログラム
// File:20220111_L3GD20test.inoネットに転がっていた事例を参考に書き直したもので、ジャイロを使って角速度を測定してシリアルに流すようになっています。
// Arduino で3軸ジャイロ(L3GD20)の値を読む
// 2022/01/11 ラジオペンチ
#include <Wire.h>
#define L3GD20_ADDR 0x6a // I2Cアドレス
#define L3GD20_CTRL_REG1 0x20 //
int rotX, rotY, rotZ; // 現在の角度
int rotX0, rotY0, rotZ0; // ゼロ補正量
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("x,y,z"); // シリアルデーターの項目名を表示
gyroSetup(); // ジャイロのモード設定
zeroCalib(); // ジャイロのゼロキャリブレーション
}
void loop() {
sensAngle(); // 現在の姿勢を計測
Serial.print(rotX); Serial.print(", "); // 結果を表示
Serial.print(rotY); Serial.print(", ");
Serial.print(rotZ); Serial.println();
delay(30);
}
void sensAngle() { // ジャイロの値を読む
int hi, lo;
lo = L3GD20_read(0x28);
hi = L3GD20_read(0x29);
rotX = ((hi << 8) | lo) - rotX0 ; // X軸
lo = L3GD20_read(0x2A);
hi = L3GD20_read(0x2B);
rotY = ((hi << 8) | lo) - rotY0 ; // Y軸
lo = L3GD20_read(0x2C);
hi = L3GD20_read(0x2D);
rotZ = ((hi << 8) | lo) - rotZ0 ; // Z軸
}
void zeroCalib() { // ジャイロのゼロ点補正
int xs = 0; // sum値用変数
int ys = 0;
int zs = 0;
rotX0 = 0; // ゼロ補正無しにして、
rotY0 = 0;
rotZ0 = 0;
for (int i = 0; i < 100; i++) { // 100回
sensAngle(); // 測定して
xs += rotX; // 値を累積
ys += rotY;
zs += rotZ;
delay(10);
}
rotX0 = xs / 100; // ゼロ補正量を設定
rotY0 = ys / 100;
rotZ0 = zs / 100;
}
void gyroSetup() { // ジャイロのモード設定
Wire.beginTransmission(L3GD20_ADDR);
Wire.write(L3GD20_CTRL_REG1);
Wire.write(0x0f); // 動作モード設定
Wire.endTransmission();
}
byte L3GD20_read(byte reg) { // 指定アドレスの値を読む
Wire.beginTransmission(L3GD20_ADDR);
Wire.write(reg); // レジスタ番号を指定
Wire.endTransmission();
Wire.requestFrom(L3GD20_ADDR, 1);
return Wire.read(); // データーを読んで帰り値にする
}
ジャイロの測定結果にオフセットが100くらいあったので、起動時にzeroCalib関数でオフセット量を測定して補正するようにしました。
◆動作例

手でジャイロを持っていろいろな向きに傾け、出力をシリアルプロッタで見たものです。動きを3軸に分離して検出出来ています。
◆まとめ
とりあえずこれで動作確認できました。このセンサーはArduinoいじりを始めた頃に倒立振子を作るために買った物で、5-6年ぶりに動かしてみた訳ですが、ちゃんと動いて良かったです。
ジャイロの出力波形がギザギザしているような感じで少し気になるのですが、あまり高い精度が必要なことに使う予定では無いので無視することにします。
これで動き(回転角)の検出ができるようになりました。次は、画面に顔を表示しているプログラム(Arduino NANO アバター)と組み合わせてみたいと思います。触ると表情が変わるような物が作れるはずです。
- 関連記事
-
- Raspberry Pi Picoで72LEDのクリスマスツリーイルミネーションを作る
- 3軸ジャイロを使ってアバターの表情を動かす、「きょろきょろ君」を作って見た
- 3軸ジャイロ L3GD20 をArduino で動かしてみる
- Arduino NANO でアバター表示、回路図とプログラム
- マンデルブロベンチマーク測定結果の一覧表