FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

壁の有無を判断する3

2月16日 追記があります。赤文字が追記です。

今晩は!
雪が降っています!

今回の記事は壁を判定するのラストです。

前回まででAD変換ができるようになりました。
壁判定の最後の敵はノイズです。

センサ値がノイズの影響をもろに受けてしまうと、壁からの距離が同じとき得られるセンサ値がばらついてしまい、しきい値の設定が難しくなってします。ですので、センサ値がばらつかないように対策を施す必要があります。

1つ目の選択肢としては回路を工夫してノイズを抑えるという手があります。
マイクロマウス業界で有名な森永さんのベーシックマウスでは回路の工夫でノイズを除去しています。

2つ目の選択肢として、ソフトウェアを工夫してノイズを抑える手があります。
技術の進化とともに、マイコンの性能が向上したことによって可能になりました。
これは、短い時間でLEDがONの状態からOFFの状態の差分を取ることでノイズの影響を小さくするというものです。

この2つについて、詳しい解説は部室のUSBの電子回路というワードファイルを見てください。

ここでは、ソフトウェアを工夫してノイズの影響を小さくすることを考えてみます。

前回まででAD変換ができるようになりました。
やり方は簡単で、

sen:センサ値
sen_on:LEDがONのときにAD変換した値
sen_off:LEDがOFFのときにAD変換した値

として、

sen = sen_on - sen_off;

とすればよいです。

注意点としては、マイコンがLEDをONにする処理をしてから実際に光が跳ね返ってくるまでにLEDが応答して光を発し、フォトトランジスタが光に応答して電圧がかわるまでには少し時間がかかるので待ち時間を設ける必要があることです。
また、センサーマウント(センサーとフォトトランジスタを固定して覆う)を使わないのであればセンサー同士で干渉する場合があります。どういうことかというと、前の壁を判定するためのLEDの光が、横の壁を判定するためのフォトトランジスタに読まれてしまうなどの事態が起こります。ですので、センサーマウントを作るか、LEDの光が干渉しないようにONとOFFのタイミングを工夫するということをすると良いです。

また、必要なONとOFFの間隔としては1msくらいが良いと思います。
ON・OFFの間隔が1msではノイズ除去が厳しいとのご指摘を頂きました。
マイクロマウスのキットなども販売しているRTのこちらの記事がとても参考になります。

AD変換には演算などの処理に比べて時間がかかるので、この間隔が短すぎると割り込み関数が終わらなくなってしまいます。

これで、壁判定の話は終わりです。
次週は姿勢制御について見ていきましょう。

ではでは($・・)/~~~
スポンサーサイト

壁の有無を判定する2

今晩は!
早いもので今日からは月のような月ですね。

前回壁の有無をどう判定するかを説明しました。
今回はその中で出てきたAD変換のプログラムを見ていきます。
例によって対象にしているマイコンはSH7125です。

では早速。
まずは割り込み関数を用意しましょう。

いきなり本筋とはそれますが、割り込み間隔がどのように設定されるべきなのかを書くことにします。
マイクロマウスで使うAD変換系の割り込みの間隔をかえることで、何が変わっていくのかというと、最終的には制御の頻度になるかと思います。当然ですが、制御頻度が多いほうが制御の精度が上がります。(壁のリファレンス(次週説明)や柱によって制御が悪い働きをするといった状況を除いて)

ここで、例えば180mm進もうで例としてきたように、1ms毎にモーターに送るパルス周期を変えるとします。走行中、機体が右に傾いたならば、左輪を遅くして右輪を早くすると姿勢が直ります。このとき、どれくらい左輪右輪の速度を±するかは壁からの距離に応じて決めて、壁に近いほど速度を大きく変えることで壁があるときに区画の真ん中を走ることができます。これが壁からの距離に応じた制御の正体です。
つまり、壁制御は、進もう2でやった理想速度に壁からの距離に応じた速度を±することです。

制御頻度の話に戻りますが、1ms毎にモーターの速度が決定されているとしましょう。
・10ms毎に壁からの距離に応じた制御をかけたらどうでしょうか。これでは制御がうまくいきません。なぜなら制御が入らない9msの間は機体が傾いたとしても、そのまま進行してしまい、機体が速く動くこの競技では制御が追い付かないからです。
・0.5ms毎に壁からの距離に応じた制御をかけたらどうでしょうか。これはマイコン内で処理が間に合うなら見た目には良さそうに見えますが、2回に1回の計算は無駄になっていてよくないです。無駄です。



こう考えてみると、モーターの速度が決定される前に壁からの制御分も決めてしまうのが良いということが分かるかと思います。そこで僕の記事も、一つの1ms割り込み関数で

1、 理想速度を計算
2、 「制御分の速度:理想速度に±する速度」を壁の距離から計算
3、 「理想速度±制御分の速度」におけるPWMの周期を計算してTGR~に代入

って感じにすることにしましょう。
(これもっと早くに示した方が話が分かりやすかったかな~(;´・ω・)

だいぶ脱線しましたが、以上の理由から用意する割り込み関数は進もうの7でやった、TGR~を計算する割り込み関数と同じで大丈夫です。

ではAD変換のプログラムの話に戻ります。
とりあえず用語の説明をしていきます。

01251.png


・分解能は前回に説明しました。
・チャンネルは直訳すると経路のことですが、ここで言うチャンネルとはAD変換できる端子のことです。SH7125では全部で8チャンネルあり、それぞれAN0~AN7の固有の名前を持っています。
・シングルモードは1つのチャンネルをを単発でAD変換します。
・1サイクルスキャンモードはAN0~AN3またはAN4~AN7を1回ずつAD変換します。
・連続スキャンモードはAN0~AN3またはAN4~AN7を繰り返しAD変換し続けます。
・データレジスタはAD変換された結果が保存されているところです。分解能は10bitなので10bit分のメモリで十分なはずですが、何かしらの大人の事情で16bit分用意されています。上位10bitに値が保存されるので、実際に使うときは下位6bitを捨てます。

大事なのはこのくらいですかね。では設定の手順を見てみましょう。
ここでは単発でAD変換をするシングルモードを設定してみます。

02011.png

この図に書いていないことも含めると、以下の手順を踏むことが必要です。

(手順0、AD変換を使えるようにする。)

手順1、AD変換するチャンネルを変える。但し、ADSTを0にしてから変える。
手順2、ADSTを1にしてAD変換を開始する。
手順3、AD変換完了を待つ。(AD変換は少し時間がかかるので)
手順4、AD変換で得られた値(A/Dデータレジスタに格納されてる)を変数に代入。


次に、これらを詳しく見ていきましょう。



手順0、AD変換を使えるようにする
PWMの設定でもありましたが、マイコンの機能を使えるようにしなければいけません。
PWMの場合はMTU2をスタンバイ解除しましたが、AD変換の場合はAD0とAD1をスタンバイ解除します。ちょっと混乱したかもしれませんが、SH7125ではAD変換ができるAN0~AN7の合計8つのチャンネルが、AN0~AN3までがAD0、AN4~AN7までがAD1に属しています。説明しずらいので図で書いてみると、

01041_20140201004124ee9.png
って感じになってます。
繰り返しますが手順0ではPWMでMTU2を機能解放したのと同様に、AD0とAD1という機能を解放します。以下が具体的な文です。

STB.CR4.BIT._AD0 = 0;
STB.CR4.BIT._AD1 = 0;

さらにシングルモードへの設定は、
AD0.ADCSR.BIT.ADM = 0;
AD1.ADCSR.BIT.ADM = 0;
です。(デフォルトで0になってるのでわざわざ宣言することもないですが。)
その他にもAD変換にかける時間なども設定できますが、デフォルト状態で良いと思いましたので割愛します。


手順1、AD変換するチャンネルを変える。但し、ADSTを0にしてから変える。
ここでは例としてAN5をシングルスキャンモードでAD変換してみます。

まずはADSTを0にします。AN6はAD1に属して、ADSTビットはADCRレジスタに属しているので

AD1.ADCR.BIT.ADST = 0;

となります。
次にAD変換するチャンネルを変えます。AN5はAN1のチャンネル1です。チャンネルの変更はADCSRレジスタに属しているCHビットを変えることで行われ、

AD1.ADCSR.BIT.CH = 1;

となります。




手順2、ADSTを1にしてAD変換を開始する
ここまでの手順を行うと、ADCRレジスタのADSTビットに1を書きこむと、ソフトウェア要因ということでAD変換が開始されます。

AD1.ADCR.BIT.ADST = 1;



手順3、AD変換完了を待つ
AD変換が終わる前に格納されているデータを読むと、前回のデータを読み込むことになってしまいます。なのでAD変換を開始したら、AD変換の完了を待ってから格納されたデータを読む必要があります。
これに使える便利なフラグがあります。ADCSRレジスタのADFビットはAD変換が完了すると自動的に1になるので、

while(AD1.ADCSR.BIT.ADF == 0);

このようにwhile分を入れることでAD変換の終了を待つことができます。
しかし、このままにしておくと次のAD変換でADFは1になったままなので
AD1.ADCSR.BIT.ADF = 0;
を直後に入れて、次回のAD変換に準備しておきます。




手順4、AD変換で得られた値を変数に代入。
AD変換によって得られた値はADデータレジスタに保存されています。ADデータレジスタは、ADDR0~ADDR7まであり、AN0ならADDR0、AN6ならADDR6のようにそれぞれ対応しています。
さらに上で書いたように分解能10bitに対してレジスタの大きさが16bitなので下位6bitを捨てます。これにはシフト演算子を使います。要は右に6ビットシフトさせて、下位6ビットを塗りつぶす感じです。例として右センサの値をr_senとおくと、今回のAN5をAD変換する例では、

r_sen = AD1.ADDR5 >> 6;

となります。

天下り的でしたが、以上がAD変換の手順です。まとめると、

初期設定:
// スタンバイ解除
STB.CR4.BIT._AD0 = 0;
STB.CR4.BIT._AD1 = 0;
// シングルモード
AD0.ADCSR.BIT.ADM = 0;
AD1.ADCSR.BIT.ADM = 0;

割り込み内:
AD~.ADCR.BIT.ADST = 0;
AD~.ADCSR.BIT.CH = ~;
AD~.ADCR.BIT.ADST = 1;
while(AD~.ADCSR.BIT.ADF == 0);
AD~.ADCSR.BIT.ADF = 0;
~~ = AD~.ADDR~ >> 6;

のようになります。ということで今週はここまで。

次週は今回できなかったパルス発光の話をします。
恐らく次で壁の判定の話は完結になると思います~

ではまた来週(*´ω`)

壁の有無を判定する1

こんにちは!
前回までで好きな距離を任意の速度で進めるようになりました。
具体的には

・任意の速度でモーターを回せる
・MTU割り込みを設定できる

という前提を獲得しています。

そしてついにタイトルが変わりました!
今回からは姿勢制御や迷路探索の基本となる、壁の有無を判定できるという前提を獲得しに向かいます。

そのために知らなければいけないことは、

・壁からの距離はどうやって認識しているのか →LEDとPTの話
・得た情報をマイコンはどう認識しているのか →AD変換の話
・得た情報をどう使うか →壁関連のプログラムの話

となります。
この構成で話を進めるつもりですが、前回までのように必要が出たらその度に寄り道していこうと思います~

では、壁からの距離をどう認識するかの話
これにはLEDとフォトトランジスタ(PT)を使うのが一般的かと思います。
これの原理等は昨年の夏くらいに講義をしました。部室のUSBに“電子回路”というWordファイルがありますのでその資料を見てもらえればと思います。簡単に説明すると、ノイズを軽減するようにLEDをパルス発光させる。LEDから出た光が壁に反射し、壁から反射してきた光量に応じてPTを通る電流が変わり、マイコンに来る電圧が変わる。(うーむ分かりづらいか)
つまり、壁からの距離を電圧の大小という形に替えて、マイコンで認識するということです。

次に壁からの距離を変換して得た、電圧の大小をマイコンはどうやって認識するかという話。
これには、マイコンの機能の1つであるAD変換というものを行います。
AD変換はアナログ・ディジタル変換のこと。つまりアナログの情報をディジタルの情報に変換するということです。
例えばSH7125のAD変換について見てみると、こんな説明が書いてあります。
01251.png

分解能 10bitというところに注目してください。
AD変換で言う分解能とは、どれくらいの細かさでアナログ情報を表現できるかということです。
2^10は1024なので、SH7125では0~1024の値でアナログ情報である電圧が表現されるということになります。

では具体例として、720という値は何Vに相当するか考えてみましょう。
これを求めるためにはアナログ電源電圧が何Vになっているかという情報が必要となります。秋月で買うマイコンボードだとマイコンのVCC(電源電圧を示す)という端子に5Vを繋いだ瞬間AVCC(アナログ電源電圧)も同じ電圧の5Vに設定されるようになっています。しかし、AVCCをVCCと違う値にするということもできますので、頭の片隅に置いてもらえればと思います。
さて、AVCCの値で何が決まるかという話に戻ります。
例えばAVCCが5Vのとき、AD変換の最高値は5Vということになります。先ほどの分解能10bitの例では、1024が5Vに相当するということです。
ですので、720という値は 1024:5=720:x で x=3.5 くらいと分かり、720は3.5Vくらいを指しているということになります。

このようにAD変換を行うことでマイコンに電圧が何V来ているかということが分かり、それを使って壁からの距離を判定しているということになります。
このことから分解能が高いとアナログ情報をより正確にディジタル情報にできるということが分かるかと思います。

それでは、AD変換で得た数値を使ってどのように壁の有無を判断するか考えましょう。
壁があるってことは、壁がないときよりも光の跳ね返りが大きいので、得られる数値が大きくなることが想像できるかと思います。これを利用して、ある値よりも大きな値を得た時、壁があると判断します。
ここで言う、ある値が部室などでよく耳にしたであろう 閾値(しきいち) です。
閾値以下の値:壁なし 閾値以上の値:壁有 となる重要な値のため、勘で決めたりせず実際に値をPCに出力して決める必要があります。

まとめ
LEDとPTで壁からの距離を電圧に変換する。
マイコンでその電圧を読み取って数値にする。(プログラムは次週)
閾値を決めることで壁の有無を判断する。

って感じです。
次週はLEDをパルス発光させる話と、AD変換を行うためのプログラムについて見ていきましょう!
ではでは( ..)φ
時計
カテゴリ
最新記事
12月14日開始
RSSリンクの表示
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。