To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.nqcOpen lugnet.robotics.rcx.nqc in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / NQC / 1035
1034  |  1036
Subject: 
Re: Electrical Data Link between 2 RCXs
Newsgroups: 
lugnet.robotics.rcx.nqc
Date: 
Mon, 26 Mar 2001 20:47:52 GMT
Viewed: 
2105 times
  
Hi Bernd,

When you need it really fast, you sholud use legOS instead of NQC.
A program written with NQC uses the LEGO firmware, which is a ByteCode
Interpreter. This pogram is interpreted Byte after Byte from firmaware. The
firmware executes the appropiate (Hitachi H8) code. A program written with
legOS  is compiled into Hitachi H8 code direct.
This interpreter is (much?) slower then a legOS program (using legOS kernel).
I guess the jitter you discribed depends on this interpreter.
(You can disable things like IR communication when compiling a legOS kernel,
this saves performance.)


I saw a LEGO demonstration of a Lego Bartender in Frankfurt last year.
They were using 17 (!) RCX with this model. One RCX and the IR-tower were
lying under the desk in a closed box. So, they obviously were using a serial
protocol to communicate.
(Allready disscused here : http://news.lugnet.com/robotics/rcx/?n=866)
I don't understand why LEGO does not share this with the lugnet community.
(Dear LEGO Team, please share !)

Who is interested in photos of it, please mail.

Tell us about it when ready ;-)

Rainer

In lugnet.robotics.rcx.nqc, Bernd Frassek writes:
It's me again with the subject "electrical datalink between 2 RCXs" (I posted
some articles a couple of weeks ago).
This subject may seem trivial but in fact it is not. Dealing with it, I
discovered some "unpleasanties" in the general execution of programs by the
RCX.

Once again the task:
- an electrical datalink between 2 RCXs (one direction) that allows sending a 4
bit number (0 ... 15)
- it should be as fast as possible.

Once you know the trick (thanks to Dean Husby), the electrical part is easy:
use a motor output at the transmitting robot and toggle between Float and Off.
At the receiving robot use a sensor input set to Touch. A Float will result in
a sensor readings of 0, an Off in a 1.

Now, the protocol. I used a start-bit followed by the four bits of the number
to be transmitted. Up to now I tried several schemes, using equidistant time
periods for the 5 bits. Since the datalink should be fast I couldn't use timers
or fast timers, instead of this I used Waits.

The summary of all investigations:

1. The RCX is slower than I thought. Simple statements need about 3 - 8
milliseconds.
2. The execution of statements is "unstable", i.e. the duration for a statement
is not constant.

If you do something like this:

While (true) {
Off (OUT_B);
Wait (2);
Float (OUT_B);
Wait (2); }

the result should be a nice square waveform, admitting that after the last Wait
a little bit more time is needed for the "long jump statement" of the loop.

In fact it is not. There is a "jitter" of  a couple of milliseconds. Especially
during the start of the sequence, the duration of a pulse is sometimes more
than double (!) than it should be. I could prove this with a very nice signal
analyzer we have in the company.

For a "normal" program the above is not disturbing. For the above scheme with
equidistant pulses and both RCXs "free running", the strongly varying pulses
are killing the concept.

So, I tried another approach where the individual bits are represented by
different pulse length.

I used a long pulse - in NQC: Wait (4) - if a bit is one and a short pulse - in
NQC: Wait (1) - if the bit is zero. The pause between the pulses is short. The
transmission starts with a start-bit  (one / long). E.g. transmitting a "9"
(binary eqivalent: 1001) would result in a pulse scheme like this
          ____      ____      __     __      ____
_____|         |__|        |__|    |__|    |__|        |_____

In the receiving routine the lengths of the pulses are measured. I used
variables which are incremented in a loop as "very fast" timers since the
internal fast timers are not fast enough.

The scheme is as follows: as soon as a pulse starts (sensor input changes to
1), the corresponding variable (_bit3 ... _bit0) is incremented continuously
until the pulse ends (sensor input changes to 0). After this the time periods
for the pulses are checked: a short pulse is represented by a value of  0 ...
2, a long pulse is typically 5 ... 7.

The transmission of a 4-bit number (value 0 to 15) needs at minimum about 110
milliseconds, at maximum (all bits set) about 190 milliseconds.

TRANSMITTER program:

#define _one   4   // Note: a "3" would also work but in a series of 100
#define _zero  1   // 100 transmissions I had errors sometimes
#define _brk   1

int num;

task main ()
{
Float (OUT_B);

while (true) {
   ClearMessage ();
   until (Message() != 0);
   num = Message ();
   SetUserDisplay (num, 0);
   PlayTone(2000, 5);

   Off   (OUT_B);
   if ((num & 0x08) == 0x08) { Wait (_one); } else { Wait (_zero); }
   Float (OUT_B);
   Wait  (_brk);
   Off   (OUT_B);
   if ((num & 0x04) == 0x04) { Wait (_one); } else { Wait (_zero); }
   Float (OUT_B);
   Wait  (_brk);
   Off   (OUT_B);
   if ((num & 0x02) == 0x02) { Wait (_one); } else { Wait (_zero); }
   Float (OUT_B);
   Wait  (_brk);
   Off   (OUT_B);
   if ((num & 0x01) == 0x01) { Wait (_one); } else { Wait (_zero); }
   Float (OUT_B);
   Wait  (_brk);
   Off   (OUT_B);
   Wait  (_one);
   Float (OUT_B);
}
}

RECEIVER Program:

#define _threshold 3

int _bit3;  // "very fast" timmers
int _bit2;
int _bit1;
int _bit0;
int _start;

int num;
int display = 0;

task main ()
{
SetSensor (SENSOR_1, SENSOR_TOUCH);
SetUserDisplay (display, 0);

while (true)
{
num = 0;
_bit3 = 0;
_bit2 = 0;
_bit1 = 0;
_bit0 = 0;

ClearSensor (SENSOR_1);

until (SENSOR_1 == 1);
until (SENSOR_1 == 0);
until (SENSOR_1 == 1);
until (SENSOR_1 == 0) _bit3 ++;
until (SENSOR_1 == 1);
until (SENSOR_1 == 0) _bit2 ++;
until (SENSOR_1 == 1);
until (SENSOR_1 == 0) _bit1 ++;
until (SENSOR_1 == 1);
until (SENSOR_1 == 0) _bit0 ++;

if (_bit3 >= _threshold) num = num + 8;
if (_bit2 >= _threshold) num = num + 4;
if (_bit1 >= _threshold) num = num + 2;
if (_bit0 >= _threshold) num = num + 1;

PlayTone(4000, 5);
display = num;
}
}

The electrical data link is especially needed if the 2 RCXs cannot "see" each
other due to the individual construction, so that IR messages would not be
received.

Best regards and always "good connections"
Bernd Frassek



Message is in Reply To:
  Electrical Data Link between 2 RCXs
 
It's me again with the subject "electrical datalink between 2 RCXs" (I posted some articles a couple of weeks ago). This subject may seem trivial but in fact it is not. Dealing with it, I discovered some "unpleasanties" in the general execution of (...) (23 years ago, 26-Mar-01, to lugnet.robotics.rcx.nqc)

11 Messages in This Thread:





Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR