下記ファイルダウンロードして,分割コンパイルを行えるように整理せよ.モータ駆動関係(タイマとポート含む)の関数のファイルをmotor.c,そのためのヘッダファイルをmotor.hとして作成せよ.
これらのファイルをUSBメモリ上の新規フォルダに保存し,今回新たにプロジェクトを作成する.これまでのプロジェクト作成と異なり,プロジェクトに追加するC言語のソースファイルとして「main.c」「sensor.c」「motor.c」の3回追加する必要がある.
このプロジェクトが最終プロジェクトとなる.以降,最後までこのプロジェクトを修正して課題をこなせ.ただし,毎週バックアップを必ずとること.途中で動かなくなっても,前の週の段階まではすぐ戻れるようにしておくこと.
#define UPPERLIMIT 0x80 #define LOWERLIMIT 略 #define そのほかの定数 //motor.cの中で使用する定数など void initMotor(void); int driveMotor(int targetR, int targetL); int turnRight(int sensor_thold); そのほか,関数プロトタイプのリスト.motor.cの中にある関数全部について記述
main.cを変更して,停止状態から加速して直進するが,前方センサに反応があったときに180度回転して元に戻るようにせよ.センサーのチェックには,sensor.cの中にすでに用意されているcheckSensor()が使用できる.checkSensorは,センサに反応があるかどうかだけを返す関数である.詳細は下記ヒントの説明文を読むこと.checkSensor()には,反応があればLEDが点灯する機能がすでに組み込まれている.
このためには次の変更も行わないとできない.
最初にwait()のプロトタイプに次のように引数を増やして,センサーを利用する場合と,しない場合を切替えられるようにする.
int wait(int msec, int sensor_thold);
このsensor_tholdには,0から1023を入れる.この値は前方センサーの基準値で,この基準値よりも大きいときにセンサーが「反応」したものとみなす.つまり大きい値→近い距離,小さい値→遠い距離である.
センサー値の範囲は0から250〜300程度(ロボットによって違う)なので,0だと必ずセンサーが反応し,1024以上(実際は300以上)だとまったくセンサが反応しなくなることを意味する.
waitの引数を追加したので,waitを呼出している部分も変更する.(プログラム中に複数存在しているはず).
wait(300); → wait(300, 200); //センサーチェックを200でする場合 → wait(300, 1024); //しない場合
このようなフラグは,プログラムを読むひとにはわかりづらいので,次のように定数を使用する.
#define SENSOR_NEAR 200 #define SENSOR_NOCHECK 1024 (中略) 呼び出すとき: wait(300, SENSOR_NEAR); //またはwait(300, SENSOR_NO_CHECK);
SENSOR_NOCHECKが1024なのは,センサー値が10bitのA/D変換によって0〜1023の値を持つ可能性があるため,それ以外の値として選択されたものである.
wait関数の本体も次のように書き換える
int wait(int msec, int sensor_thold){ ※5ミリ秒に一回実行される部分 { ※ここでセンサーの読み込み そして,読み込んだ値を判定すること センサーに反応あり → return -1; センサーに反応なし → そのまま続行 指定時間が経過したかどうかのチェック(前回作成した部分) 経過していたらbreak; } return 0; //センサーに反応なしのまま,指定待ち時間が経過した時だけ,ここまで到達 }
int checkSensor(int sensor_thold);
checkSensorに渡す引数には,センサの基準値(sensor_thold)を指定する.例えば「150」を指定するように使用するには,次のように書く.
int kekka; kekka = checkSensor(150);
こうすると,センサ値150を基準として,それよりもセンサが大きい値(壁から近い)の時に,「反応あり」とする.右センサ・前センサ・左センサのすべてに対して基準値との比較で反応ありかどうかを調べ,次のLEDを点灯する.
前センサ ● ●課題11で使用 左センサ● ●右センサ
LEDに対応して次のような返値を返し,変数kekkaに格納する.
これは,前方のセンサに障害物を検知した場合ビット1に1をセットし,右センサの場合にビット0,左をビット2とする.すると次のように3ビットで表せる0から7の値で,三つのセンサが反応したかしないかの組み合わせを表現できる.
checkSensorを呼び出した後,得られた返値kekkaを使って,例えば次のように前センサに反応があった時の処理を書くことができる.
if(kekka == 2) { /* 前センサに反応,左右にはなし,の場合にここを実行する */ }
waitと同様にforward()を次のように書き換え,センサーの基準値を指定できるようにしておくこと.
int forward(int msec, int sensor_thold);
(1)の段階で,forward()本体の中でwait()を呼び出している部分を修正してあるはずだが,そのwaitの返値を判断して,forward自身の返値を制御する.
int turnRound(int sensor_thold); //180度回転
作り方は課題08のturnLeft()とほとんど同じである.ただwaitする秒数をうまく調整して90度でなく180度回転させる点と,wait()やforward()と同様に,センサーの基準値を指定できるようにすること.