赤外線反射センサで地面の白と黒を判断するので、センサの値がどのように変化するのかを確認します。
GCC Developer Liteを起動して、赤外線反射センサの値を表示するプログラムを作成します。
#include <fd.h> void main (void) { uint8_t GroundData; fd_SetBeepCondition (FD_BEEP_MMI | FD_BEEP_PACKETERR | FD_BEEP_LOWVOLTAGE | FD_BEEP_BOOTUP); fd_SetUVThreshold (7.4); DX_ChangeBaudrate (1000000); while (!fd_rx_buff ()) { DX_ReadByteData (100, 28, &GroundData, 10, NULL); fd_printf ("ground: %3d\r", GroundData); fd_Wait (10); } }
DX_ReadByteDataで赤外線反射センサの値を取得し、fd_printfで値を表示しています。
ファイル名をIRSensor.cとして保存し、プログラムをビルドして、実行してみましょう。
赤外線反射センサと地面の距離が近ければ地面の色に関わらず値は255となっているのではないでしょうか。距離を離すと地面の色によりセンサの値が変わることが分かります。
AX-S1を地面から離した状態でロボットにするにはバランスも悪く、AX-S1の固定方法も難しいため、センサ自体の出力を抑えることにします。
先ず赤外線反射センサの原理を説明します。
AX-S1を見ると3方向にそれぞれ2つの丸い物が並んで付いています。その2つの丸いものを良く見ると片方は黒く、片方は透明です。
黒い方から赤外線が照射されます。照射された赤外線は直進し、その先に物体があると反射します。
反射して戻ってきた赤外線の量を透明の方が測定します。
これによって、対象との距離や色を判別します。
この測定された赤外線の量を0~255の値に変換した値を、今私たちは見ています。
跳ね返ってくる赤外線の量が多すぎて飽和してしまっているのであれば、照射する赤外線の量を減らせば良いのです。
では、出力を抑えるにはどうすれば良いのか、物理的に赤外線照射部を隠すのが一番簡単ではないのでしょうか。
黒いビニールテープで少しだけ隙間残して赤外線照射部を隠してみました。
どれくらい隠すかは、赤外線反射センサの値を見ながら調節することになります。
上図の場合、白い地面では約120、黒い地面では約20という値になりました。
これで白い地面の上にいるか、黒い地面の上にいるかを判断することができるようになりました。
ライントレースは黒いラインに沿って進みます。 赤外線反射センサは黒いラインの上から始まりますので、もし白い地面を検知したら黒いラインへ戻るようにタイヤを動かすことで、ライントレースすることが可能です。
図のように黒いラインから右に外れたら左へ、左に外れたら右へ進めば良いのですが、残念ながら赤外線反射センサが1つしかありませんので、実は右に外れたのか、左に外れたのかを判断することができません。
勿論赤外線反射センサが2つあれば判断することは可能ですが、今回は1つしかありませんの別の方法でライントレースすることを考えます。
赤外線反射センサ1つでライントレースをする方法としては、「黒いラインをトレース」するのではなく、「黒と白の境界線をトレース」すれば良いのです。 例えば左側の白い地面は忘れ、黒いラインの右側の境界線をトレースするとします。
図のように地面が白い時は左に、黒い時は右に進むことで黒と白の境界線をトレースすることができます。
赤外線の照射量を調整するで、赤外線反射センサの値は白い地面では約120、黒い地面では約20と計測できましたので、白い地面と黒い地面の閾値は中間の値(70)としますが、赤外線の照射量の抑止程度によりセンサ値は異なりますので、ここでのセンサの値は参考にしないでください。
#include <fd.h> // アクチュエータ操作 void Direction (short left, short right) { fd_DXSetSpeed (1, -right); fd_DXSetSpeed (2, left); } // メイン関数 void main (void) { uint8_t GroundData; fd_SetBeepCondition (FD_BEEP_MMI | FD_BEEP_PACKETERR | FD_BEEP_LOWVOLTAGE | FD_BEEP_BOOTUP); fd_SetUVThreshold (7.4); DX_ChangeBaudrate (1000000); fd_DXSetEndlessTurn (1, true); fd_DXSetEndlessTurn (2, true); while (!fd_GetPB () && !fd_rx_buff ()) { DX_ReadByteData (100, 28, &GroundData, 10, NULL); fd_printf ("ground: %3d\r", GroundData); if (GroundData < 70) { // 黒検知 Direction (400, 100); // 右斜め前方 } else { Direction (100, 400); // 左斜め前方 } fd_Wait (10); } Direction (0, 0); // 停止 }
赤外線反射センサの値が閾値未満であれば地面を黒として、右斜め前方へ進みます。センサの値が閾値以上であれば地面を白として、左斜め前方へ進みます。
このプログラムでは急なカーブやループには対応できず、ラインを逸脱したり見当違いの方向へ走ってしまう可能性がありますので、プログラムの更なる改造を行います。