#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入門)

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS