|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||||
|
|||||
|
I was lieing in bed this morning when it hit me: Since the prog port is RS-232, and so is a computer, there is a chance you could connect LEGO's old COMM tower with the prog port on the RC or the EDU. You would probably need to make a custom cable, but it might work.
Basically, to control the RCX, you send it IR messages via the IR tower. From there it's a simple matter of programming the two. The LUGNET thread for sending messages in VB can be found here. Here's some FRC code to do it: Code:
#define SendByte(Byte) {TXREG = Byte; Wait4TXEmpty();}
void SendRCXMessage (char Message)
{
//Header
SendByte(0x55);
SendByte(0xFF);
SendByte(!0xFF);
//Opcode for Message
SendByte(0xF7);
SendByte(!0xF7);
//Message Byte
SendByte(Message);
SendByte(!Message);
//Checksum
SendByte((0xF7 + Message) & 0xFF);
SendByte(!((0xF7 + Message) & 0xFF));
}
The RCX has outputs A, B, and C. They can be Forward, Backward, or stopped, and have a speed of 1-8. This can be expressed as -8 to 8. If you just want 2 motors, you can set both in the same byte in the range of -7 to 8. Use the first 4 bits for A and the second 4 for B. In NQC: Code:
// A Basic RC Skid-Steer Program (Recieve)
#define mLeft OUT_A
#define mRight OUT_C
#define nOffset 7
#define nBit 16
int Left = 0;
int Right = 0;
task main()
{
start GetMessage;
start RunLeft;
start RunRight;
}
task GetMessage()
{
Left = Message() / nBit - nOffset;
Right = Message() % nBit - nOffset;
}
task RunLeft()
{
while (true)
{
SetPower (mLeft, abs(Left));
if (Left > 0) OnFwd(mLeft);
if (Left < 0) OnRev(mLeft);
if (Left == 0) Off(mLeft);
}
}
task RunRight ()
{
while (true)
{
SetPower(mRight, abs(Right));
if (Right > 0) OnFwd(mRight);
if (Right < 0) OnRev(mRight);
if (Right == 0) Off(mRight);
}
}
In the FRC: Code:
void Set2RCXMotors(signed char Left, signed char Right)
{
char Temp = 0;
//Check Left value
if (Left > 8)
Left = 8;
if (Left < -7)
Left = -7;
//Check Right value
if (Right > 8)
Left = 8;
if (Right < -7)
Left = -7;
Temp = (Left+7) << 4;
Temp |= Right+7;
SendRCXMessage(Temp);
}
If you want to control all 3 outs directly, then you'll have to specify which one. The first 2 bits are what out, 3 is 0, 4 is direction, 5-7 are power-1, and 8 is "Is on?". So, in a nutshell: MM0D PPPOn. On the RCX: Code:
// A Basic RC 3 Motor control
int Left = 0;
int Center = 0;
int Right = 0;
task main()
{
start GetMessage;
start RunLeft;
start RunRight;
start RunCenter;
}
task GetMessage()
{
int Mess;
Mess = Message;
//Left
if ((Mess/64) == 1)
{
if (Mess & 0x10)
{
Left = ((Mess/2) & 8) & ((Mess & 1) != 0) ;
}
else
{
Left = -(((Mess/2) & 8) & ((Mess & 1) != 0));
}
}
//Center
if ((Mess/64) == 2)
{
if (Mess & 0x10)
{
Center = ((Mess/2) & 8) & ((Mess & 1) != 0);
}
else
{
Center = -(((Mess/2) & 8) & ((Mess & 1) != 0));
}
}
//Right
if ((Mess/64) == 3)
{
if (Mess & 0x10)
{
Right = ((Mess/2) & 8) & ((Mess & 1) != 0);
}
else
{
Right = -(((Mess/2) & 8) & ((Mess & 1) != 0)));
}
}
}
task RunLeft()
{
while (true)
{
SetPower (OUT_A, abs(Left));
if (Left > 0) OnFwd(OUT_A);
if (Left < 0) OnRev(OUT_A);
if (Left == 0) Off(OUT_A);
}
}
task RunRight()
{
while (true)
{
SetPower(OUT_C, abs(Right));
if (Right > 0) OnFwd(OUT_C);
if (Right < 0) OnRev(OUT_C);
if (Right == 0) Off(OUT_C);
}
}
task RunCenter()
{
while (true)
{
SetPower (OUT_B, abs(Center));
if (Left > 0) OnFwd(OUT_B);
if (Left < 0) OnRev(OUT_B);
if (Left == 0) Off(OUT_B);
}
}
Code:
void Set3RCXMotors(signed char Left, signed char Center, signed char Right)
{
char Temp = 0;
//Check Left value
if (Left > 8)
Left = 8;
if (Left < -8)
Left = -8;
//Check Center value
if (Center > 8)
Left = 8;
if (Center < -8)
Left = -8;
//Check Right value
if (Right > 8)
Left = 8;
if (Right < -8)
Left = -8;
//Motor
Temp = 0x40;
//Direction
Temp |= ((Left<0)? 0 : 0x10); //Ooooh! A Ternary!
//Power
Temp |= absdif(Left, 1) << 1;
//Is On?
Temp |= (Left != 0) & 1;
SendRCXMessage(Temp);
//Again for the center
//Motor
Temp = 0x80;
//Direction
Temp |= ((Center<0)? 0 : 0x10); //Ooooh! Another Ternary!
//Power
Temp |= absdif(Center, 1) << 1;
//Is On?
Temp |= (Center != 0) & 1;
SendRCXMessage(Temp);
//Again for the right
//Motor
Temp = 0xC0;
//Direction
Temp |= ((Right<0)? 0 : 0x10); //Ooooh! Another Ternary!
//Power
Temp |= absdif(Right, 1) << 1;
//Is On?
Temp |= (Right != 0) & 1;
SendRCXMessage(Temp);
}
|
|
#2
|
||||
|
||||
|
Re: Using an FRC with the RCX?
That'd probably work. It would be interesting, you could say, have the RCX in charge of controlling drive motors, leaving the RC free to determine where you want to go, etc. I have a Mindstorms set (plus all of the expansions (a few of them twice
)), so I might find this and interesting thing to look into.--EDIT-- Oh, yeah. NQC is good, but BrickOS (former LegOS) is better. BrickOS is also C/C++ programming, but everything is precompiled, not interpruted like with NQC and the default LEGo firmware. |
|
#3
|
|||||
|
|||||
|
Re: Using an FRC with the RCX?
Plus, if you have an RCX v1, there is a 9-volt AC adaptor plug in the back (made for the train adaptors). So, connect the 12v Exide to a 12vdc-9vdc transformer, hook that up to the RCX, and you don't need to use 6 AAs!
Anyway, The connecting cable won't be standard: the tower is a Male with just enough space for the cable that came with the kit (No screws). The FRC prog is female. Both the FRC prog and the LEGO IR Tower (LIRT) are made to connect to a computer, so there are going to be problems if you just connect them directly. (Some good info on RS-232 can be found here.) Using the jargon, we are trying to connect 2 DCE devices. Unfortunately, I only have pins for DTEs which is (DB9): Code:
DTE
Pin Purpose
0 - Gnd (Shell)
1 < DCD (Data Carrier Detect)
2 < Rx
3 > Tx
4 > DTR (Data Terminal Ready)
5 - Gnd (signal Ground)
6 < DSR (Data Send Ready)
7 > RTS (Request To Send)
8 < CTS (Clear To Send)
9 < RI (Ring Indicator)
^Direction (< = DCE to DTE, > = DTE to DCE, - = None)
Code:
FRC LIRT Gnd Gnd Tx Rx Rx Tx DSR DTR DTR DSR (The standard is RS-232.) Last edited by Astronouth7303 : 06-04-2004 at 18:17. |
|
#4
|
||||
|
||||
|
Re: Using an FRC with the RCX?
Quote:
![]() I'm going to look up some info on the RC to computer protocol. |
|
#5
|
|||||
|
|||||
|
Re: Using an FRC with the RCX?
Got it!
Thank you B&B Electronics! Code:
FRC LIRT Gnd - Gnd Tx < Rx Rx > Tx DTR < DSR DSR > DTR RTS < CTS CTS > RTS DCD X DCD RI X RI The pins are as follows (DB9): Code:
Shell Shell (optional)
5 5
3 2
2 3
4 6
6 4
7 8
8 7
So if anyone fries something doing this, please tell us before we fry something! |
|
#6
|
||||
|
||||
|
Re: Using an FRC with the RCX?
Quote:
![]() You'll have to wait until tomorrow for the info. Sorry. ![]() |
|
#7
|
|||
|
|||
|
Re: Using an FRC with the RCX?
Two questions:
1) What kind of hardware would I need on the receiving end to make this work? 2) Has anyone tried to accomplish this successfully? Thanks, I would have never thought of trying something like this! |
|
#8
|
||||
|
||||
|
Re: Using an FRC with the RCX?
Quote:
Quote:
![]() |
|
#9
|
||||
|
||||
|
Re: Using an FRC with the RCX?
Here are a few links:
Packet description: (includes example of sending IR message) http://graphics.stanford.edu/~kekoa/rcx/protocol.html From this website, I think that sending: 55 ff 00 f7 08 M ~M C ~C Where C is the checksum. Sends the messageM. One thing I'm confused on is the checksum. It doesn't seem to work the way I read it in his description. Even trying to figure the checksum using his example I didn't come up with the same thing he did. It may be I just don't understand it. If you kow, tell me how to compute it. Some more stuff on the packets: (not as good) http://graphics.stanford.edu/~kekoa/rcx/#Protocol Do you need to know how to send that out, or do you already have that figured out? --EDIT-- Here is a site with examples of using it in C++. http://www.generation5.org/content/2001/rob08.asp. Reading that, it's a great site. ![]() Last edited by Ryan M. : 07-04-2004 at 07:13. |
|
#10
|
|||||
|
|||||
|
Re: Using an FRC with the RCX?
Quote:
A message packet is only one additional info section. Header (3 bytes) OpCode (2) Message (Info, 2) Checksum (2) The OpCode for Message is 0xF7. It has one argument: the message value. Every data byte is followed by it's not. So you get: Header = 55FF00 OpCode = F708 Message = M ~M CheckSum = (F7+M) & FF I think we're finally getting it! The second link is extremely helpful. And I'm glad to know about the Null-modem cable thing: The LIRT is CTE, not a CSE (it is a male, like your computer), so maybe a standard cable works! |
|
#11
|
||||
|
||||
|
Re: Using an FRC with the RCX?
You said the prog port earlier, but how do we access that? Or, rather, can we get enough control to do what we want? You can send text, but I haven't studied the printf() access of the port. Maybe that port will work or maybe something else is necessary. Correct me if you know the way.
![]() |
|
#12
|
|||||
|
|||||
|
Re: Using an FRC with the RCX?
Quote:
Quote:
Quote:
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| FRC Program State Frozen at Power-up | WillyC | Control System | 4 | 14-02-2004 18:05 |
| Request for FLL Volunteers for FLL National Invitational at the FRC Championships | Natchez | General Forum | 3 | 08-04-2003 12:19 |
| Controlling a FIRST robot with a Lego RCX Controller? | archiver | 2001 | 5 | 24-06-2002 04:19 |