#nomenubar #navi(NQC入門) RCXは赤外線を使用した通信機能を持っています。 この通信機能を使うことで2台以上のRCXを連携させることができます。 目次 #contents * 7.1 メッセージの送受信 [#w198ad4d] RCX は 0 〜 255 までの値をメッセージとして(合計8個の0と1を同時に)送受信することができます。 メッセージを送信するためには // SendMessage(i); // ただし i は 0〜255 の数字 // という命令を使います。 一方、受信側のロボットでは、最後に受信した値を Message() で得ることができます。 そして ClearMessage(); という命令を使えば、 Message() の値を 0 に初期化することができます。 したがってもし一方が 0 というメッセージを送ってしまった場合、 受信側のロボットはメッセージを受け取ったことで Message() の値が 0 になったのか、 クリアして 0 になったのか、単純には判断できません。 ですので、0 は送らないようにしましょう。 では、例としてロボット1のタッチセンサ1が押されるとロボット2のモータAが正回転し、 ロボット1のタッチセンサー2が押されるとロボット2のモータがストップするプログラムを考えましょう。 (片方のロボットをリモコンの送信器のように使った例です) // 送信側プログラム // #define SIGNALON 11 // モータ回転のためのメッセージ #define SIGNALOFF 12 // モータ停止のためのメッセージ (SIGNALONと違うものにする) task main () { SetSensor(SENSOR_1,SENSOR_TOUCH); SetSensor(SENSOR_2,SENSOR_TOUCH); while (true) { // センサー1だけが押されているときは SIGNALON(=11) を送信する while ( (SENSOR_1 == 1) && (SENSOR_2 == 0) ) { SendMessage(SIGNALON); } // センサー2だけが押されているときは SIGNALOFF(=12) を送信する while ( (SENSOR_1 == 0) && (SENSOR_2 == 1) ); while ( (SENSOR_1 == 0) && (SENSOR_2 == 1) ) { SendMessage(SIGNALOFF); } } } // 受信側のプログラム // #define SIGNALON 11 // モータ回転のためのメッセージ #define SIGNALOFF 12 // モータ停止のためのメッセージ task main () { ClearMessage(); // Message()の値を0に初期化 while (true) { until (Message() == SIGNALON); // 11 を受信するまで待つ OnFwd(OUT_A); // Aのモータを正回転 until (Message() == SIGNALOFF); // 12 を受信するまで待つ Off(OUT_A); // Aのモータをストップ } } ★ 練習問題~ 上の例で送信側のタッチセンサを一つに減らし、そのタッチセンサが一回反応する度に受信側のロボットのモータが ON と OFF を繰り返すようにプログラムを変更しなさい。 * 7.2 返事もさせる [#b4580e4a] 上の例では、送信側のロボットはメッセージを相手側にうまく送信できたどうか自分ではわかりません。 そこでこの節では、うまく送信できた場合にはピッ、失敗した場合にはブッというサウンドを鳴らす ようにプログラムを改良してみましょう。 // 送信側プログラム // #define SENDTIME 200 // 一回のメッセージを送信する最大時間 #define SIGNALON 11 // モータ回転のためのメッセージ #define SIGNALOFF 12 // モータ停止のためのメッセージ (SIGNALONと違うものにする) task main () { SetSensor(SENSOR_1,SENSOR_TOUCH); SetSensor(SENSOR_2,SENSOR_TOUCH); while (true) { // センサー1だけが押されるまで待つ until ( (SENSOR_1 == 1) && (SENSOR_2 == 0) ); ClearTimer(0); // 時間測定開始 ClearMessage(); // この時点で Message() は 0 になる // 2秒間あるいは相手からの返事(1)がくるまで 11 を送り続ける while ( (Message() != 1) || (FastTimer(0) < SENDTIME) ) { SendMessage(SIGNALON); } if (Message() == 1) { PlaySound(SOUND_CLICK); // 送信に成功したときはピッと鳴らす } else { PlaySound(SOUND_LOW_BEEP); // 送信に失敗したときはブッと鳴らす } Wait(50); // 0.5秒休止 // センサー2だけが押されるまで待つ until ( (SENSOR_1 == 0) && (SENSOR_2 == 1) ); ClearTimer(0); ClearMessage(); // 2秒間あるいは相手からの返事(2)がくるまで 12 を送り続ける while ( (Message() != 1) || (FastTimer(0) < SENDTIME) ) { SendMessage(SIGNALOFF); } if (Message() == 2) { PlaySound(SOUND_CLICK); // 送信に成功したときはピッと鳴らす } else { PlaySound(SOUND_LOW_BEEP); // 送信に失敗したときはブッと鳴らす } Wait(50); // 0.5秒休止 } } // 受信側のプログラム // #define SIGNALON 11 // モータ回転のためのメッセージ #define SIGNALOFF 12 // モータ停止のためのメッセージ task main () { ClearMessage(); // Message()の値を0に初期化 while (true) { until (Message() == SIGNALON); // 11 を受信するまで待つ SendMessage(1); // 返事として 1 を送る OnFwd(OUT_A); // Aのモータを正回転 until (Message() == SIGNALOFF); // 12 を受信するまで待つ SendMessage(2); // 返事として 2 を送る Off(OUT_A); // Aのモータをストップ } } //他の例: // // // 送られたメッセージに従って左右に回転するロボットのプログラム // // #define turn_left OnRev(OUT_A);OnFwd(OUT_C); // #define turn_right OnFwd(OUT_A);OnRev(OUT_C); // #define stop_turning Off(OUT_A+OUT_C); // // task main() // { // while (true) // { // ClearMessage(); // Message() を 0 に設定 // until (Message() != 0); // Message() に 0 以外の値が入るまで待つ // // if ( Message() == 1 ) {turn_left; } // 1 を受信したときには左回転 // if ( Message() == 2 ) {turn_right; } // 2 を受信したときには右回転 // if ( Message() == 3 ) {stop_turning;} // 3 を受信したときにはストップ // } // } // // // メッセージを送信するプログラム // // task main() // { // // 相手が反対側を向いていると受信できないので // // 5 秒間メッセージを送り続ける // // ClearTimer(0); // while ( Timer(0) <= 50 ) { SendMessage(1); } // 最初の 5秒間 1 を送信する // while ( Timer(0) <= 100 ) { SendMessage(2); } // 次の 5秒間 2 を送信する // while ( Timer(0) <= 150 ) { SendMessage(3); } // さらに 5秒間 3 を送信する // // // SendMessage の後に Wait(50); くらいを挿入すると電池が節約できる? // } #navi(NQC入門)