Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serial port communication in .NET

Tags:

c#

serial-port

I am using C# to receive data from a serial port but there are some problems. I'm new to this so I need some help.

  1. First off all I want to know which functions are event driven:

    ReadExisting()
    Read()
    Readbyte() 
    Readchar()
    ReadLine()
    Readto()
    
  2. How can I take the required data form input stream of this port?

    I have static sized protocols. Can I use a special char to specify limits of a protocol data, and which will be a suitable char for this?

  3. How do I handle this exception:

    C# SerialPort System.ObjectDisposedException, safe handle has been closed in System.DLL

like image 855
Badr Avatar asked Dec 09 '22 15:12

Badr


2 Answers

None of these methods are "event driven", you'd use them in the DataReceived event. Which is called when the serial port has at least one byte of data available to read.

Not sure what "static sized" means. If the device sends a fixed number of bytes then you'd use the Read() method to read them. Pay attention to the return value, you'll get only as many bytes as are available. Store them in a byte[] and append to that in the next DR event until you've got them all.

If the device sends characters rather than bytes then you can usually take advantage of the NewLine property. Set it to the character or string that terminates the response. A linefeed ("\n") is by far the most typical choice. Read the response with ReadLine(). No buffering is required in that case.

You'll get the ObjectDisposed exception when you close a form but don't ensure that the device stops sending data. Be sure to use only BeginInvoke in the DataReceived event, not Invoke. And don't call BeginInvoke if the form's IsDisposed property is true.

like image 103
Hans Passant Avatar answered Dec 27 '22 07:12

Hans Passant


I can't add anything much to Hans' answer except to say that one of the biggest traps I have seen is that people tend to expect that when the DataReceived event fires, all of the bytes they would like to receive are all present.

e.g. if your message protocol is 20 bytes long, the DataReceived event fires and you try to read 20 bytes. They may all be there, they may not. Pretty likely that they won't be, depending on your baud rate.

You need to check the BytesToRead property of the port you are reading from, and Read that amount into your buffer. If and when more bytes are available, the DataReceived event will fire again.

Note that the DataReceived event will fire when the number of bytes to receive is at least equal to the ReceivedBytesThreshold property of the serial port. By default I believe this is set to a value of 1.

If you set this to 10 for example, the event will fire when there are 10 or more bytes waiting to be received, but not fewer. This may or may not cause problems, and it is my personal preference to leave this property value set to 1, so that all data received will fire the event, even if only 1 byte is received.

Do not make the mistake that this will cause the event to fire for every single byte received - it won't do that.

like image 33
Andy Avatar answered Dec 27 '22 08:12

Andy