Page 2 of 3
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 13:51
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?)
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 14:44
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
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...
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 15:14
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
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) ?
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 16:00
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.
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 16:14
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) ?
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 16:28
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);
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 16:38
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.
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 16:44
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.
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 16:49
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.
Re: NXC: converting a BT program to RS485
Posted: 30 Jun 2011, 20:08
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