View unanswered posts | View active topics It is currently Fri Nov 28, 2014 12:31 am






Reply to topic  [ 6 posts ] 
RS485 protocol 
Author Message
Rookie

Joined: Mon Jan 02, 2012 5:15 pm
Posts: 3
Post RS485 protocol
Hi,

where can I find information about the protocol (databits, parity, stopbits) the RobotC functions for the high-speed port is using? I am trying to connect a NXT to an Arduino via a RS485 connection.

Thanks,
Thomas


Mon Jan 02, 2012 6:05 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3293
Location: Rotterdam, The Netherlands
Post Re: RS485 protocol
Good news and bad news:
  • Good news is that you don't need to know about the stop bits and all that larkin when you're using RS485, it's all taken care of for you. If you really do want more info on how RS485 works on an electrical level, I suggest you check out Google and Wiki.
  • Bad news is that there's not a whole lot of documentation on these functions in ROBOTC.
  • Good news is that it's not overly complex.
First step is that you need to configure S4 as a high-speed port and select a BAUD rate:
Code:
nxtEnableHSPort();
nxtSetHSBaudRate(9600);  // can go as high as 921600 BAUD

Then you need to setup the mode. This can be one of hsRawMode, hsMsgModeMaster and hsMsgModeSlave. RS485 is a half duplex protocol, that means that only one BXT can say something at any given time. I would recommend you set it to hsRawMode but that you make sure one of your devices does all the querying and the other merely replies. Otherwise you will end up with very complex code.
You can set the mode like this:
Code:
nxtHS_Mode = hsRawMode;

Now you can send information down the RS485 bus with some pretty simple calls:
Code:
ubyte data[5] = {'h', 'e', 'l', 'l', 'o'};
nxtWriteRawHS(data[0], 5, 0);

You can catch the return value of nxtWriteRawHS() and check if it's equal ioRsltSuccess. Anything else usually indicates an error.
So let's assume the NXT is the master in this whole story and you've just sent it a request that you know will return 2 bytes. How do you code this? It's not as hard as you think.
Code:
ubyte reply[2]
while (nxtGetAvailHSBytes() < 2) EndTimeSlice(); // wait for the two bytes to come in.
nxtReadRawHS(reply[0], 2);

That's it, really. Please take note that I wrote this code off the top of my head and I don't really have time to test it all, but this is the general operation of how to communicate using RS485 on an NXT. How it's done with Arduino, I am not really sure. I would say probably using Serial object of some kind and an RS485 transceiver chip to translate the UART to RS485 levels.

- Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Tue Jan 03, 2012 3:45 am
Profile WWW
Rookie

Joined: Mon Jan 02, 2012 5:15 pm
Posts: 3
Post Re: RS485 protocol
Hi Xander,

thank your very much for the quick and extensive reply. The RobotC code you sketched is very similar to what I tried. The Arduino on the receiving end of the RS485 link does receive bytes from the NXT, but they are neither the correct number nor have the correct content. This is why I asked for the protocol (=how a single byte of information is sent) -- to set the U(S)ART at the Arduino side correctly. The standard setting of the Arduino side is 8-N-1. When I tried changing parity (from none to even or odd) or adding another stopbit, the data received by the Arduino changed (in number and content) - that is why I think that the U(S)ART on the Arduino is not set correctly to receive the data sent from the NXT correctly. In addition, somewhere I read that the protocols typically employed for RS485 connections (such as ModBus or, as mentioned in the Lego-NXT development documents, P-Net) do not use 8-N-1, the "pseudo standard" for RS232.

Background: I use a MAX485 to connect one of the serial ports on an Arduino Mega (actually a seeeduino mega) to port 4 of the NXT. My goal is to setup a fast and simple link between the Arduino and the NXT to exchanged data packets of typially ~50 bytes. I wrote a version of the code that uses I2C, but because of the limited buffer in the NXT (16 bytes) the transmission of a full packet requires back and forth with multiple data and acknowledgement messages, and therefore becomes more time consuming and less stable. This I was hoping to avoid with the RS485 link. But maybe I have to go back to the I2C solution.

Thanks,
Thomas


Tue Jan 03, 2012 8:40 am
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3293
Location: Rotterdam, The Netherlands
Post Re: RS485 protocol
The NXT uses 8N1, it's how I've communicated with things like the NXTBee and the Dexter WiFI sensor, both of which use RS485.

The problem is probably a mismatched baud rate. Try settings both sides to 9600 and see how that goes.

- Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Tue Jan 03, 2012 12:21 pm
Profile WWW
Rookie

Joined: Mon Jan 02, 2012 5:15 pm
Posts: 3
Post Re: RS485 protocol
Hi Xander,

the BAUD rate seems not to be the problem and 8-N-1 is what the Arduino is using as default.
Taking a closer look at the data received by the Arduino I noticed something. I use the following code on the NXT:

Code:
  nxtEnableHSPort();
  nxtHS_Mode = hsRawMode;
  nxtSetHSBaudRate(9600);
//nxtSetHSBaudRate(28800);
//nxtSetHSBaudRate(57600);
  wait1Msec(2000);
  [...]
  const int nSizeOfData       = 10;
  ubyte myMessage[nSizeOfData] = {0,1,2,3,4,5,20,127,128,255};
  // using "char" does not make a difference

  nxtWriteRawHS(myMessage[0], nSizeOfData, 0);
  wait1Msec(50);
  [...]


Sending this data from the NXT is received at the Arduino side as:
Code:
characters received: 10
data received : "11111111_11111101_11111011_11111001_11110111_11110101_11010111_1_11111111_0"

This puzzles me, since it looks as if only 7bit data is transferred. Converting the incoming data on the Arduino using:
Code:
dataInNew = ((~dataIn) >> 1) & 0x007F;

results in the almost correct ... well at least kind of "understandable" byte sequence:
Code:
characters received: 10
data received: "0_1_2_3_4_5_20_127_0_127"


What am I missing?!

Thanks and best,
Thomas


Thu Jan 05, 2012 6:22 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3293
Location: Rotterdam, The Netherlands
Post Re: RS485 protocol
I haven't used the MAX485 myself but maybe there's something you need to do with the pins to make it work properly with the NXT. I know for the NXTBee, which also uses that chip, something had to be done with one of the pins. I can't remember the details, it's been a while.

- Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Fri Jan 06, 2012 2:22 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 6 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.