1

I'm handling a caller id serial device and write the following program:

serialPort = new SerialPort("COM7", 19200, Parity.None, 8, StopBits.One);
serialPort.DataReceived += serialPort_DataReceived;
serialPort.RtsEnable = true;
serialPort.Encoding = Encoding.ASCII;
serialPort.Open();

void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
    byte[] data = new byte[serialPort.BytesToRead];
    serialPort.Read(data, 0, data.Length);
    Console.WriteLine(Encoding.ASCII.GetString(data));
}

At first that I receive a call, the event fires perfectly and the result is: "A0101181456926E"

The problem is the subsequent events... next time that I make a call, the event serialPort_DataReceived fires a lot of times each one with 1 char.

Is there any property to set or method to invoke to solve this behaviour?

ps. If I comment the line serialPort.RtsEnable = true;, I don't receive any subsequent event.

Otiel
  • 18,404
  • 16
  • 78
  • 126
Alexandre
  • 7,004
  • 5
  • 54
  • 72
  • 1
    AFAIK this is normal behaviour... something similar happens for example with TCP connection - you will have to deal with that, by designing the protocol accordingly... – Yahia Nov 25 '11 at 20:33
  • What values is your `ReceivedBytesThreshold` property? – H H Nov 25 '11 at 20:38

3 Answers3

6

As Henk mentioned, you can set the amount of bytes to be received before the DataReceived event is triggered with the property ReceivedBytesThreshold.

But in any case you have to deal with any number of bytes to be received at a time. You have to design your protocol in a way that you are able to recognize when a message is fully received.

Jan
  • 15,802
  • 5
  • 35
  • 59
4

It is normal behavior. You can change the ReceivedBytesThreshold property, but doing so means that you have to receive at least that amount, and if there are any errors in transmission, getting in sync again can be difficult.

My advice is to leave ReceivedBytesThreshold=1, and queue the received data up until you have what you need.

dbasnett
  • 11,334
  • 2
  • 25
  • 33
1

I have done just that what is suggested by building in a buffering mechanism to detect when I have received a full input string based on a vendors protocol. works fine. (Must say, not all protocol designs provides clear start and end sequences to work with) What I couldn't understand was why the DataReceived eventhandler was still firing although when I read the input buffer with the Port.ReadExisting() method, the string length was zero. Reading up on the SerialPort.ReceivedBytesThreshold Property on https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.receivedbytesthreshold(v=vs.110).aspx I realized that even though the default of the property is 1 the handler will still fire "if an Eof character is received, regardless of the number of bytes in the internal input buffer" Maybe this is the reason why the handler fires what seems to be unnecessarily

RonnieT
  • 11
  • 2