3

I am looking for a way to have as much control as it is possible over serial port in my c# application. The problem is that I need to communicate with a device that has no documentation except for an old c++ program written to control it. I've tried to use SerialPort class to communicate with the device but its behaviour is quite odd (I have to repeat some of the commands, some other commands dont work at all). I would like to copy that unmanaged program's behaviour, however it seems to be impossible with serialport class, as it does not provide access to low-level functions and structures like DCB for example.

Are there any low-level wrappers for serial communication available for .net? Maybe i could use reflection to manipulate serialport innacessible members at runtime?

1
  • 1
    Did you check through all the properties on the SerialPort class? There are only a very few things not mapped. Commented Jul 23, 2010 at 13:41

5 Answers 5

5

For those suggesting to look at the .NET SerialPort class; frequent Stack Overflow answer provider on Serial related issues, Ben Voigt, provides some excellent insights on why a wrapper around WinAPI would eventually turn out to be a much better idea than using the framework provided SerialPort:

Ben Voigt on .NET SerialPort

A must read.

He also refers to a WinAPI wrapper that he might reveal in future blog posts. If that would happen, it would answer the original question.

Also, there seems to be at least one commercial solution providing the requested functionality here.

Another edit:

Some more searching online has yielded this blog post apparently from the time when there was no SerialPort class in .NET... Source code is provided showing how to wrap Win32 API for the purpose.

EDIT

Some users have pointed out that the above mentioned MSDN blog post link is dead.

The title of the linked article was:

"Use P/Invoke to Develop a .NET Base Class Library for Serial Device Communications", written by John Hind andpublished October 2002 as I can tell from another MSDN article referring to it:

enter image description here

Unfortunately, Microsoft seems to only serve editions of their magazine down to 2003:

https://msdn.microsoft.com/en-us/magazine/msdn-magazine-issues.aspx

FWIW, I found a half working online version elsewhere...

Sign up to request clarification or add additional context in comments.

4 Comments

I do not mind the odd down vote but please provide feedback as well.
The link to MSDN blog post is broken. if it is possible, include article title too, in case the link break again.
I'll look for it!
Another thing I dislike about Microsoft's SerialPort class is that it's not overridable (no virtual methods), so you can't even use it as a skeleton and improve it. Instead you have to create a new disconnected one.
3

Unfortunetely, the SerialPort class is an incomplete wrapper. I have found the only way to gain access to the underlying DCB is through reflection.

The only other option would be to re-write SerialPort and make it complete. I have not seen any such implementation freely available (yet).

Here is an example where I used reflection to gain access to RTS_CONTROL_TOGGLE: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/45a89532-b01c-4ef8-aa46-532882cec004

Comments

3

The SerialPort class is a very thin wrapper around the Win32 serial port API, hard to see how another wrapper could improve your life. There are wrappers available from the .NET 1.x days, it didn't support serial ports. Here is one from MSDN magazine.

But you're just as likely to have the same problems. One way that written commands could get lost is by the device throwing away received bytes (or losing them) when it has turned off the RTS signal off. You fix that by setting the Handshake property to RequestToSend.

One way that things can go wrong with reading commands is to get the Read() call wrong. It will return an arbitrary number of bytes, as many as are available in the receive buffer. Pay attention to the return value, it tells you how many bytes were actually read. The only guarantee is that it will at least be 1 and never more than count.

The SysInternals' PortMon utility can help you troubleshoot communications, it gives you a raw view of what the device driver sees. Compare with, say, Hyperterminal or another known-good program.

5 Comments

The PortMon reference was very useful, thanks for that
It's not thin at all. It introduces SerialStream layer, which in turn uses overlapped (fail-asynchronous) winapi methods. There are so many troubles with SerialPort, what I am also looking now for a real thin wrapper: DataReceived event is crap, exceptions on port closing, ObjectDisposedException (huh) when usb-to-serial adapter is disconnected, etc.
Hmm, if you don't like ODE then don't jerk the connector while the port is opened. There's completely no point in doing that. Using the "Safety Remove Hardware" tray icon is not optional when you use a USB emulator, serial ports are not play-and-play devices.
@HansPassant, You cannot expect your end user or a hardware technician follow all your instructions. most of the time, they don't even read the instructions. when ObjectDisposedException happens, your application will become unstable and there is no possible way to avoid that and management will blame you for writing lousy code even though you try to tell them it is microsoft's fault!
I write answers for programmers, not technicians. A technician never has any trouble figuring out that unplug cable => program crashes => not a good strategy. You prefer unplug cable => stops working => call programmer approach, have at it.
2
+100

Working with a serial port through PInvoke works fine. We're doing this in a Silverlight application, but it should work the same in a normal .NET app. The answer to Serial Communication with Silverlight 5 (COM port) provides a basic wrapper for a which could easily be adapted to your needs. It uses the normal WinAPI method so you get full access to all serial port functionality, like you would in a C++ application.

P.S. If you don't already, use PortMon to monitor what's happening on the line.

2 Comments

Thanks for the ling to the other answer. The code posted there seems quite useful. Portion is indeed a nice tool on 32 bit Win7. My experience is that it does not work on x64 though (stackoverflow.com/questions/1356470/…). Even running as admin and setting WinXP SP2/3 compatibility did not help. A pity, because its a nice tool.
I ended up using the solutions you referenced and they suit my purposes fine. Thanks.
0

You may be able to copy the old C++ code into a managed C++ class, which you could then use just like any normal .NET class from your C# code. This may be the fastest way to reach your goal.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.