|
In lugnet.robotics.spybotics, Alex Jayasundara wrote:
> Now I have couple of questions for you all.
>
> 1. When I send 0x9223 from RCX unit why spybot checking for 0x0200? (This may
> be very primitive question. But I dont know). Actually I want to know the
> relationship of sending data and receiving data and a complete understanding of
> How RCX Communications Work?. An URL will be alright.
First of all, my apologies for not answering you via email. I've been a bit
busy at work. I needed to run some tests myself before I could properly respond
as well.
The 0x9223 from the RCX happens to match the IR sent out by the Spybot
Controller when you press button 2. In SpyBot.h you will see a constant for
each controller button. Button two happens to have the value 0x0200. It's
something internal to the Spybot firmware that performs the translation between
the controller IR data and the 4 bytes it stores in the receive buffer.
> 2. Then I tried to use SetSpybotMessage and SendSpybotMsg posted by John
> Hanson couple of days ago. I am pretty sure message will get delivered to
> spybot, but it doesnt do any thing. [...]
> I didnt change my spybot code to capture any additional messages. Do I have to
> check for any value at the spybot code or not?
You do have to change the program running on the Spybot so that it responds
appropriately to the IR messages it receives. I've included sample programs
below which I have tested with an RCX and a Spybot and it is working as it
should.
Here's a MindScript "listener" for the Spybot. It sets up a pointer in global
variable #3 which initially points to the address of global variable #4. Then
in the watcher for IR messages it writes the Hi and Lo bytes as a word to the
variable pointed to by the pointer and then it increments the pointer. After
the sending program has finished running you can stop this program on the Spybot
and use BricxCC to watch variables 4 through 4+n, where n is the number of times
an IR message was received.
program SpyRcv
{
#include "SpyBot.h"
#include "Events.h"
#include "Globals.h"
// Display 8 bit value on LEDs
sub DebugOut(x)
{
// bits 0-5 on green & red LEDs, green is MSB
led[iDisplay] = (x & 0x17) | ((x & 8) * 4) | ((x & 32) / 4)
led[iYellowWarn] = (x / 64) & 1 // bit 6 on yellow LED
led[iVLL] = (x / 128) & 1 // bit 7 on rear red LED
}
var aaaaaaa1
var aaaaaaa2
var aaaaaaa3
var aaaaaaa4
var aaaaaaa5
var msg
var pmsg
main
{
pmsg = @msg
// Turn off annoying IR pinging
ping[iInterval] = cDisablePings
// Receive IR messages on channel 2
link[iRxChannel] = iRCChannel2
start MessageHandler
start VLLHandler
forever { wait 100 }
}
watcher MessageHandler monitor PostEvent
{
Disp(ledSparkle)
wait 50
pmsg^ = message[ iRxIR, iHiByte ] *256 + message[ iRxIR, iLoByte ]
pmsg += 1
/*
wait 50
pmsg^ = message[ iRxIR, iIndex ]
DebugOut(pmsg^)
wait 50
pmsg += 1
pmsg^ = message[ iRxIR, iCommand ]
DebugOut(pmsg^)
wait 50
pmsg += 1
pmsg^ = message[ iRxIR, iHiByte ]
DebugOut(pmsg^)
wait 50
pmsg += 1
pmsg^ = message[ iRxIR, iLoByte ]
DebugOut(pmsg^)
wait 50
pmsg += 1
*/
if message[ iRxIR, iCommand ] = cCommandController
{
select message[ iRxIR, iHiByte ] * 256 + message[ iRxIR, iLoByte ]
{
when cControllerButton2 {
sound sndShocked
Disp(ledSparkle)
}
when cControllerButton3 {
sound sndHitByLaser
Disp(ledAlarm)
}
}
}
}
watcher VLLHandler monitor VLLEvent
{
sound sndGotIt
DebugOut(vll) // display VLL code on LEDs
}
}
Here's an NQC "listener" program for the Spybot. It acts similarly, but each
time an IR message is received it writes to 4 variables starting from variable
0. It reserves variables 0-24 so if it receives more than 6 IR messages it will
overwrite variables in use for other purposes. You can use this to see each of
the 4 byte values of a received IR message.
#pragma reserve 0 24
#define VLLEvent 1
#define MessageEvent 2
int* p;
void DebugOut(const int &x)
{
SetLED(LED_MODE_ON, (x & 0x17) | ((x & 8) * 4) | ((x & 32) / 4));
SetLED(LED_MODE_YELLOW, (x / 64) & 0x01);
SetLED(LED_MODE_VLL, x & 0x80);
}
task WatchVLL()
{
while (true)
{
monitor (EVENT_MASK(VLLEvent))
{
Wait(100);
}
catch
{
PlaySound(SOUND_GOT_IT);
DebugOut(VLL()); // display VLL code on LEDs
}
}
}
task WatchMessage()
{
while (true)
{
monitor (EVENT_MASK(MessageEvent))
{
Wait(100);
}
catch
{
Disp(ANIMATION_SPARKLE);
Wait(50);
*p = RxMessage(MSG_IR, MSG_INDEX);
p++;
*p = RxMessage(MSG_IR, MSG_COMMAND);
p++;
int y = RxMessage(MSG_IR, MSG_HI_BYTE);
*p = y;
p++;
int z = RxMessage(MSG_IR, MSG_LO_BYTE);
*p = z;
p++;
int x = y * 256 + z;
switch(x)
{
case CONTROLLER_BUTTON2 :
PlaySound(SOUND_SHOCKED);
Disp(ANIMATION_SPARKLE);
break;
case CONTROLLER_BUTTON3 :
PlaySound(SOUND_HIT_BY_LASER);
Disp(ANIMATION_ALARM);
break;
/*
default :
DebugOut(y);
PlaySound(SOUND_CRASH);
Disp(ANIMATION_SCAN);
break;
*/
}
}
}
}
task main()
{
p = 0;
PingInterval() = 0;
// SetPingInterval(0); // turn off Spybot ping
// SetSerialChannel(SERIAL_CHANNEL_IR); // IR channel
// SetSerialBiPhase(SERIAL_BIPHASE_OFF);
// SetSerialChecksum(SERIAL_CHECKSUM_NONE);
// SetRxMessageLock(MSG_NONE); // no IR locks
RCRxChannel() = RC_CHANNEL_2;
// SetRCRxChannel(RC_CHANNEL_2); // Receive IR messages on channel 2
// setup the IR and VLL message events
SetEvent(MessageEvent, VLL(), EVENT_TYPE_MSG_RECEIVED);
SetEvent(VLLEvent, VLL(), EVENT_TYPE_VLL_MSG_RECEIVED);
// start our watcher tasks
start WatchVLL;
start WatchMessage;
while (true)
Wait(100);
}
Here's a "sender" program for the RCX which uses the new API functions I posted
about a while back. These API functions are included in the swan test version
of NQC at http://bricxcc.sourceforge.net/swan_test.zip.
#pragma noinit
task main()
{
/*
InitRCComm();
SetRCMessage(RC_CHANNEL_2, RC_CMD_FWD, RC_CMD_FWD);
repeat(2)
{
SendRCMsg();
Wait(400);
}
Wait(200);
*/
InitSpybotComm(); // switch to Spybot communication
SetSpybotMessage(MSG_BROADCAST, ID_BOT_MIN+1, 0, CMD_FIRE_LASER, 1, 100);
repeat(2)
{
SendSpybotMsg();
Wait(300);
}
Wait(100);
SendSpybotCtrlMessage(0, SPY_CTRL_BTN_1);
Wait(100);
SendSpybotCtrlMessage(0, SPY_CTRL_BTN_2);
Wait(100);
SendSpybotCtrlMessage(0, SPY_CTRL_BTN_3);
Wait(100);
SendSpybotCtrlMessage(0, SPY_CTRL_BTN_4);
Wait(100);
SendSpybotCtrlMessage(0, SPY_CTRL_BTN_5);
Wait(100);
// the next call imitates SendSpybotCtrlMessage(0, SPY_CTRL_BTN_2) except
// for the first byte of the received IR message.
SendSpybotMessage(MSG_BROADCAST, ID_BOT_MIN+1, 0, 0x40, 2, 0);
/*
SetSpybotCtrlPingMessage(ID_BOT_MIN+1);
repeat(2)
{
SendSpybotCtrlPingMsg();
Wait(400);
}
*/
}
In response to
SendSpybotMessage(MSG_BROADCAST, ID_BOT_MIN+1, 0, CMD_FIRE_LASER, 1, 100)
the Spybot receives the following four bytes: 0x80, 0x21, 0x01, 0x64
In NQC on the Spybot these values are INDEX_BROADCAST, CMD_FIRE_LASER, 1, and
100. I haven't tried to figure it out yet, but my guess is that ID_BOT_MIN+1 is
stored somewhere so the Spybot can tell who the message is from.
I hope this helps.
John Hansen
P.S. The contents of swan_test.zip are new as of this evening. I fixed a bug in
BricxCC on the Preferences dialog where the Editor tab could wind up with blank
Color selections that would result in an error when you clicked OK. I also
fixed a very long existing problem in setting the serial port timeout value in
both NQC and BricxCC which makes (at least in my testing) talking to the bricks
via a serial port MUCH MUCH MUCH faster. Nobody (except 1) seems to have tried
the last version I posted about so I don't hold much hope for this one getting
much use either.
|
|
Message has 1 Reply:
Message is in Reply To:
3 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
This Message and its Replies on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
Active threads in Robotics
|
|
|
|