469,282 Members | 1,732 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,282 developers. It's quick & easy.

SerialPort and SerialDataReceivedEventHandler help

I have the following method that handles the data received event:
private void _port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
string data = _port.ReadExisting();
_log.LogToFile(data, true);
}

The LogToFile function logs data to a file. The second parameter
indicate if the file should timestamp the message.

On the initial test of this method I got the following result:
[9/19/2008 4:40:04 PM]10??I 1
[9/19/2008 4:40:04 PM] 1909081
[9/19/2008 4:40:04 PM]640?

This is not what I expected. I converting an old VB 6.0 program to
C#. If I add Thread.Sleep(500) before the ReadExisting() I get the
string I was expecting:
[9/19/2008 4:57:47 PM]10??I 1 1909081657?

Notice in the first try it is sending 8 bytes at a time. Is there
anyway to avoid using Thread.Sleep to achieve this?
Sep 25 '08 #1
8 6249
hi Kevin,

Ke***********@gmail.com wrote:
On the initial test of this method I got the following result:
[9/19/2008 4:40:04 PM]10??I 1
[9/19/2008 4:40:04 PM] 1909081
[9/19/2008 4:40:04 PM]640?

This is not what I expected. I converting an old VB 6.0 program to
C#. If I add Thread.Sleep(500) before the ReadExisting() I get the
string I was expecting:
[9/19/2008 4:57:47 PM]10??I 1 1909081657?
The first result looks good. I don't know, what device you are querying,
but your string has obviously an explicit start and end symbol. Just
read it in a loop as long as your string is not complete.
mfG
--stefan <--
Sep 25 '08 #2
hi,

Stefan Hoffmann wrote:
The first result looks good. I don't know, what device you are querying,
but your string has obviously an explicit start and end symbol. Just
read it in a loop as long as your string is not complete.
Better than a loop (i'm using <as start/end tags):

private string _Data = null;
private void _port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
string data = _port.ReadExisting();

if (_Data == null && data.StartsWith("<"))
{
_Data = data;
data = null;
}
if (_Data != null && data != null)
_Data += data;
if (_Data != null)
if (_Data.EndsWith(">"))
{
_log.LogToFile(_Data, true);
_Data = null;
}
}

Depending on the kind of device, you must consider that you get strings
like "789><123897"
mfG
--stefan <--
Sep 25 '08 #3
I tried that. There is still only 8 bytes available at a time. The
only solution I have found so far is to add the sleep. I don't want
to do that because then I have to make the sleep long enough to get
the larger messages but not so large any timeouts will be triggered.
Sep 25 '08 #4
On Sep 25, 9:51*am, Stefan Hoffmann <stefan.hoffm...@explido.de>
wrote:
hi,

Stefan Hoffmann wrote:
The first result looks good. I don't know, what device you are querying,
but your string has obviously an explicit start and end symbol. Just
read it in a loop as long as your string is not complete.

Better than a loop (i'm using <as start/end tags):

private string _Data = null;
private void _port_DataReceived(object sender,
* *SerialDataReceivedEventArgs e)
{
* *string data = _port.ReadExisting();

* *if (_Data == null && data.StartsWith("<"))
* *{
* * *_Data = data;
* * *data = null;
* *}
* *if (_Data != null && data != null)
* * *_Data += data;
* *if (_Data != null)
* * *if (_Data.EndsWith(">"))
* * *{
* * * *_log.LogToFile(_Data, true);
* * * *_Data = null;
* * *}

}

Depending on the kind of device, you must consider that you get strings
like "789><123897"

mfG
--stefan <--
That's interesting. What isn't being displayed in my post is the
start and end character - 0x02 and 0x03.
Sep 25 '08 #5
hi Kevin,

Ke***********@gmail.com wrote:
I tried that. There is still only 8 bytes available at a time.
Try setting another bit (baud) rate for your port.
mfG
--stefan <--
Sep 26 '08 #6
Ke***********@gmail.com wrote:
I have the following method that handles the data received event:
private void _port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
string data = _port.ReadExisting();
_log.LogToFile(data, true);
}

The LogToFile function logs data to a file. The second parameter
indicate if the file should timestamp the message.

On the initial test of this method I got the following result:
[9/19/2008 4:40:04 PM]10??I 1
[9/19/2008 4:40:04 PM] 1909081
[9/19/2008 4:40:04 PM]640?

This is not what I expected. I converting an old VB 6.0 program to
C#. If I add Thread.Sleep(500) before the ReadExisting() I get the
string I was expecting:
[9/19/2008 4:57:47 PM]10??I 1 1909081657?

Notice in the first try it is sending 8 bytes at a time. Is there
anyway to avoid using Thread.Sleep to achieve this?
If you know the minimum length of an incoming message, then you could change the
ReceivedBytesThreshold property of the SerialPort. Or, if your incoming message
contains a known end byte that you can synch on, you could use the ReadTo()
method.

HTH,
-rick-
Sep 26 '08 #7
I cannot change the baud rate, I have to match the machine, right?
The minimum number of characters could be one. The machine sends an
ACK once and a while to see if anything is listening. This is
receiving data from a medical device. There is a comments field that
can be filled out and that will be in the data stream

I said VB but that was my mistake. It's a service that uses Vb to
manage it. The code that monitors the serial port is C++. here's the
C++ code:
if(ReadFile(hComm,buf,4096,&dwBytesTransferred,NUL L) == TRUE)

That will read the entire stream into the buffer.

Someone suggested to me to use SerialPort.ReadLine. None of these
make a difference. First, there may be new line characters in the
data stream that is part of the data. I've tried all of the read
functions, the program is only getting 8 bytes at a time unless I put
a sleep in there.

I have even tried something like
while (_port.BytesToRead 0)
{
iRead = _port.Read(buffer, iRead, _port.BytesToRead);
iTotal += iRead;
}

Only the first 8 bytes unless I put a sleep in the loop. A sleep
probably isn't bad, it just has to be large enough that on slower
machines it will still get all the data into the buffer but not so
long that it causes any timeouts.

I think I have to do what Stefan suggested if I want to be safe.

BTW, thanks for the responses. I tried to get a response on the msdn
forum but apparently my question was off topic for the general C#
forum.
Sep 26 '08 #8
Ke***********@gmail.com wrote:
On Sep 25, 9:51 am, Stefan Hoffmann <stefan.hoffm...@explido.de>
wrote:
>hi,

Stefan Hoffmann wrote:
>>The first result looks good. I don't know, what device you are querying,
but your string has obviously an explicit start and end symbol. Just
read it in a loop as long as your string is not complete.
Better than a loop (i'm using <as start/end tags):

private string _Data = null;
private void _port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
string data = _port.ReadExisting();

if (_Data == null && data.StartsWith("<"))
{
_Data = data;
data = null;
}
if (_Data != null && data != null)
_Data += data;
if (_Data != null)
if (_Data.EndsWith(">"))
{
_log.LogToFile(_Data, true);
_Data = null;
}

}

Depending on the kind of device, you must consider that you get strings
like "789><123897"

mfG
--stefan <--

That's interesting. What isn't being displayed in my post is the
start and end character - 0x02 and 0x03.
Then, again I will suggest ReadTo(). It looks as if your data may consist of a
fixed length ASCII string bracketed by start and end framing values. You could
use ReadTo() to read up to the next start byte, as per

string startPattern = Encoding.ASCII.GetString(new byte[]{2});
string input, junk;
while (1)
{
/*
Read previous previous input through end byte
(should be 20 bytes as per your example). Then
read and discard the start byte you just found.
*/
input = myPort.ReadTo(startPattern);
junk = myPort.ReadByte(); //
}

If your data pattern is as simple as you indicate then this simple loop or
something very like it may work for you. You would probably want to add
validation of the start and end bytes plus code to recover your framing if you
happen, e.g., to get a short input string.

HTH,
-rick-
Sep 27 '08 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Nathan Ie | last post: by
2 posts views Thread by Andrea Judge | last post: by
13 posts views Thread by Jean Paul Mertens | last post: by
7 posts views Thread by Simon | last post: by
1 post views Thread by Lars Siden | last post: by
reply views Thread by cronusf | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.