- 追加された行はこの色です。
- 削除された行はこの色です。
#navi(NQC入門)
(すみません、まだ作成中です)
RCXは赤外線を使用した通信機能を持っています。
このセクションでは、この通信機能を使って2台のRCXの動きを連係させてみましょう。
* 7.1 メッセージの送受信 [#w198ad4d]
RCX は 0 〜 255 までの値をメッセージとして送受信することができます。
相手のRCXにメッセージを送信するためには
//
SendMessage(i); // ただし i は 0〜255 の数字
//
というコマンドを使います。
一方、受信側のロボットでは、最後に受信した値を Message() で得ることができます。
そして
ClearMessage();
という命令を使えば、 Message() の値を 0 に初期化することができます。
したがって、もし一方が 0 というメッセージを送った場合、他方ではメッセージを受け取った
ことで Message() の値が 0 になったのか、あるいはクリアして 0 になったのかわからないので
0 を送ることはやめましょう。
例:ロボット1のタッチセンサ1が押されるとロボット2のモータAが正回転し、
ロボット1のタッチセンサー2が押されるとロボット2のモータがストップするプログラム。
うまく送信できた場合にはピッ、失敗した場合にはブッというサウンドを鳴らす。
(片方のロボットをリモコンの送信器のように使った例です)
// 送信側プログラム
//
#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) ) {
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) ) {
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 を受信したときにはストップ
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) <= 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入門)