|
In lugnet.robotics.rcx, Philippe Hurbain wrote:
> In lugnet.robotics.rcx, Mark Riley wrote:
> > Now, as has been mentioned here before, the Spybot and Manas remotes send IR
> > messages using a 76KHz IR carrier. My RCX 2.0 can receive these messages just
> > fine, while my RCX 1.0 struggles to receive these messages even with the remote
> > a few inches from the RCX.
>
> Hello Mark,
>
> How did you managed to receive Spybot remotes messages with your RCX? I tried
> several settings, no luck :-(
>
> Philo
Hi Philippe,
I've been adding support for the Spybot and Manas remotes to my custom firmware
LDCC. The idea is to allow 3 people to each control a seperate train using
these remotes. This is how I discovered the problem with RCX 1.0 not receiving
the packets from the remotes very well.
Unfortunately, I don't think there is a way to receive the remote packets using
Lego's standard firmware, though it's easy enough to send the packets for
controlling Spybots or Manas motor units.
However, I put together a fun little program for BrickOS that turns the RCX into
a Manas motor unit. I've run an RCX 2.0 and a Spybot around the room using the
Spybot remotes and they both respond wonderfully.
Have fun,
Mark
// rspybot.c - 11/02/03 - Mark Riley
// This is an example program for BrickOS 0.2.6.10 that
// enables the RCX to detect packets sent by the Spybot or
// Manas remote controls. Motors A and C are activated in
// response to the left/right motor commands from the remote.
// With the Spybot remote, pressing the fire button will
// activate output B.
// By default, the program listens to channel 1, however, you
// can reprogram the channel using the same technique used by
// the Spybot remote to reprogram a Spybot.
// This program is intended for use on an RCX 2.0. It doesn't
// work well with RCX 1.0 since the IR receiver isn't sensitive
// enough at the 76 KHz carrier frequency used by the Spybot
// and Manas remotes.
#include <unistd.h>
#include <conio.h>
#include <time.h>
#include <dmotor.h>
#include <persistent.h>
#include <sys/h8.h>
// returns received IR byte (-1 if no byte available)
int get_ir_byte()
{
// byte ready?
if (S_SR & SSR_RECV_FULL)
{
// yes, clear ready bit and return the byte
S_SR &= ~SSR_RECV_FULL;
return S_RDR;
}
// clear any errors encountered
if (S_SR & SSR_ERRORS)
S_SR &= ~SSR_ERRORS;
// no byte received
return -1;
}
unsigned char spy_packet[2];
unsigned char spy_count;
int spy_timeout;
// returns non-zero result when valid packet received
unsigned char get_spy_packet()
{
int b = get_ir_byte();
if (b >= 0)
{
spy_packet[spy_count++] = b;
switch (spy_count)
{
case 1:
// set timeout for second byte
spy_timeout = (int)get_system_up_time() + 4;
break;
case 2:
spy_count = 0;
// verify checksum
if ( ( ( spy_packet[0] + (spy_packet[0] >> 4) +
spy_packet[1] + (spy_packet[1] >> 4) ) & 0x0F ) == 0 )
return 1; // good, packet ready!
break;
}
}
// reset if next byte not received in timely fashion
if ((int)get_system_up_time() - spy_timeout >= 0)
spy_count = 0;
// packet not ready
return 0;
}
unsigned char channel __persistent = 1;
int motor_timeout;
int fire_timeout;
int main()
{
// disable serial receive IRQ handler
S_CR &= ~SCR_RX_IRQ;
// switch to 4800 baud
S_BRR = B4800;
motor_a_speed(MAX_SPEED);
motor_b_speed(MAX_SPEED);
motor_c_speed(MAX_SPEED);
while (!shutdown_requested())
{
// packet ready?
if (get_spy_packet())
{
// yes, display received packet
cputw((spy_packet[0] << 8) | spy_packet[1]);
// check for left/right motor packet
// format: 01CCRRRR LLLLSSSS
// C = channel number (1 to 3)
// R = right motor
// L = left motor
// S = checksum
if ((spy_packet[0] & 0xC0) == 0x40)
if (((spy_packet[0] & 0x30) >> 4) == channel)
{
// left motor
switch (spy_packet[1] & 0xF0)
{
case 0x70: motor_a_dir(fwd); break;
case 0xF0: motor_a_dir(rev); break;
default: motor_a_dir(off); break;
}
// right motor
switch (spy_packet[0] & 0x0F)
{
case 0x07: motor_c_dir(fwd); break;
case 0x0F: motor_c_dir(rev); break;
default: motor_c_dir(off); break;
}
// set timeout for motor packets
motor_timeout = (int)get_system_up_time() + 200;
}
// check for fire button packet
// format: 00CC0001 0001SSSS
// C = channel number (1 to 3)
// S = checksum
if ( (spy_packet[0] & 0xCF) == 0x01 &&
(spy_packet[1] & 0xF0) == 0x10 )
if (((spy_packet[0] & 0x30) >> 4) == channel)
{
motor_b_dir(fwd);
// set timeout for fire button packet
fire_timeout = (int)get_system_up_time() + 250;
}
// check for channel assignment packet
// format: 100100CC 1111SSSS
// C = channel number (1 to 3)
// S = checksum
if ( (spy_packet[0] & 0xFC) == 0x90 &&
(spy_packet[1] & 0xF0) == 0xF0 )
channel = spy_packet[0] & 0x03;
}
// turn off motors A & C if no motor packet received in a while
if ((int)get_system_up_time() - motor_timeout >= 0)
{
motor_a_dir(off);
motor_c_dir(off);
}
// turn off output B if no fire button packet received in a while
if ((int)get_system_up_time() - fire_timeout >= 0)
motor_b_dir(off);
msleep(1);
}
// restore original IR settings
S_BRR = B2400;
S_CR |= SCR_RX_IRQ;
return 0;
}
// EOF
|
|
Message has 2 Replies:
Message is in Reply To:
17 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
|
|
|
|