Программирование LEGO NXT роботов на языке NXC - Коммуникации между роботами — различия между версиями

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск
(Создана новая страница размером =Коммуникации между роботами= If you own more than one NXT this chapter is for you (though you can still communic...)
 
Строка 9: Строка 9:
 
The NXT that starts the connection is called Master, and can have up to 3 Slave devices connected on lines 1,2,3;
 
The NXT that starts the connection is called Master, and can have up to 3 Slave devices connected on lines 1,2,3;
 
Slaves always see the Master connected on line 0. You can send messages to 10 mailboxes available.
 
Slaves always see the Master connected on line 0. You can send messages to 10 mailboxes available.
==Master – Slave messaging==
+
==Отправка сообщений мастер-подчиненный==
 
Two programs will be shown, one for the master, one for the slave. These basic programs will teach you how a
 
Two programs will be shown, one for the master, one for the slave. These basic programs will teach you how a
 
fast continuous stream of string messages can be managed by a two-NXT wireless network.
 
fast continuous stream of string messages can be managed by a two-NXT wireless network.
Строка 80: Строка 80:
 
numbers, without knowing that all the messages sent will be lost, because no one is listening on the other side.
 
numbers, without knowing that all the messages sent will be lost, because no one is listening on the other side.
 
To avoid this problem, we could plan a finer protocol, with delivery acknowledgement.
 
To avoid this problem, we could plan a finer protocol, with delivery acknowledgement.
==Sending numbers with acknowledgement==
+
 
 +
==Отправка чисел с подтверждением==
 
Here we see another couple of programs: this time master sends numbers with
 
Here we see another couple of programs: this time master sends numbers with
 
SendRemoteNumber(conn,queue,number) and stops waiting for slave ack (until cycle, inside which we
 
SendRemoteNumber(conn,queue,number) and stops waiting for slave ack (until cycle, inside which we
Строка 152: Строка 153:
 
}
 
}
  
==Direct commands==
+
==Прямые команды==
 
There's another cool feature about Bluetooth communication: master can directly control its slaves.
 
There's another cool feature about Bluetooth communication: master can directly control its slaves.
 
In the next example, the master sends the slave direct commands to play sounds and move a motor; there is no
 
In the next example, the master sends the slave direct commands to play sounds and move a motor; there is no

Версия 08:27, 20 мая 2009

Коммуникации между роботами

If you own more than one NXT this chapter is for you (though you can still communicate data to the PC, having a single NXT). Robots can communicate with each other via Bluetooth radio technology: you can have multiple robots collaborate (or fight with each other), and you can build a big complex robot using two NXTs, so that you can use six motors and eight sensors. For good old RCX, it is simple: it sends an InfraRed message and all robots around receive it. For NXT it's a whole different thing! First, you must connect two or more NXTs (or NXT to PC) with the onbrick Bluetooth menu; only then you can send messages to connected devices. The NXT that starts the connection is called Master, and can have up to 3 Slave devices connected on lines 1,2,3; Slaves always see the Master connected on line 0. You can send messages to 10 mailboxes available.

Отправка сообщений мастер-подчиненный

Two programs will be shown, one for the master, one for the slave. These basic programs will teach you how a fast continuous stream of string messages can be managed by a two-NXT wireless network. The master program first checks if the slave is correctly connected on line 1 (BT_CONN constant) using BluetoothStatus(conn) function; then builds and sends messages with a M prefix and a growing number with SendRemoteString(conn,queue,string), while receives messages from slave with ReceiveRemoteString(queue,clear,string) and displays data. //MASTER

  1. define BT_CONN 1
  2. define INBOX 1
  3. define OUTBOX 5

sub BTCheck(int conn){ if (!BluetoothStatus(conn)==NO_ERR){ TextOut(5,LCD_LINE2,"Error"); Wait(1000); Stop(true); } } task main(){ string in, out, iStr; int i = 0; BTCheck(BT_CONN); //check slave connection while(true){ iStr = NumToStr(i); out = StrCat("M",iStr); TextOut(10,LCD_LINE1,"Master Test"); TextOut(0,LCD_LINE2,"IN:"); TextOut(0,LCD_LINE4,"OUT:"); ReceiveRemoteString(INBOX, true, in); SendRemoteString(BT_CONN,OUTBOX,out); TextOut(10,LCD_LINE3,in); TextOut(10,LCD_LINE5,out); Wait(100); i++; } } The slave program is very similar, but uses SendResponseString(queue,string) instead of SendRemoteString because slave must can send messages only to its master, seen on line 0.

//SLAVE

  1. define BT_CONN 1
  2. define INBOX 5
  3. define OUTBOX 1

sub BTCheck(int conn){ if (!BluetoothStatus(conn)==NO_ERR){ TextOut(5,LCD_LINE2,"Error"); Wait(1000); Stop(true); } } task main(){ string in, out, iStr; int i = 0; BTCheck(0); //check master connection while(true){ iStr = NumToStr(i); out = StrCat("S",iStr); TextOut(10,LCD_LINE1,"Slave Test"); TextOut(0,LCD_LINE2,"IN:"); TextOut(0,LCD_LINE4,"OUT:"); ReceiveRemoteString(INBOX, true, in); SendResponseString(OUTBOX,out); TextOut(10,LCD_LINE3,in); TextOut(10,LCD_LINE5,out); Wait(100); i++; } } You will notice that aborting one of the programs, the other will continue to send messages with growing numbers, without knowing that all the messages sent will be lost, because no one is listening on the other side. To avoid this problem, we could plan a finer protocol, with delivery acknowledgement.

Отправка чисел с подтверждением

Here we see another couple of programs: this time master sends numbers with SendRemoteNumber(conn,queue,number) and stops waiting for slave ack (until cycle, inside which we find ReceiveRemoteString); only if slave is listening and sending acks, the master proceeds sending the next message. Slave simply receives number with ReceiveRemoteNumber(queue,clear,number) and sends the ack with SendResponseNumber. Your master-slave programs must agree on the common code for the ack, in this case, I choose the hex value 0xFF. The master sends random numbers and waits for slave ack; every time it receives an ack with the right code, the ack variable must be cleared, otherwise the master will continue sending without new acks, because the variable got dirty. The slave checks continuously the mailbox and, if it is not empty, displays the read value and sends an ack to the master. At the beginning of the program, I choose to send an ack without reading messages to unblock the master; in fact, without this trick, if the master program is started for first, it would hang even if we start slave later. This way the first few messages get lost, but you can start master and slave programs in different moments without the risk of hanging.

//MASTER

  1. define BT_CONN 1
  2. define OUTBOX 5
  3. define INBOX 1
  4. define CLEARLINE(L) \

TextOut(0,L," "); sub BTCheck(int conn){ if (!BluetoothStatus(conn)==NO_ERR){ TextOut(5,LCD_LINE2,"Error"); Wait(1000); Stop(true); } } task main(){ int ack; int i; BTCheck(BT_CONN); TextOut(10,LCD_LINE1,"Master sending"); while(true){ i = Random(512); CLEARLINE(LCD_LINE3); NumOut(5,LCD_LINE3,i); ack = 0; SendRemoteNumber(BT_CONN,OUTBOX,i); until(ack==0xFF) { until(ReceiveRemoteNumber(INBOX,true,ack) == NO_ERR); } Wait(250); } } //SLAVE

  1. define BT_CONN 1
  2. define OUT_MBOX 1
  3. define IN_MBOX 5

sub BTCheck(int conn){ if (!BluetoothStatus(conn)==NO_ERR){ TextOut(5,LCD_LINE2,"Error"); Wait(1000); Stop(true); } } task main(){ int in; BTCheck(0); TextOut(5,LCD_LINE1,"Slave receiving"); SendResponseNumber(OUT_MBOX,0xFF); //unblock master while(true){ if (ReceiveRemoteNumber(IN_MBOX,true,in) != STAT_MSG_EMPTY_MAILBOX) { TextOut(0,LCD_LINE3," "); NumOut(5,LCD_LINE3,in); SendResponseNumber(OUT_MBOX,0xFF); } Wait(10); //take breath (optional) } }

Прямые команды

There's another cool feature about Bluetooth communication: master can directly control its slaves. In the next example, the master sends the slave direct commands to play sounds and move a motor; there is no need for a slave program, since it is the firmware of the slave NXT to receive and manage messages! //MASTER

  1. define BT_CONN 1
  2. define MOTOR(p,s) RemoteSetOutputState(BT_CONN, p, s, \

OUT_MODE_MOTORON+OUT_MODE_BRAKE+OUT_MODE_REGULATED, \ OUT_REGMODE_SPEED, 0, OUT_RUNSTATE_RUNNING, 0) sub BTCheck(int conn){ if (!BluetoothStatus(conn)==NO_ERR){ TextOut(5,LCD_LINE2,"Error"); Wait(1000); Stop(true); } } task main(){ BTCheck(BT_CONN); RemotePlayTone(BT_CONN, 4000, 100); until(BluetoothStatus(BT_CONN)==NO_ERR); Wait(110); RemotePlaySoundFile(BT_CONN, "! Click.rso", false); until(BluetoothStatus(BT_CONN)==NO_ERR); //Wait(500); RemoteResetMotorPosition(BT_CONN,OUT_A,true); until(BluetoothStatus(BT_CONN)==NO_ERR); MOTOR(OUT_A,100); Wait(1000); MOTOR(OUT_A,0); }

Подводим итоги

In this chapter we studied some of the basic aspects of Bluetooth communication between robots: connecting two NXTs, sending and receiving strings, numbers and waiting for delivery ackowledgments. This last aspect is very important when a secure communication protocol is needed. As extra feature, you also learned how to send direct commands to a slave brick.