.Net 2 SerialPort Class Questions

D

David White

Hello,

I am working to port an existing application from .net 1.1 to 2.0 and we hope
to employ the new SerialPort class. In our application, the SerialPort class
instance is "wired" to a virtual serial port that is Win32-based. So when
changes take place to the virtual port, we need to migrate those changes to the
serial port and vis-a-vis. The previous version of our code was using a serial
port class based on the Win32 API (derived from the one found at
<http://msdn.microsoft.com/msdnmag/issues/02/10/netserialcomm/default.aspx>).

In porting to the .net 2 SerialPort, I have a few issues:

I am having some confusion about how to map the Win32 notion of serial port
timeouts to that in the .Net 2 SerialPort class. The new class offers a single
property each for ReadTimeout and WriteTimeout. These are documented as:

"Gets or sets the number of milliseconds before a time-out occurs when a read
(or write) operation does not finish."

In the Win32 API, timeouts do not seem this simple and they do not seem to map
easily as their values are based since the last byte was received or sent and
their are multipliers and constants.

Has anyone out there managed to make any sense of how to map the Win32 API
sense of timeouts to that in the new .Net class?

Also, the same thing seems an issue with the idea of Hanshaking? Any
suggestions here?

Thanks,

David
 
D

Dick Grier

Hi David,

Why do Timouts concern you? The default should be fine.

A send timeout will only occur when hardware or software flowcontrol has
inhibited the transmission of data. The default, I think, is 5000 mS, so as
long as the device (or software, in this case) has not signalled that the
..NET application stop sending, then a timeout won't happen.

A receive timeout will happen if your app requests data from the port, but
there is no data to receive (within the timeout period). There is no
obvious reason for this to happen at all.

However, the timeouts specified in the SerialPort class do map EXACTLY to
those in the Device Control Block of the SetCommState API. So, it isn't
clear to me what's up.

Also, I don't understand the question about Handshaking. These settings
also map directly. You either have no handshaking (flowcontrol), you have
CTS/RTS (hardware), you have Xon/Xoff (software), or in some oddball setups
you might have both CTS/RTS and Xon/Xoff (both hardware and software flow
control). Again, since you are using a virtual serial port, it isn't
obvious to me how flowcontrol applies.

I suspect that I haven't answered your questions, because I don't have a
grip on them.

Dick
--
Richard Grier, MVP
Hard & Software
Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
Edition,
ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
2006.
See www.hardandsoftware.net for details and contact information.
 
D

David White

Thanks for the response Dick. You may be correct that my questions were not
very clear. It is, I am sure, because I am such a newbie at all this serial
comm stuff.

I agree that send timeouts should be unimportant. But applications talking to
my virtual port do seem to be setting them and I feel that I need to propogate
those settings to my SerialPort instance so that the SerialPort mirrors the
virtual port to the fullest extent possible. I feel I need to do this because I
really do not wish to interfere with what the application is trying to do (any
more than I am in general by inserting a virtual to physical layer). So that
raises all these issues.

I am not sure why you say "the timeouts specified in the SerialPort class do
map EXACTLY to those in the Device Control Block of the SetCommState API". That
function takes a DCB and I see nothing about timeouts in that structure's
definition. Perhaps you mean SetCommTimeouts? This is where I was coming from.
But when I read the docs for the members of the COMMTIMEOUTS structure I see:

(a) ReadIntervalTimeout
(b) ReadTotalTimeoutConstant
(c) ReadTotalTimeoutMultiplier

The docs for this structure all talk about how the values are combined to yield
the "total timeout period for read operations". And the total seems to be a
function of the number of bytes to be read.

From the SerialPort class docs, I get the feeling (although there is still
room for doubt) that the ReadTimeout property is a "total timeout period". But
I am not sure about this or about how the number of bytes to be read figure
into the equation. I cannot see how the number of bytes to be read can be used
by the SerialPort class in calls to ReadLine where the number of bytes
ultimately to be read is unknown at the time the read begins. So I guess the
question really should have been: How should I combine the values I get when
SetCommTimeouts is called to compute the requested value to passed to the
single, ReadTimeout property of the SerialPort class? I guess the same would
apply to the write timeout but maybe I get away with always using infinite on that.

Does this help focus my question any? I hope so.

Regards handshaking: again, I am trying to propogate settings made by an
application to the virtual port onto the SerialPort instance. Handshake seems
the domain of the DCB and SetCommState. In the DCB, I see two members which
seem to relate to the details of CTS/RTS hardware handshaking:

(a) OutxCtsFlow
(b) RtsControl

Also, can't DSR/DTR be used in hardware handshaking? I am not sure if DSR/DTR
is simply not used any more (and can be ignored). Can DSR/DTR be specified in
conjunction with RTS/CTS in the DCB? If so, are these included when Hardware
handshaking is specified for the SerialPort class (or is it, as you imply, only
CTS/RTS)? If the application requests DSR/DTR via the following:

(c) OutxDsrFlow
(d) DtrControl

What is the proper course with the SerialPort class? I suppose that what I am
looking for is something like a big truth table which shows how various
combinations of DCB handshake settings should be mapped into the set of values
that can be specified on the SerialPort class.

Similarly I wonder about the interpretation of the OutX and OutIn flags plus
the XContinueOnXoff flag.

Again, my confusion is likely due to my high level of ignorance in serial port
matters. I just generally feel that I should be trying tp propogate the
settings requested on the virtual port into the SerialPort instance.

Your help is greatly appreciated.

Thanks.
 
D

Dick Grier

Hi,

I doubt seriously that the timeouts will be an issue. These apply in only
the most obscure situations (and even then, on the TransmitTimeout -- for
very slow data transfer).

Here is the way that I show them in the classes that I have written:

Private Structure COMMTIMEOUTS

Public ReadIntervalTimeout As Int32 ' Specifies the maximum acceptable time,
in milliseconds, to elapse between the arrival of two characters on the
communication line.

Public ReadTotalTimeoutMultiplier As Int32 ' Specifies the multiplier, in
milliseconds, used to calculate the total time-out period for read
operations.

Public ReadTotalTimeoutConstant As Int32 ' Specifies the constant, in
milliseconds, used to calculate the total time-out period for read
operations.

Public WriteTotalTimeoutMultiplier As Int32 ' Specifies the multiplier, in
milliseconds, used to calculate the total time-out period for write
operations.

Public WriteTotalTimeoutConstant As Int32 ' Specifies the constant, in
milliseconds, used to calculate the total time-out period for write
operations.

End Structure

The actual timeout in either situatio (ReadTimeout or WriteTimeout) is the
xTotalTimeoutConstant multiplied by the xTotalTimeMultiplier. The result is
in mS.

Dick
--
Richard Grier, MVP
Hard & Software
Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
Edition,
ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
2006.
See www.hardandsoftware.net for details and contact information.
 
D

David White

Thanks Dick. I will follow your lead. After all, you wrote the book!

Any comment/suggestion on how to properly decode handshake info from a DCB into
the SerialPort class?

Cheers,

David
 
D

Dick Grier

Hi,

I go into this in a little more detail in my book (and, it is somewhat
tricky). Here is the routine that I use for flowcontrol (this is controlled
by bit-mapped values in the DCB, as isthe Parity setting):

Private Sub SetBits(ByRef DCB As DCB)

With DCB

If m_Parity = 0 Then

..Bits = .Bits And (FPARITY Xor &HFFFF)

Else

..Bits = .Bits Or FPARITY

End If

If m_EnableHardwareFlowcontrol = False Then

..Bits = .Bits And (FOUTXCTSFLOW Xor &HFFFF)

..Bits = .Bits And (FRTSCONTROL Xor &HFFFF)

Else

..Bits = .Bits Or FOUTXCTSFLOW

..Bits = .Bits Or FRTSCONTROL

End If

If m_EnableSoftwareFlowcontrol = False Then

..Bits = .Bits And (FOUTX Xor &HFFFF)

..Bits = .Bits And (FINX Xor &HFFFF)

Else

..Bits = .Bits Or FOUTX

..Bits = .Bits Or FINX

End If

End With

End Sub

The contants you see are described in the DCB documentation.

Dick
--
Richard Grier, MVP
Hard & Software
Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
Edition,
ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
2006.
See www.hardandsoftware.net for details and contact information.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top