Page 2 of 5

Re: Communicating via RS485

Posted: 29 Dec 2011, 22:52
by alphasucht
afanofosc wrote:But, again, that is old low level should not be used anymore code.
Oh, man! I was blind! I thought this version of 2008 was the actual state.

Sorry!
I think some of your new features were lost on the way across the Ocean. ;)

Best wishes!
alphasucht

Re: Communicating via RS485

Posted: 30 Dec 2011, 03:06
by mattallen37
Just to add my personal results, I have been able to send and receive RS485 messages without loosing any of them. I did some tests once on my code, and I was able to do thousands of send/receive transactions between a master and slave with no errors. Success is definitely based on the user-code level of the program (running on the good EFW).

Re: Communicating via RS485

Posted: 30 Dec 2011, 03:49
by afanofosc
doc-helmut wrote:just curious:

what do these outcommented lines mean?

Code: Select all

//  // hi level API function call
//  RS485Initialize();
(similarily in sender and receiver),
I was demonstrating that calling RS485Initialize(); is exactly the same as using RS485Uart like this:

Code: Select all

//  // initialize the UART to default values
//  RS485Initialize();
  // configure the UART (this is equivalent to RS485Initialize)
  RS485Uart(HS_BAUD_DEFAULT, HS_MODE_DEFAULT);
RS485Initialize == RS485Uart(HS_BAUD_DEFAULT, HS_MODE_DEFAULT);

Use one or the other but there is no need to use both (which is why one is commented out).

John Hansen

Re: Communicating via RS485

Posted: 30 Dec 2011, 08:35
by alphasucht
Just one more question. If I use more than 2 NXTs, is there any chance to address one Brick directly? With the help of IDs/Addresses or similar? Or is that one thing that my Prgramm have to do?

Thank you!
alphasucht

Re: Communicating via RS485

Posted: 30 Dec 2011, 08:58
by mightor
No, there is no way to address a specific brick. The information is "broadcasted" across the serial link. If you want only a specific brick to respond to it, you'll need to devise some kind of addressing scheme and create code for it. Then when a message for a specific brick is sent, the others will simply ignore it.

- Xander

Re: Communicating via RS485

Posted: 30 Dec 2011, 09:37
by HaWe
my proposal was to add an initial specific char at the start of each msg,
e.g. if the message is "123456" and the NXTs are called a,b,c,d,e,f,g,... the resulting msg would be like
"a123456" or "f123456" and only the brick which recognizes it's own initial would be attentively, drop the first char and process the rest,
while all other NXTs will ignore this msg.

This would be also the way I would implement a token ring network when passing the token (e.g., "ZZZZZ" or "__TOKEN__") to the next brick in the ring - I guess this should work, though I didn't try it so far
@all: what do you think about that?

Re: Communicating via RS485

Posted: 30 Dec 2011, 15:25
by mattallen37
That's basically how I do it, but I don't ever use peer/peer (token). I always use master/slave. Obviously all the NXTs on the network can see all the messages, but I just make them ignore everything that's not for them. I used address 0x00 for the master, and then 0x01 0x02... for the slaves.

Also, instead of just a single byte (address) header on the messages, I used three bytes (I forget now what all the other two bytes were for). I think I used at least one of the other bytes for commands (such as ping, return values...).

Re: Communicating via RS485

Posted: 30 Dec 2011, 15:50
by HaWe
yes, starting the first char of the array by 0x00 / 0x01 is probably the better choice than starting by 'a'.
What I'm also curious about is this:

Code: Select all

// RS-485 sender program

inline void WaitForMessageToBeSent()
{
  while(RS485SendingData())
    Wait(MS_1);
}

task main()
{
  // configure the S4 port as RS485
  UseRS485();
  // make sure the RS485 system is turned on
  RS485Enable();
  // initialize the UART to default values
  // low level API function call (allows changing UART settings)
  RS485Uart(HS_BAUD_DEFAULT, HS_MODE_DEFAULT);
//  // hi level API function call
//  RS485Initialize();
  Wait(MS_1); // make sure everything gets turned on okay
  int i;
  byte buffer[];
  while (true) {
    string msg;
    msg = "goofy " + NumToStr(i);
    TextOut(0, LCD_LINE1, msg);
   
    // send the # of bytes (5 bytes)
    byte cnt = ArrayLen(msg);
    SendRS485Number(cnt);
    WaitForMessageToBeSent();

    // wait for ACK from recipient
    until(RS485DataAvailable());
    RS485Read(buffer);

    // now send the message
    SendRS485String(msg);
    WaitForMessageToBeSent();

    // wait for ACK from recipient
    until(RS485DataAvailable());
    RS485Read(buffer);

    i++;
  }
  // disable RS485 (not usually needed)
  RS485Disable();
}
it's obviously possible to send both a string and integers. But:
1) how does the recipient know that the msg he gets has to be interpreted as a 4-byte string what he receives and not 4 single unsigned/signed bytes or one 32-bit long integer or two 16-bit ints (if the sender is transmitting all those different patterns mixed up and garbled)?
2) what about sending / receiving floats?
3) what is the maximum size of transmitted arrays (strings=arrays of char (+ terminating "0x00"?), or arrays of ints, or arrays of long or floats) ?

Re: Communicating via RS485

Posted: 30 Dec 2011, 16:34
by mattallen37
doc-helmut wrote:yes, starting the first char of the array by 0x00 / 0x01 is probably the better choice than starting by 'a'.
Actually, it is probably better practice to use a higher value (more like 'a'), than 0x00 (often interpreted as NULL).
doc-helmut wrote:1) how does the recipient know that the msg he gets has to be interpreted as a 4-byte string what he receives and not 4 single unsigned/signed bytes or one 32-bit long integer or two 16-bit ints (if the sender is transmitting all those different patterns mixed up and garbled)?
The user-code needs to know how to translate the data. There is no magic way of knowing, it's just how you have the receiving NXT assemble the data.
doc-helmut wrote:2) what about sending / receiving floats?
Well, you could format them as a string with n number of digits, and then convert it back once received.
doc-helmut wrote:3) what is the maximum size of transmitted arrays (strings=arrays of char (+ terminating "0x00"?), or arrays of ints, or arrays of long or floats) ?
I think it's around 64 (maybe 63 plus null?).

Once I have finished assembling my array of data, I always flatten it into a string for sending. On the other end, I unflatten the string into an array, and then dis-assemble it however I need to (NXT address, commands, motor powers and directions, etc.).

Re: Communicating via RS485

Posted: 30 Dec 2011, 16:46
by HaWe
thx so far!
what I never understood:
what is "flatten" actually doing? why do I have to "flatten" an array into a string? Is it only for more-dim arrays? Or is it just adding a "0x00" at the end? Apart from that a string doesn't appear to me to be anything different than a 1-dim array...?