|
|
|
![]() |
|
|||||||
|
||||||||
|
|
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);
}
|
| 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 | 02-14-2004 06:05 PM |
| Request for FLL Volunteers for FLL National Invitational at the FRC Championships | Natchez | General Forum | 3 | 04-08-2003 12:19 PM |
| Controlling a FIRST robot with a Lego RCX Controller? | archiver | 2001 | 5 | 06-24-2002 04:19 AM |