Serial Port
-
Hi What are the things i need to look into when i use serial port class? My issue is I am getting a Timeout Exception every now and then in Reading the port. My understanding about the serial port class is as below 1. We need to set the baud rate, parity etc once 2. Timeout value (read timeout and write timeout) every time you read or write. a. Read timeout timer starts when the first characeter arrives at the hardware buffer and code will wait till all the characters arrived as per the code
comPort.Read(buffer, 0, 100);
here it will wait for 100 bytes or timeout value whichever is earlier. ie. if it read 100 bytes it will return even if timeout (say 100mS) not reached. but what happens if there is lesser bytes? is there a interbyte timeout as in CPP here in C#? how to set it? b. Write timeout functions in same fashion with writing to port. it will return after specified bytes have written unless timeout is not reached. Am i correct in these assumptions? Do I have to use some sort of thread locking in DataReceived event thread for proper displaying of the data? (I assume that the DataReceived event thread is system handled thread and does not have control over it. Am i correct?)
-
Hi What are the things i need to look into when i use serial port class? My issue is I am getting a Timeout Exception every now and then in Reading the port. My understanding about the serial port class is as below 1. We need to set the baud rate, parity etc once 2. Timeout value (read timeout and write timeout) every time you read or write. a. Read timeout timer starts when the first characeter arrives at the hardware buffer and code will wait till all the characters arrived as per the code
comPort.Read(buffer, 0, 100);
here it will wait for 100 bytes or timeout value whichever is earlier. ie. if it read 100 bytes it will return even if timeout (say 100mS) not reached. but what happens if there is lesser bytes? is there a interbyte timeout as in CPP here in C#? how to set it? b. Write timeout functions in same fashion with writing to port. it will return after specified bytes have written unless timeout is not reached. Am i correct in these assumptions? Do I have to use some sort of thread locking in DataReceived event thread for proper displaying of the data? (I assume that the DataReceived event thread is system handled thread and does not have control over it. Am i correct?)
You must set the port name, baudrate, parity, stopbit and databit. Then if you set for example timeout 2000ms, if you call the line : comPort.Read(buffer, 0, 100); at this line will be hold for 2000ms. If in 2000ms no data received, then TimeoutException.
-
You must set the port name, baudrate, parity, stopbit and databit. Then if you set for example timeout 2000ms, if you call the line : comPort.Read(buffer, 0, 100); at this line will be hold for 2000ms. If in 2000ms no data received, then TimeoutException.
Yes. I have set the port name, baudrate, parity, stopbit and databit. and my timeout is 100mS
stancrm wrote:
at this line will be hold for 2000ms. If in 2000ms no data received, then TimeoutException.
Does this mean that the received data can be less than 100 bytes? That is if a single byte is received within the timeout period (in my case it is 100mS) there will be no timeout exception right? One more thing is that I jump to this code only when System generates a DataRecieved event as in
void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
SetTimeOuts(true);
byte[] buffer = new byte[101];
int iReadBufSize = comPort.Read(buffer, 0, 100);
string strData = String.Empty;
for (int i = 0; i < iReadBufSize; i++)
{
strData = strData + buffer[i].ToString() + " ";
}
DisplayRecievedData(buffer);
strData = "Rcd <<--: " + strData;
UpdateDisplayArea(strData);
//comPort.DiscardOutBuffer();
SetTimeOuts(true);
}
catch (Exception exp)
{
MessageBox.Show("Exception in comPort_DataReceived()" + Environment.NewLine + exp.Message);
}
}this event was registered like this when the serial port was created as
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
I observed that some times the byte[] buffer was null when I put break points there? Is it normal?
-
Yes. I have set the port name, baudrate, parity, stopbit and databit. and my timeout is 100mS
stancrm wrote:
at this line will be hold for 2000ms. If in 2000ms no data received, then TimeoutException.
Does this mean that the received data can be less than 100 bytes? That is if a single byte is received within the timeout period (in my case it is 100mS) there will be no timeout exception right? One more thing is that I jump to this code only when System generates a DataRecieved event as in
void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
SetTimeOuts(true);
byte[] buffer = new byte[101];
int iReadBufSize = comPort.Read(buffer, 0, 100);
string strData = String.Empty;
for (int i = 0; i < iReadBufSize; i++)
{
strData = strData + buffer[i].ToString() + " ";
}
DisplayRecievedData(buffer);
strData = "Rcd <<--: " + strData;
UpdateDisplayArea(strData);
//comPort.DiscardOutBuffer();
SetTimeOuts(true);
}
catch (Exception exp)
{
MessageBox.Show("Exception in comPort_DataReceived()" + Environment.NewLine + exp.Message);
}
}this event was registered like this when the serial port was created as
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
I observed that some times the byte[] buffer was null when I put break points there? Is it normal?
received data can be less than 100ms. if you want 1 byte, then use ReadByte. Set timeout to value 1000ms or greater, and read the buffer faster than 100ms. That means, if you received no data within 1000ms, there is something wrong with communication. I never use DataReceived, because the first sample from MS was while()..., set timeout 1000ms, if no data in 1000ms, you get timeoutexception, just ignore it, and start again with read.
-
received data can be less than 100ms. if you want 1 byte, then use ReadByte. Set timeout to value 1000ms or greater, and read the buffer faster than 100ms. That means, if you received no data within 1000ms, there is something wrong with communication. I never use DataReceived, because the first sample from MS was while()..., set timeout 1000ms, if no data in 1000ms, you get timeoutexception, just ignore it, and start again with read.
My data is 30 to 60 byte long My question is Will the code return with first few byte immediately when it recevies the first event for DataRecieved? (because of slight inter-byte delays?) Or it will go for reading and if found (it should... because event was generated) something in Hardware Buffer wait for the entire stream till there is no more bytes? In both case there is no chance for timeouts :confused: Is there any thing like "De register the event once it is served" ? PS: I can not say when the data will be pushed from the other side so I need to be continuously monitoring the port. Is there any other method to do this than dataReceived event?
-
My data is 30 to 60 byte long My question is Will the code return with first few byte immediately when it recevies the first event for DataRecieved? (because of slight inter-byte delays?) Or it will go for reading and if found (it should... because event was generated) something in Hardware Buffer wait for the entire stream till there is no more bytes? In both case there is no chance for timeouts :confused: Is there any thing like "De register the event once it is served" ? PS: I can not say when the data will be pushed from the other side so I need to be continuously monitoring the port. Is there any other method to do this than dataReceived event?
don't set timeout. use something like this: code will be hold at line "int dataLength = ..." until data is received, then next line will be called.
while(true)
{
int dataLength = _serialPort.Read(buffer, 0, buffer.Length);
string text = Encoding.ASCII.GetString(buffer, 0, dataLength);
Console.WriteLine(text);
} -
My data is 30 to 60 byte long My question is Will the code return with first few byte immediately when it recevies the first event for DataRecieved? (because of slight inter-byte delays?) Or it will go for reading and if found (it should... because event was generated) something in Hardware Buffer wait for the entire stream till there is no more bytes? In both case there is no chance for timeouts :confused: Is there any thing like "De register the event once it is served" ? PS: I can not say when the data will be pushed from the other side so I need to be continuously monitoring the port. Is there any other method to do this than dataReceived event?
Deepak.Prahlad wrote:
Is there any thing like "De register the event once it is served" ?
Yes - you can remove the handler in the same way you add them, but using -= instead of +=. If for example it was a Timer event you would add with:
tim.Tick += new EventHandler(tim\_Tick);
and remove it with:
tim.Tick -= tim\_Tick;
You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
-
Hi What are the things i need to look into when i use serial port class? My issue is I am getting a Timeout Exception every now and then in Reading the port. My understanding about the serial port class is as below 1. We need to set the baud rate, parity etc once 2. Timeout value (read timeout and write timeout) every time you read or write. a. Read timeout timer starts when the first characeter arrives at the hardware buffer and code will wait till all the characters arrived as per the code
comPort.Read(buffer, 0, 100);
here it will wait for 100 bytes or timeout value whichever is earlier. ie. if it read 100 bytes it will return even if timeout (say 100mS) not reached. but what happens if there is lesser bytes? is there a interbyte timeout as in CPP here in C#? how to set it? b. Write timeout functions in same fashion with writing to port. it will return after specified bytes have written unless timeout is not reached. Am i correct in these assumptions? Do I have to use some sort of thread locking in DataReceived event thread for proper displaying of the data? (I assume that the DataReceived event thread is system handled thread and does not have control over it. Am i correct?)
Here is a nice Com Class that you can use.
using System;
using System.IO.Ports;
using System.Runtime.Remoting.Messaging;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
namespace ModemAPP
{
/// <summary>
/// Routines for finding and accessing COM ports.
/// </summary>public class ComPorts { private const string ModuleName = "ComPorts"; // Shared members - do not belong to a specific instance of the class. internal static bool comPortExists; internal static string\[\] myPortNames; internal static string noComPortsMessage = "No COM ports found. Please attach a COM-port device."; internal delegate void UserInterfaceDataEventHandler( string action, string formText, Color textColor ); internal static event UserInterfaceDataEventHandler UserInterfaceData; internal delegate void UserInterfaceResultEventHandler(string strResult); internal static event UserInterfaceResultEventHandler NumberCrunchInterface; // Non-shared members - belong to a specific instance of the class. internal delegate void SerialDataReceivedEventHandlerDelegate( object sender, SerialDataReceivedEventArgs e ); internal delegate void SerialErrorReceivedEventHandlerDelegate( object sender, SerialErrorReceivedEventArgs e ); internal delegate bool WriteToComPortDelegate( string textToWrite ); internal delegate bool ReadComPortDelegate(); delegate void SetTextDeleg(string text); internal WriteToComPortDelegate WriteToComPortDelegate1; internal ReadComPortDelegate ReadComPortDelegate1; // Local variables available as Properties. private bool m\_ParameterChanged; private bool m\_PortChanged; private bool m\_PortOpen; private SerialPort m\_PreviousPort = new SerialPort(); private int m\_ReceivedDataLength; private int m\_SavedBitRate = 9600; private Handshake m\_SavedHandshake = Handshake.None ; private string m\_SavedPortName = ""; private SerialPort m\_SelectedPort = new SerialPort(); internal bool ParameterChanged { get { return m\_ParameterChanged; } set { m\_ParameterChanged = value; } }
-
Hi What are the things i need to look into when i use serial port class? My issue is I am getting a Timeout Exception every now and then in Reading the port. My understanding about the serial port class is as below 1. We need to set the baud rate, parity etc once 2. Timeout value (read timeout and write timeout) every time you read or write. a. Read timeout timer starts when the first characeter arrives at the hardware buffer and code will wait till all the characters arrived as per the code
comPort.Read(buffer, 0, 100);
here it will wait for 100 bytes or timeout value whichever is earlier. ie. if it read 100 bytes it will return even if timeout (say 100mS) not reached. but what happens if there is lesser bytes? is there a interbyte timeout as in CPP here in C#? how to set it? b. Write timeout functions in same fashion with writing to port. it will return after specified bytes have written unless timeout is not reached. Am i correct in these assumptions? Do I have to use some sort of thread locking in DataReceived event thread for proper displaying of the data? (I assume that the DataReceived event thread is system handled thread and does not have control over it. Am i correct?)
Deepak.Prahlad wrote:
Timeout value (read timeout and write timeout) every time you read or write
No, timeout is a property just like all others. You can set it once, it will hold its value.
Deepak.Prahlad wrote:
Read timeout timer starts when the first characeter arrives at the hardware buffer
No, read timeout starts when a read operation starts. The behavior you are referring to exists in Windows but AFAIK is not exposed to the SerialPort class.
Deepak.Prahlad wrote:
thread locking in DataReceived event
DataReceived is an asynchronous event; as such it is handled by a ThreadPool thread, which is not allowed to touch the Winform Controls directly. See this[^] and this[^] article. One can never be sure that all the serial data that belongs together (a "message") will be received in one go; there always could be a hick-up somewhere, causing the message to be split over two DataReceived events. One approach that often leads to success is by having some delay between the start of the DataReceived event and the actual reading of the data. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.
-
Hi What are the things i need to look into when i use serial port class? My issue is I am getting a Timeout Exception every now and then in Reading the port. My understanding about the serial port class is as below 1. We need to set the baud rate, parity etc once 2. Timeout value (read timeout and write timeout) every time you read or write. a. Read timeout timer starts when the first characeter arrives at the hardware buffer and code will wait till all the characters arrived as per the code
comPort.Read(buffer, 0, 100);
here it will wait for 100 bytes or timeout value whichever is earlier. ie. if it read 100 bytes it will return even if timeout (say 100mS) not reached. but what happens if there is lesser bytes? is there a interbyte timeout as in CPP here in C#? how to set it? b. Write timeout functions in same fashion with writing to port. it will return after specified bytes have written unless timeout is not reached. Am i correct in these assumptions? Do I have to use some sort of thread locking in DataReceived event thread for proper displaying of the data? (I assume that the DataReceived event thread is system handled thread and does not have control over it. Am i correct?)
-
Hi stancrm, OriginalGriff, DotNetCoderJunior, Luc Pattyn, PIEBALDconsult I think I solved the issue by using a thread.sleep() at the bigining of the DataRecieved() as suggested by Luc Pattyn, :thumbsup: Thanks for the help from every one! :-O :-O Regards Deepak