5

I have been researching various third party libraries and approaches to low latency serial communications in .Net. I've read enough that I have now come full circle and know as little as I did when I started due to the variety of conflicting opinions.

For example, the functionality in the Framework was ruled out due to some convincing articles stating: "that the Microsoft provided solution has not been stable across framework versions and is lacking in functionality."

I have found articles bashing many of the older COM based libraries. I have found articles bashing the idea of a low latency .Net app as a whole due to garbage collection.

I have also read articles demonstrating how P/Invoking Windows API functionality for the purpose of low latency communication is unacceptable.

THIS RULES OUT JUST ABOUT ANY APPROACH I CAN THINK OF!

I would really appreciate some words from those with been there / done that experience. Ideally, I could locate a solid library / partner and not have to build the communications library myself. I have the following simple objectives:

  • Sustained low latency serial communication in C# / VB.Net
  • 32/64 bit
  • Well documented (if the solution is 3rd party)
  • Relatively unimpacted (communication and latency wise) by garbage collection .
  • Flexible (I have no idea what I will have to interface with in the future!) The only requirement that I have for certain is that I need to be able to interface with many different industrial devices such as RS485 based linear actuators, serial / microcontroller based gauges, and ModBus (also RS485) devices.

Any comments, ideas, thoughts or links to articles that may iron out my confusion are much appreciated!

dsolimano
  • 8,870
  • 3
  • 48
  • 63
Berney Villers
  • 162
  • 1
  • 7

5 Answers5

3

Latency is a non-issue on modern machines. Serial ports are glacially slow, 19.2 kilobaud is peanuts, the .NET SerialPort class handles them fine. The DataReceived event is delivered asynchronously by a threadpool thread that performs a blocking wait with WaitCommEvent(), you can't go faster than that.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Try the simplest approach with a test rig and see if you're in trouble or not before going esoteric. – dkretz Jun 23 '10 at 17:35
  • The serial port driver has buffers, so it can handle the throughput. Throughput is not the same as latency/turnaround, e.g. the OP might want to consistently tranmsit a message within msec of receiving a message. – ChrisW Jun 23 '10 at 17:37
  • 1
    Latency is a huge issue on modern machines. In my case I was handling the datareceived event of the SerialPort class. It executes the event handler on a separate thread. The latency introduced by simply using the event handler was simply unacceptable for my application. You can send as much data as you want, true. But the issue is "how fast you notice you have received new data" – Cedric Mamo Jun 13 '13 at 08:50
2

I have a .NET Application that runs on a server with 16 COM ports, about 11 of which are currently connected to various devices, some RS485, many RS-232. (Diagram here: http://blog.abodit.com/2010/03/home-automation-block-diagram/). Most of these devices are running just 9600 baud, and most don't have very tight timing requirements. I have a thread per device handling receiving and while it runs at normal thread priority, all other non-communication threads run at a lower priority (as you should do for most background tasks anyway). I have had no issues with this setup. And, BTW it also plays music on three sound cards at the same time using high-priority threads from managed code and 1second DSound buffers, all without glitching.

So how tight are your latency requirements, what baud rate and how many serial ports are you trying to serve? The buffer on your UART at most normal baud rates is more than sufficient for garbage collection and much more to delay taking the next byte off it.

GC is not as evil as it is made out to be. On a properly prioritized threaded system with good management of object sizes and lifetimes and sufficient buffering (UARTS/Sound buffers etc.) it can perform very well. Microsoft is also continuously improving it and the .NET Framework 4 now provides background garbage collection. This feature replaces concurrent garbage collection in previous versions and provides better performance. See MSDN.

Ian Mercer
  • 38,490
  • 8
  • 97
  • 133
  • Thanks for the heads up on the GC improvements. This highest performance scenario that I will need to achieve is 250Hz communication to a linear actuator. If in fact the GC is not an issue, then the next it all boils down to what type of latency is introduced by the framework or P/Invoke. – Berney Villers Apr 29 '10 at 03:10
  • Most connections will be 115200 baud, but a few will be higher. – Berney Villers Apr 29 '10 at 03:12
1

.NET is generally a poor choice for the kind of application you describe. This kind of thing is going to require native code and a language like C++ for at least the portion that requires low-latency.

Tom Cabanski
  • 7,828
  • 2
  • 22
  • 25
  • My goal is 250Hz communication with a linear actuator in the most extreme scenario. Is your take on this due to garbage collection, or additional latency added by P/Invoke or some other element that I am overlooking? – Berney Villers Apr 29 '10 at 03:11
  • @bvillersjr - I think that an unmanaged thread can be set to a higher priority than a managed thread. That, writing a native DLL which used unmanaged threads, is how we achieved low latency once when we were interfacing with a USB drivers which had small buffers and which therefore imposed tight timing on the application. – ChrisW Jun 23 '10 at 17:41
0

Personally I love my BBUSB interface. When switched to bitbang mode it allows you direct on/off control 8 pins which you can set to be input or output.

"But I need a serial port." You say. It's entirely possible. Simply wire up the pins to a 9 pin male serial port and you're good to go.

Spencer Ruport
  • 34,865
  • 12
  • 85
  • 147
0

The .Net Serial Port Class Consumes far too much CPU when sending receiving small packets at high frequencies. It also seems to miss some events. Since I needed to beable to send and receive 16 byte packets 1000 timesper seond reliably I wound up putting together something based off of the Windows API and can now easily fire 1000 small packets per second while consuming next to no CPU. I tried nearly every library available library, and fr this simple task, they all failed due to excessive CPU utilization or missed events.

Berney Villers
  • 162
  • 1
  • 7