FEZ Cobra with RS485 interface

I have connected a RS485 chip to my FEZ (COM1). I am able to send an receive data at the desired baudrate. That’s all fine. There is however one thing that bothers me.

When TX has finished I need to disable the transmitter and start listening the RS485 line. This is done by looking at the nr of bytes left to be written. When there are no bytes left to be written, I just wait an extra millisecond before I disable the transmitter. All this is done in a seperate thread. The thread normally is suspended and resumed when I’m starting TX. Nothing wrong with this either.

What bothers me is the time it (sometimes) takes before this thread is actually started. Most of the time the transmitters is disabled in 1.5 msec. Sometimes however it takes much longer, up to 200 msec, for no reason at all.

Any of you guys knows a better way to handle this?

Since NETMF is not real time, this is expected.

How do you disable the transmit? Is it on a separate IO?

The TX disable is connected to UEXT5 or IO48.

This is the source of the thread taking care of the disable:

        void TxFinishedThreadEntry()
        {
            while (true)
            {
                //Wait until we have some work to do
                TxFinished.Suspend();

                //Thread waits until all bytes are written
                do
                {
                    Thread.Sleep(1);
                }
                while (mySerialPort.BytesToWrite > 0);

                //Make sure the last byte has left
                Thread.Sleep(1);

                BoardLed.Write(false);
                TXenable.Write(false);
            }
        }

Please tag your code so it is readable, like this

void TxFinishedThreadEntry()
{
while (true)
{
//Wait until we have some work to do
TxFinished.Suspend();

//Thread waits until all bytes are written
do
{
Thread.Sleep(1);
}
while (mySerialPort.BytesToWrite > 0);

//Make sure the last byte has left
Thread.Sleep(1);

BoardLed.Write(false);
TXenable.Write(false);
}
}

So basically you need a pin to go high when transmitting and then it goes low when TX is done?
And you need this because you have multiple RS485 nodes on the network?
What I am trying to understand is how RS232<->RS485 converters work without having such IO? http://www.bb-elec.com/product_family.asp?FamilyId=17&TrailType=Sub&Trail=11

I am not RS485 expert so I am trying to understand it so I can help you better.

Yes, i have multiple nodes on the 485 bus. Depending on the configuration we are talking about 2 - 20 other units.

To interface with RS485 I use a 232/485 convertor (max3485). For TX a pin on this chip is set hi, activating the transmitters. For RX the same pin is set lo. From that moment on the receivers on the chip are enabled and the RS485 bus is available for others to TX.

The devices on B&B auto-disable the transmitter after a timeout of 1 msec. At least, that is what I conclude from this document:

http://www.bb-elec.com/bb-elec/literature/485cosr.pdf

You didn’t answer my question :frowning:

If yes then I will pass this on to the experts to see if they can do something about this.

Also, does it matter if this pin toggles on every byte transfer? Is there delay that is needed after TX is sent?

Sorry, I didn’t understand that part.

Yes, you’re right. I make the pin hi just before the first byte is transmitted and it should go lo after the last byte has been transmit.

Pleaase don’t toggle it for every byte.

But then how would the underlaying driver knows that you have started or have finished?

so

UART.Write(....);//pin go high
UART.Write(...);// pin stays high but then if previous transition was finished then pin will toggle?

Maybe this?


UART.Write(....);//pin go high
while(data is not done sending);
//pin is low now
// ....

TX is really finished when the TX buffer is empty and the last byte has been transmitted. Now and then I work with Atmel’s ATmega 2560, this controller works that way. I don’t know if this feature is available with FEZ hardware.

Alternatively, TX could be considered finished when the TX buffer is empty and we have waited a little while (at 9600 baud, wait 1 msec for example). This is what I am doing at the mmoment.

My code looks like this:


            public void TxStart(byte[] buffer, int offset, int count)
            {
                if (count > 0)
                {
                    //Enable TX, led on
                    TXenable.Write(true);
                    BoardLed.Write(true);
                    mySerialPort.Write(buffer, offset, count);

                    //Resume thread waiting unit all bytes have been TXed
                    //and then disables TX, switches the led off
                    ThreadTxFinished.Resume();
                }
            }

Here comes the thread:


            void TxFinishedThreadEntry()
            {
                //Forever
                while (true)
                {
                    //Wait until we have some work to do
                    TxFinished.Suspend();

                    //Thread waits until all bytes are written
                    do
                    {
                        Thread.Sleep(1);
                    }
                    while (mySerialPort.BytesToWrite > 0);

                    //Make sure the last byte has left
                    Thread.Sleep(1);

                    BoardLed.Write(false);
                    TXenable.Write(false);
                }
            }

In another PC project, a very long time ago, I worked with this software:
[url]http://www.wcscnet.com/CdrvVBro.htm[/url]

They had this very nice feature: [quote]Provides support for RS485/RS422 devices. It can automatically drop the RTS signal when all data has been transmitted for optimum control of the RS485 buses or other devices requiring said protocol. [/quote], which is, in fact, exactly what I need right now.

Hope this clarifies enough. If not please come back.

I also had this problem with the FEZ.

This is how I’ll solve the problem now:
Connect another microcontroller (I took an ATmega) using I2C to the FEZ.
Let the ATmega do the real-time RS485 communication.

This is the only way to solve this problem until GHI decides to adds a property for RS485 where you could assign a pin for switching the RS485 direction.

Toggling on each byte is not a problem, but it must be as fast as possible after the stopbit of each byte. (Some methods even switch the driver off while still sending the stopbit, but this is not possible on all CPU’s)

@ Gus
Was my last post clear? Hope you have enough information now to pass in onto the experts. Basically, the pin should be set lo when there is no more data in the TX buffer and the last byte has left the uart.

regards, Jos

It has been passed on as a request for a free new feature. It is up to the team to add it or not, depending on the overall value.

See tis please http://www.tinyclr.com/forum/1/1503/

I just run into the same problem described in this post. One solution is to use an auto-switching module from maxim. I don’t have on however and I need control the direction. Was anything added regarding this issue to new SDK release ? Maybe using RLP could solve this ?

Yes with RLP, this is solved automatically but you need to write UART drivers in RLP. Shouldn’t be too difficult plus NXP already provides plenty of code examples.

I use something like this right now:


                reqToSend.Write(true);
                serial.Write(buffer, 0, buffer.Length);
                serial.Flush();
                reqToSend.Write(false);

This is problematic however because I’m communicating with RS485 slaves that handle communication faster (native code). I might not toggle back my reqToSend output quick enough before slave starts transmitting his response.

Ok, will look into NXP examples and post about it in RLP section on forum

I have looked into NXP manual and searched for something called RS485 mode for UART. Unfortunately I didn’t find such mode and also flow control options didn’t seem like something i could use for direction control in RS485 converter.

My friend at work suggested a hardware solution that seems to work just fine. Here is the schematics. I can confirm that it works. I have tested it by connecting to COM2 of Domino and the other end to a RS485<->USB converter. I run Docklight on PC that sends response upon received “Hello” message. Could anyone confirm that this solution is ok (or not) and explain how it works? :slight_smile: My RS485 convereter is SIPEX SP485RCP.

Well the chip you are using is a rs485 transceiver, so there is no mystery how it works :slight_smile:

I have used Docklight as well. Found it to be an awesome program for working out serial protocols.

@ Jeff_Birt Yes Docklight is a very handy tool. Use it all the time. So do you think there should be no problem using this hardware automatic flow switching solution ?

Before this solution i was simply changing the communication direction using a digital output from managed code but it was too slow when communicating with other devices that were programmed using native code.

I succesfully comunicate over a half-duplex RS-485 bus from my Cobra with devices that are much faster then the cobra. I have implemented my RS-485 packet driver in native code by using RLP. It just works fine!

Your RS485 level convertor should be connected as in your latest schematic you posted here. In the previous schematic you’re creating a CAN-like bus with RS485 drivers :slight_smile: If you want that I would just use CAN in the whole system and forget about RS485.

If you still want to use RS485 you may use my RLP code.

Contact me: housy [at] telenet [dot] be