NXC: converting a BT program to RS485

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: converting a BT program to RS485

Post by HaWe »

well, this stuff is still quite confusing to me, I already read around in the documentations.
An approximate theoretical solution is clear so far - I didn't ask for that.
As I wrote in my TO post: I need specifically a "rs485 wrapper" round the BT functions.
So have you got any specific NXC code? (something like mattallen will probably develop in the future?)
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC: converting a BT program to RS485

Post by linusa »

doc-helmut wrote:well, this stuff is still quite confusing to me, I already read around in the documentations.
Cool, then do what they say.
doc-helmut wrote:So have you got any specific NXC code? (something like mattallen will probably develop in the future?)
I'm not doing your homework, but try this and report back if it works:
In your program, replace these commands

Code: Select all

BTConnect(BT_CONN_1);
with

Code: Select all

  // configure the S4 port as RS485
  UseRS485(); 
  // make sure the RS485 system is turned on
#if 0
  // low level API function call
  RS485Control(HS_CTRL_INIT, HS_BAUD_DEFAULT, HS_MODE_DEFAULT);
#else
  // hi level API function call
  RS485Enable(); 
#endif
  // initialize the UART to default values
#if 0
  // low level API function call (allows changing UART settings)
  RS485Uart(HS_BAUD_DEFAULT, HS_MODE_DEFAULT); 
#else
  // hi level API function call
  RS485Initialize(); 
#endif

  Wait(MS_10);
Then, instead of your

Code: Select all

SendRemoteString(OUTBOX, 1, cmd);
ReceiveRemoteString(INBOX_11, true, msg)
ReceiveRemoteNumber(INBOX, true, ack);
do this:

Code: Select all

SendRemoteString(CONN_HS_ALL, 1, cmd);
// or try SendRemoteString(CONN_HS_1, 1, cmd);

ReceiveRemoteString(INBOX_11, true, msg)
ReceiveRemoteNumber(INBOX, true, ack);
Construct a minimal example program, test it, and report back, so we can continue from there!

As SendRemoteString() already accepts BT and RS connections, it already is the wrapper function.

If you want to wrap one lewel higher, use

Code: Select all

char myCustomSendingFunction(byte connectionIndex, byte mailbox, string message) {
if (globalUseBT) {
  return SendRemoteString(globalBTConnectionArray[connectionIndex], mailbox, message);
} else if (globalUseRS) {
  return SendRemoteString(globalRSConnectionArray[connectionIndex], mailbox, message);
}
In this case, populate globalBTConnectionArray[] or globalRSConnectionArray[] with values of CONN_BT0 etc or with CONN_HS_1 etc, and set globalUseBT or globalUseRS...
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: converting a BT program to RS485

Post by HaWe »

thank you very much - but actually I didn't expect you "to do my homework", I just asked if anybody could help and if anybody already may have an answer...
linusa wrote: In your program, replace these commands

Code: Select all

BTConnect(BT_CONN_1);
with

Code: Select all

  // configure the S4 port as RS485
  UseRS485(); 
  // make sure the RS485 system is turned on
#if 0
  // low level API function call
  RS485Control(HS_CTRL_INIT, HS_BAUD_DEFAULT, HS_MODE_DEFAULT);
#else
  // hi level API function call
  RS485Enable(); 
#endif
  // initialize the UART to default values
#if 0
  // low level API function call (allows changing UART settings)
  RS485Uart(HS_BAUD_DEFAULT, HS_MODE_DEFAULT); 
#else
  // hi level API function call
  RS485Initialize(); 
#endif

  Wait(MS_10);
so you mean:
all of that just for BTConnect(BT_CONN_1) ?
(certainly ok for the 1st step, I will try that of course - but later on, what about BTConnect(BT_CONN_2)and BTConnect(BT_CONN_3) ?
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC: converting a BT program to RS485

Post by linusa »

doc-helmut wrote: so you mean:
all of that just for BTConnect(BT_CONN_1) ?
(certainly ok for the 1st step, I will try that of course - but later on, what about BTConnect(BT_CONN_2)and BTConnect(BT_CONN_3) ?
Well, this was of course just an example -- it has to be done for all calls to BTConnect. You could do the "if (globalUseBT)" decision inside your BTConnect of course, or introduce yet another wrapper. So something like this:

Code: Select all

void connectAnything(byte connection) {
  if ((connection == CONN_BT0 ) ||(connection == CONN_BT0 ) || (connection == CONN_BT0 ) || (connection == CONN_BT0 ) {
    globalUseBT = true;
    BTConnect(connection);
  } else if ((connection == CONN_HS_ALL ) ||(connection == CONN_HS_1) || (connection ==  CONN_HS_2) /* etc... */ ) {
    globalUseRS = true;
    RSConnect(connection);
  }
}

// then RSConnect is something like this
void RSConnect(byte connection) {
  // configure the S4 port as RS485
  UseRS485();
  // make sure the RS485 system is turned on
#if 0
  // low level API function call
  RS485Control(HS_CTRL_INIT, HS_BAUD_DEFAULT, HS_MODE_DEFAULT);
#else
  // hi level API function call
  RS485Enable();
#endif
  // initialize the UART to default values
#if 0
  // low level API function call (allows changing UART settings)
  RS485Uart(HS_BAUD_DEFAULT, HS_MODE_DEFAULT);
#else
  // hi level API function call
  RS485Initialize();
#endif

  Wait(MS_10);
}
In this example, RSConnect() is probably not correctly designed. It seems RS connections don't have parameters. Once everything is initialized, set up and connected, you're basically "online" and can send commands to connections. I.e. it looks stateless, just like UDP. So you're online with 1 "connection" and can send right away, whereas for Bluetooth, you have to establish N connections.

So in this case, you have to design RSConnect(void) without the connection-parameter, and make sure it's only called once (as opposed to BTConnect(), which has to be called for every connection).

I suggest testing with a small example app and start with only 2 NXTs (1 master, 1 slave), and no multiplexer. The go step by step, and finally upgrade the BT multiplexer app.
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: converting a BT program to RS485

Post by HaWe »

yes, I will start small, of course.
But because I don't understand anything of the rs485 connection stuff (even BT conn I'm confusing) and it's far too many letters what you wrote:
what exactly do I have to write instead of BTConnect(BT_CONN_1) ?
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC: converting a BT program to RS485

Post by linusa »

doc-helmut wrote: far too many letters
better give up then
doc-helmut wrote: what exactly do I have to write instead of BTConnect(BT_CONN_1) ?

Code: Select all

  // hi level API function call
  RS485Enable();

  // initialize the UART to default values
  // hi level API function call
  RS485Initialize();
  Wait(MS_10);
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: converting a BT program to RS485

Post by HaWe »

linusa wrote:
doc-helmut wrote: far too many letters
better give up then
no, that's why I'm asking. There is actually a lack of documentation and examples.
linusa wrote:
doc-helmut wrote: what exactly do I have to write instead of BTConnect(BT_CONN_1) ?

Code: Select all

  RS485Enable();
  RS485Initialize();
  Wait(MS_10);
aah - fine, just 3 lines - much shorter, far less letters, much more understandable. Thx!

But actually I only have my BT muxer to test, what else should I do with all those strings polling and sending continuously? If the wrappers work (finally for 5 slaves: 3 for rs485 and 2 left for BT), my BT muxer will be a much faster network with more sensor ports than I may use now.
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: NXC: converting a BT program to RS485

Post by mattallen37 »

I only ever set it up for RS485 once per program. Just like setting up the port for I2C or any other sensor. Here are the few lines I run at the beginning of the program to enable RS485:

Code: Select all

SetSensorType(IN_4, SENSOR_TYPE_HIGHSPEED);     //enables the port
SetHSState(HS_INITIALISE);                      //initializes RS485
SetHSFlags(HS_UPDATE);                          //dunno what this does
SetHSSpeed(HS_BAUD_921600);                     //sets the speed to the fastest available
SetHSInputBufferInPtr(0);                       //clears the input buffer
SetHSInputBufferOutPtr(0);                      //clears the output buffer
After those few lines, I can send and receive just fine. However, I am not using all these new, fancy, BT look-alike functions. I don't know, maybe they need more that what I am doing. I am sure of this though, that you don't need to initialize RS485 for each NXT slave.

Also, I thought I would mention this. Unlike USB, BT, and I2C, RS485 is not limited to a Master-Slave setup. You can do much more than that. You can do Peer-Peer, or anything else you can dream up. The main thing you need to prevent though it two NXTs talking on the same bus at the same time. If that occurs, you will lose all the data that collided. You will always need to implement some sort of "spoon" to pass between NXTs to keep multiple NXTs from talking at the same time.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: converting a BT program to RS485

Post by HaWe »

matt,
but you think it's possible to use it like BT master-slave with mailbox functions with more than 1 slave?
That's the most important thing to me. I can't re-write all my BT functions, I just want to replace them 1-by-1 so that they will work by rs485 instead, and for less than 3 slaves it's useless to me.

edit:
the mailbox architecture is actually a perfect way to avoid data collision because only the master gets all strings and values by reading from /writing to the mailboxes one by one sequentially.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: converting a BT program to RS485

Post by afanofosc »

There is no way to use mailboxes like you do with the mailbox/bluetooth form of inter-NXT communication via RS-485. With the mailbox system the firmware automagically does many things for you. All the data is transferred under the control of the master NXT. Nothing flows directly from a slave to the master unless the master retrieves it. And each slave typically has its own mailbox and each mailbox has a 5 message queue to help avoid lost messages. None of that exists in the firmware for RS485. Each device can send/receive at will under user-program control. All the firmware does is send what your program asks it to send and read any incoming data that your program asks it to read. There are no built-in multiple storage queues for messages between a master and one or more slaves. In reality, with RS485 there is no notion at the firmware level of a master/slave relationship. Any kind of master/slave association would have to be established at the user-program level (i.e., you have to write it yourself).

Several of the API functions that Matt mentions are low level IOMapRead/IOMapWrite-based functions that you should generally not use since there are newer ones that work with the enhanced NBC/NXC firmware using system calls. Read/search the help to find out what is available. The newer ones generally start with RS485.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests