今回は加速度センサを利用してみます。
今はスマートフォンにも内蔵されていて、縦横の画面の切り替え検出や、ゲームなどのアプリでも利用されていますね。加速度センサはスマートフォンを始めとして日常のさまざまなデバイスに利用されていて、アイデア次第で面白い使い方ができるセンサとなっています。
今回の電子工作レシピ
完成までの時間目安:90分
必要なパーツ
- Arduino本体(Arduino Uno R3)http://www.switch-science.com/catalog/789/
- ブレッドボード http://www.switch-science.com/catalog/313/
- 3軸加速度センサモジュール (KXR94-2050 http://akizukidenshi.com/catalog/g/gM-05153/)
- マイクロサーボ9G (SG90 http://akizukidenshi.com/catalog/g/gM-08761/)
加速度センサとは?
加速度センサとは、簡単に表すと傾き・衝撃・振動などといったセンサの動きの状態を検出することができるセンサです。今回利用する3軸加速度センサ KXR94-2050はXYZ平面の3軸を検出することができ、それぞれの軸に対して内部構造で加速度を検出することができる仕組みとなっています。ロームグループKionixの加速度センサが変換基板上にハンダ付けされているタイプなので、すぐブレッドボードに刺して利用することが可能です。
実際にセンサ内部の加速度を検出する方法には光を利用した光学式、バネをつかった振動式、電位の移動を利用した静電容量式などさまざまな方法がありますので、気になる方は詳しくはWikipediaの加速度計などの項目を参照してください。
加速度センサを使ってみる前に〜スマートフォンでの利用
さっそく加速度センサをArduinoで使ってみる前に、まずは加速度センサがどのようなものか勉強しておきましょう。加速度センサが内蔵されているスマートフォンをお持ちであれば、下記のURLをスマートフォンのブラウザで開くことで端末に内蔵されている加速度センサの状態を見られます。
加速度センサのサンプル
※HTML5の加速度が取得できるブラウザ/端末OSで利用が可能です(参考仕様:Androidの場合OSが4.0以上、iPhoneではiOS4.2.1以上)
このサンプルは、ブラウザ上で端末に内蔵されている、加速度センサのXYZ軸の数値を取得できます。この数値を分析することで、端末が今どのような傾き・動きをしているのかを検出することができるので、それを利用してアプリやゲームに生かすことが可能です。
Arduinoで加速度センサを利用してみる
では次にArduinoで利用してみましょう。センサを動かすために必要な電源電圧も2.5V〜5.25Vなので、Arduino UNOのVcc(5V)出力で直接まかなうことが可能です。
今回利用するセンサでは、8本端子があり、図2のような役割を持っています。
- VDD – 電源電圧
- PSD – センサ値を表示する為にVDDに接続
- GND – グランド
- Parity – 今回は利用しません
- SelfTest – 今回は利用しません
- X軸のデータ
- Y軸のデータ
- Z軸のデータ
//******************************** //加速度センサの値を取得するプログラム //******************************** void setup() { // シリアルモニターの初期化をする Serial.begin(9600) ; } void loop() { long x , y , z ; x = y = z = 0 ; x = analogRead(3) ; // X軸 y = analogRead(4) ; // Y軸 z = analogRead(5) ; // Z軸 Serial.print("X:") ; Serial.print(x) ; Serial.print(" Y:") ; Serial.print(y) ; Serial.print(" Z:") ; Serial.println(z) ; delay(50) ; }
このプログラムを動かすと、平常時のセンサの数値が表示されます。
この時は平らな机の上に置きました(いわゆる角度0度)。X軸では安定時498、Y軸は536、Z軸は750の数値が表示されていますね。
傾きを読み取ってみる
図4の数値を例に、センサの傾きを計測してみます。傾きはセンサの構造について簡単に説明すると、センサの中で構成される部品それぞれにかかる重力の状態を検出することで、傾きを検出できます(詳しくは調べてみてください)。傾きの状態を示す単位はgravity=重力のgです。単純に傾きを知りたい場合、センサで表示されるXYZ軸のうち、X軸を例にとると図5のように傾きの状態を計測できます。
※ちなみに物理の話になりますが、地球上の全ての物体は標高0mで静止状態の場合1Gがかかっています。いわゆる万有引力の法則、というやつですね。正確には、標高や、地球の位置(地球の遠心力で北極と南極にいくと軽くなる)などの様々な影響を受けるため、数値にずれが生じます。
数値は277(-90度)〜728(90度)まで表示されていますね。通常時は500前後なので、センサの範囲は277(-90度)〜500(0度)〜728(90度)となります。
ここから角度を求めるには、比例式を利用します。
1度あたりのセンサ値 = (最大値 – 最小値) /180
(724 – 277)/180 = 2.48 ← 1度当たりのセンサ値角度を求める
角度 = (現在のセンサ値 – 最小値)/2.48 – 90
Arduinoで表示されている数値から角度を算出するには上記の式を用いることで算出できます。※センサにはノイズがあるため、センサごとにこのような形で相関係数を算出の必要があります。また、ブレッドボードにささっている状態が既に傾いていたりすると正確な値がでなかったりしますのでそれも気をつけてみてください。
次に加速度センサからの数値を安定させるため、プログラムを改良してみます。Arduinoのloop内で加速度センサの値をfor文で複数回(ここでは50回)取得して平均することでセンサの値を安定させます(図7)。
//******************************** //加速度センサの値を取得するプログラム2 //******************************** void setup() { // シリアルモニターの初期化をする Serial.begin(9600) ; } void loop() { int i ; long x,y,z; //50回センサ値を読み込んで平均を算出 x=y=z=0; for (i=0 ; i < 50 ; i++) { x = x + analogRead(3) ; // X軸 y = y + analogRead(4) ; // Y軸 z = z + analogRead(5) ; // Z軸 } x = x / 50 ; y = y / 50 ; z = z / 50 ; int rotateX = (x-277)/2.48 - 90; //角度を求める式 Serial.print("X:") ; Serial.print(x) ; Serial.print(" ") ; Serial.print(rotateX) ; int rotateY = (y-277)/2.48 - 90; Serial.print(" Y:") ; Serial.print(y) ; Serial.print(" ") ; Serial.print(rotateY) ; delay(50) ; }
これで、加速度センサの傾きの角度も表示することができました。
応用してみる〜水平カメラ台デバイスの作成
この加速度センサを用いて応用してみます。ぱっと思いついたのが、傾きを検出して、常に水平を保つ台を作ってみたいと思います。どんな傾いた状況でも、水平が保てるときっといいことがあるはずです!(笑)。
簡単に思いつくところだと、カメラで景色などを撮影する際にあとで撮影した画像を確認したら水平がやや傾いていた、なんてことがあったりします(撮影が下手なだけかもしれませんが…)。また、某漫画のように車になみなみに水を注いだコップを置いて峠を走る必要があったりと…いずれにせよ、そのような状況でも常に水平を保ってくれるデバイスを作ってみたいと思います。
さっそく作ってみた
さっそく加工しやすい素材で作ってみました。傾けてもある程度水平を保っていますね。この作例は、次回詳しく解説します。
基本的な仕様は実に単純です。XY軸それぞれに傾きを検出した角度と同じ分だけ逆にサーボモータを傾けるだけで、上に置かれている台は常に水平を保てます。
サーボモータのスピードや、加速度センサのノイズの誤差などで若干傾きが大きくなってしまう場合もありますが、その場合はプログラム側の式や、デバイスの筐体の素材を曲がらない固いものに変更するなどの工夫をしてみてください。
まとめ
今回、加速度センサの基本の扱い方から、簡単な応用例まで試してみました。次回では、さらに今回作成した水平カメラデバイスのモックアップをバージョンアップさせてみたいと思います。