SerialPort: How do I time the arrival between characters on a serialstream?

J

Jamie Risk

I'm trying to implement a protocol that has a concept of a GAP
timer in the serial stream; if two properly framed characters
are spaced in time by so many milliseconds or longer, there is
an error.

So far I'm looking at using the SerialPort.DataReceived event.
It's nice because I can suck in bytes filter it through a state
machine to see if packets are properly framed than raise an
event. The problem as I understand it, the DataReceived event
is minimally guaranteed to fire every time it gets
ReceivedBytesThreshold.

This doesn't help me, if I set the threshold to one (1), on the
odd occasion my event handler may be dealing with two or more
characters in the buffer. All this to write that the
DataReceived event isn't a perfect solution for implementing a
GAP timer.

I'm not comfortable with the idea of using the
SerialPort.ReadTimeout mechanism for two reasons:
1. I'm not sure it times what I want it too (could
someone fill me - see the post script?)
2. The DataReceived event mechanism looks like it would work
more nicely with threading. (As opposed to continually
calling SerialPort.ReadByte and relying on the timeouts.

I'm really, _really_ new at this .Net/C# stuff, design help
would be appreciated.

- Jamie


p.s. Does the ReadTimeout mechanism start counting during some
point to the call of ReadByte/Char/Existing/Line/To?
 
D

Dick Grier

Hi,

With what resolution do you need to do your timing?

Windows provides absolutely no guarantee of any real-time performance. The
problems with serial data timing are manifest. I'll list some of them here.

1. The Windows serial driver provides the interrupt service routine that
recevies data from the UART, and buffers receive data until an application
requests it. This driver can provide notificatations to applications (via
events) that data have arrived, but this notification is done with no
schedule or timing guarantee.
2. The serial port implements a receive FIFO. Nominally, the receive FIFO
depth is 16-bytes, with a threshold of 14-bytes. What this means is that
the ISR may not receive a notification of data arrival for up to 14-byte
times (or with some hardware variations that implement much deeper FIFOs...
much longer times).
3. Your application is multitasking (with other applications), and the
SerialPort object is multithreaded (with other threads in the application).
These mechanisms are non-determistic. How long it takes to execute any
portion of them is how long it takes (sometimes more).

Perhaps you get the idea? If you are looking for gross timing, say 20 mS
data gaps, then you may be able to implement the code that does the job .
Most of the time. How reliably? Only testing will tell you. If you want
to measure gaps in data smaller than that, I'd speculate that the
reliability might be problematic.

In any case, you might want to set the UART receive FIFO threshold to 1
(from the default 14). There is no API for this that I know of, so I think
you would have to do it manually using Control Panel/Device Manager.

BTW, ReadTimeout offers nothing to help you here.

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

Dick Grier

I should have added...

The only truely reliable way to get this to work would be to implement the
receive protocol on a microcontroller (IMO). If the micro had two ports,
one could be used for the timing oriented protocol, and the other could be
used to communicate with the host PC, implementing a more robust non-timing
oriented packet protocol. This is a non-trivial project, but would result
in something that would work as reliably as might be desired.

--
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.
 
J

Jamie Risk

Thanks for the quick response.

I'm not to keen to go beyond .Net framework. Insomuch as the
micro controller, I'm an embedded systems designer by trade so
implementation wouldn't be a problem - I just don't want to get
into custom cabling/power etc..

I really only posted to see if there was a method .Net provided
that I hadn't discovered.

The error timeout is about 2 milliseconds. If I time between
hits on the DataReceived event handler I'm sure I can sell as
much as 50 milliseconds latency, which for this purpose, is
still much faster than human perception.

- Jamie
 
D

Dick Grier

Hi,

2 mS is a rather short time in a non-deterministic system, even on a fast
machine, when dealing with serial data. My guess is that it would work
(most, perhaps 99%) of the time without any problem. What happens in the
other 1% of the time? Can you live with an occasional "miss?"

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