ラベル Arduino の投稿を表示しています。 すべての投稿を表示
ラベル Arduino の投稿を表示しています。 すべての投稿を表示

2014/05/05

ジャイロセンサで遊ぶ

ジャイロセンサ(9 Degrees of Freedom センサスティック)を使っていろいろ実験。
ゆくゆくはセグウェイもどきを作る予定。

実験方法

ジャイロセンサを地面に置いた状態を初期値とする。
ジャイロセンサを傾けてみて、元に戻す。
これを何回か繰り返す。

CPU : Arduino UNO
センサ : 9 Degrees of Freedom センサスティック

ジャイロセンサの設定

Sample rate :1000Hz
Digital LPF :47Hz

センサ値の取得は1軸のみ。


1.補正無し

ジャイロセンサから100ms間隔でデータ値を取る。このデータ値、つまり変化量は赤線で表す。
取得したデータ値を変数に加算していって積分する。このデータは現在角度で緑線で表す。


だんだんと誤差が増えていっている模様。


2.オフセット、平均補正を付加

起動時、センサの値を20ms間隔で5回取得し、この平均をオフセット値とする。

センサ値を20msで5回取得した平均を取ったものを変化量とする。変化量は赤線。
変化量を加算した(積分した)のが現在角度。角度は緑線。


補正よりはマシになった。何回か動かすだけならば問題ないみたい。



課題

オフセットと平均補正を取ったら改善はした。
が、どうしても少しずつズレていっているみたい。
これをどうにかする。

2013/05/04

加速度センサで角度検出してみるの巻

【2014/10/12 記事更新】


前回の記事(http://nekolab.blogspot.jp/2013/05/arduino.html)で、加速度センサ(ADXL345)を動かしてみました。


今回は、センサから得た値の計算をして、センサの傾きを検出してみようと思います。


前回の記事で、加速度センサに傾き検出が~、と書いてましたが、加速度センサは重力加速度も検出するというコメントを頂きました。


と、いうことはですよ、重力がどの向きにかかっているのかを検出することで、センサがどれだけ傾いているかを検出できるということですね。

スマホの画面の向きが変わるやつとかはこれを利用してるのか...知らなかったです。
加速度センサで傾きが分かるとは思わなかったので。



デバイスはArduinoで、前回と大体同じです。


ちょこっとだけプログラムが変わっています。

センサの値を取得するのは前回の記事と変わりません。


このセンサの値ですが、重力加速度がそのまま出力されているわけではありません。

センサに設定してあるスケール(今回は±16g)の範囲で、13bitの分解能(高分解能モードの場合)で出力されます。

出力が1だけ変化したときの重力加速度の変化は、

(16 + 16) / 2^13 = 0.00390635

と、約3.9mgです。


センサ出力の値に0.0039を掛けると、重力加速度に変換できます。

ただしこれは、±16gのスケールと13bitの分解能の場合です。
センサの設定が違えば、この値も変わってきます。



センサの値を重力加速度に変換できたら、X軸の回転角と、Y軸の回転角を求めます。



上図で、OX向きをX軸の回転軸とします。同様にY軸もOYを回転軸とします。

OZは重力加速度で、常に1gの大きさがあります。

また、上図には書いてませんが、角OXZ、角OYZ、角XOYは直角です。


この図で、θxがXの回転軸の角度、θyがYの回転軸の角度です。

θx、θyを求めれば、センサがどれだけ傾いているかがわかります。



上図は、OXZの三角形を抜き出したものです。


これからθxを求めるには、OZとOYの大きさが分かっていれば求められます。

OZは重力加速度なので常に1です。

OYはY軸方向の加速度で、センサの出力から求められます。


よって、θxは、

θx = sin^-1(OY / 1)[rad]

で求められます。


sin^-1はアークサインで、直角三角形の斜辺と求めたい角に接しない辺の長さから、求めたい角の大きさを求める三角関数です。

また、この計算結果は弧度法(ラジアン)で与えられるため注意が必要です。(C言語のmath.hの場合)



同様に、θyについても計算を行うと、もう片方の軸の角度を求めることができます。



さて、これを実際にArduinoで実装してみます。


#include
#include

int acc_address = 0x53;
long acc_x, acc_y, acc_z;
double g_x, g_y, g_z;
double x_rol, y_rol;


void setup()
{
  Serial.begin(9600);
  
  Wire.begin();
  
  Wire.beginTransmission(acc_address);
  Wire.write(0x31);
  Wire.write(0x0B);
  Wire.endTransmission();
  
  Wire.beginTransmission(acc_address);
  Wire.write(0x2d);
  Wire.write(0x08);
  Wire.endTransmission();
  
  delay(1);
}

void loop()
{
  Wire.beginTransmission(acc_address);
  Wire.write(0x32);
  Wire.endTransmission();
  Wire.requestFrom(acc_address, 6);
  if(Wire.available() > 5){
    acc_x = Wire.read();
    acc_x = (Wire.read() << 8) | acc_x;
    acc_y = Wire.read();
    acc_y = (Wire.read() << 8) | acc_y;
    acc_z = Wire.read();
    acc_z = (Wire.read() << 8) | acc_z;
  }
  
  
  g_x = acc_x * 0.0039;
  g_y = acc_y * 0.0039;
  g_z = acc_z * 0.0039;
  
  x_rol = asin(g_y / 1) * (180 / 3.1415);
  y_rol = asin(g_x / 1) * (180 / 3.1415);
  
  Serial.println(g);
  Serial.print("X_rol:");Serial.println(x_rol);
  Serial.print("Y_rol:");Serial.println(y_rol);
  
  delay(100);
}


大体こんな感じです。

シリアル通信で、PCに傾きの値を送信しています。



しかし、この加速度センサは、静止状態では傾きが分かりますが、水平方向に加速度が働くと、正しい値を得られません。

逆に、傾いた状態で、水平方向の加速度を測定することもできません。


じゃあどうするか?

加速度センサ以外のセンサを使って、傾きを検知すればいいのではないか?と思います。


というわけで、ジャイロセンサと加速度センサを使って、傾きと加速度を検出できるようにしたいと思います。


でもまだやってないので、また今度です。


【2014/10/12追加】
加速度センサとジャイロセンサを使って、傾きを検出する方法を書きました。
https://sites.google.com/site/nekolabwiki/electronic/posturecontroll

以下、参考文献、またはサイト
http://www.geology.smu.edu/~dpa-www/robo/balance/inertial.pdf
https://sites.google.com/site/yamagajin/home/filter
http://www.slideshare.net/rogy01/6-32797657

2013/05/03

加速度センサーをArduino使って読み取ってみる

部の顧問の先生から、こんなモジュールを頂きました。


加速度センサ(ADXL345)と方位センサ(HMC5883L)とジャイロセンサ(ITG-3200)が一つの基板にまとめられたモジュールです。

ストロベリーリナックスで売られてました。
一個で一万円ぐらいします。

学生の自分にはなかなか手が出せませんね。


せっかく頂いたので、使ってみようじゃないかということで、使ってみました。


このモジュール、Arduinoを使えと言わんばかりに、Arduinoのシールドにはんだ付け済みでした。

手元にArduinoがあるので、これで動かしてみます。




今回は3つあるセンサのうちの一つ、加速度センサ「ADXL345」というセンサを使ってみます。
http://www.analog.com/static/imported-files/jp/data_sheets/ADXL345_jp.pdf




このセンサは、SPI通信か、I2C通信を用いて、通信をします。

センサは基板にはんだ付けされていて、このモジュールではI2C通信はできません。
そのため、I2C通信を使います。


ADXL345の使い方を簡単にまとめてみます。



・ADXL345を測定モードにする
POWER_CTL(0x2D)のD3をセット。


・測定レンジを変える
DATA_FORMAT(0x13)のD0,D1で測定レンジを変えられる。
D0 = 0, D1 = 0 : ±2g
D0 = 1, D1 = 0 : ±4g
D0 = 0, D1 = 1 : ±8g
D0 = 1, D1 = 1 : ±16g


・最大分解能モードにする
DATA_FORMAT(0x13)のD3をセット。


・サンプリング周波数を変える。
BW_RATE(0x2C)のD0:D3を変えることで、サンプリング周期を変えられる。


Rate (Hz)  Bandwidth (Hz)    Rate Code
3200         1600          1111
1600         800                    1110
800           400                    1101
400           200                    1100
200           100                    1011
100           50                     1010
50             25                     1001
25             12.5                   1000
12.5           6.25                   0111
6.25           3.13                   0110
3.13          1.56                    0101
1.56           0.78                   0100
0.78           0.39                   0011
0.39           0.20                   0010
0.20           0.10                   0001
0.10           0.05                   0000


・X,Y,Z方向の加速度を取得する。
0x32~0x37に、1軸につき2バイトずつ、データが格納されています。

データは2の補数で格納されています。

それぞれレジスタを読みだして、マスタ側で、加速度に変換してください。




他にもFIFOなど、機能がたくさんあるので、興味がある方はデータシートを参照してください。



それと、このセンサは、傾けても値が変化します。

前後左右に動かしても値が変化するので、平行移動で値が変化しているのか、回転したことで値が変化しているのかが分からなくなるので、どうすればいいのかを検討中です。

データシートを見た限りでは、傾きを検出しないようにする方法が分からなかったです。


加速度センサはどれもこういう感じなのかなぁ...?

ジャイロセンサがあるので、それで補正するようなことをしないといけないんですかね?
大変だなぁ...。

人気の投稿