RS485 is a popular serial protocol that can use only two wires and reach great distances an many devices can be connected on the same line, for this reason is quite popular with industrial instrumentation.
The problem with RS485 is that in it's two wire version it is a half duplex protocol, which basically mean it is synchronous : you cannot send and receive data at the same time.
While this is ok for many applications, it actually requires some attention on how you develop your protocol.
First, you normally need to have a single device (often called "master") initiating the communication and then you need to address a specific device which will respond ONLY when it will understand that your communication packet is over.
This is key, since in half duplex, when a device is in "write mode" it will not be able to read any data and will lose all the eventual bytes sent.
Some simple chips are available to "drive" the RS485, probably the most common one is the inexpensive MAX485 (which I am using).
These drivers feature on one side a TTL UART (RO/DI) and a R/W mode set pin (RE / DE) and on the other side they provide the A,B differential line for the RS485.
RO and DI are simply connected to a ttl uart TX and RX, while the RE/DE are connected together and managed with a separate ttl line (we will call it RW)
When the RW line is high, then the driver is set to WRITE data and it will output into the differential line whatever arrives in the uart TX.
When RW is low, all the data incoming from the differential line is sent to the uart RX.
So, the basic operation mode is to have RW low, then, when we need to send out a data stream, RW is set to high, the data stream is flushed out the uart TX and finally RW is driven back to low.
On the MSP430 RW will be connected to any available GPIO line and the procedure that sends data packets overt the uart will manage to bring theis GPIO line up before sending and immediately down after sending.
However, with more complex architectures things may not be that simple.
I am using the java RXTX GNU serial communication library to manage the communications and I am experiencing issues both on pc platforms and on a beaglebone.
The reason is that the OS / library is buffering the data and if I simply raise RW, write, lower RW I normally end up by setting the driver in read mode before the buffer is actually flushed.
I tried to use the outputBufferEmpty method to switch back RW to low, but did not work either as the method is called sometimes before the actual data physically manages to escape the buffer.
Forcing a buffer.flush or adding a delay has the opposite effect : sometimes the slave device answers before the RW is driven to LOW, so the master misses part of the response.
This is happening at least on the beaglebone.
The purpose of my test is to use the MSP430 as an echo device that responds after a given delay, and check if the beaglebone can get the answer.
The idea is to send two bytes of data from the bone, they will represent a 16 bit integer, then the MSP430 will wait for a number of microseconds equal to that integer before responding with "OK".
The software on the bone will generate a ramp with the delay request and log the success/failure to receive the response.
Once the delay range is identified, a repetitive test will be performed with numbers around that value to calculate the percentage of success versus the delay.
Small data streams and long data streams will be used for the test.
No comments:
Post a Comment