How to check if a Serial port is disconnected in c# - c#

I want to check if a Serial port is disconnected or not after clicking a button in C# WinForms.
Eg:
private void btn_Click()
{
if("code to check device disconnected")
{
Do this;
}
else
{
Do this;
}}
PS: Is there any way to check that the device is disconnected when the application is running.
SerialPinchanged, ErrorRecieved, DataRecieved don't help.
Thank you in advance

It depends on the specifications of the target device connected to the COM port.
For example, if RTS/CTS or DTR/DSR are cross-connected, or if the device equivalent to a modem has a DCD or RI valid signal line, and the CTS/DSR/DCD/RI signal line shows valid connection information. , There may be a case where there is a command/response specification for health check or keep alive.
As an alternative, if the COM port is a USB Serial converter, you can check whether or not the device with the corresponding VID and PID exists, but make sure that the device is actually connected at the end of the converter. There is no guarantee.

It is simple logic that whenever SerialPort is disconnected, serialPort.IsOpen turns to false.
private void btn_Click()
{
if(!SerialPort.IsOpen)//If SerialPort is not open
{
Do this;
}
else//Else if SerialPort is open
{
Do this;
}
}

Related

C# can fail to open STMicro virtual COM port

I have an issue with opening an STMicro USB virtual COM port.
When I plug the device into my PC, the COM port appears as it should, and the Windows Device Manager indicates it is working properly.
I have a C# program on the PC which selects and opens this port.
However, in about 1 in 10 attempts, the PC program sticks on the port.open() command, and after about half a minute, returns with the error "The semaphore timeout period has expired".
I have written a tiny C# program that does nothing more than open the port. This still gives the behaviour noted.
public partial class Form1 : Form
{
SerialPort port = new SerialPort();
string portName = "COM1"; // Give it a default to start with
public Form1()
{
InitializeComponent();
// Populate the COM port selector combobox with available port names
cmbPortSelect.Items.Clear();
string[] activePorts = SerialPort.GetPortNames();
foreach (string availablePort in activePorts)
{
cmbPortSelect.Items.Add(availablePort);
}
// Declare the serial port
port = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
port.ReadTimeout = 100;
}
private void cmbPortSelect_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbPortSelect.SelectedIndex != -1)
{ // It will get set to -1 (i.e. no selection) in the catch below - we don’t want this selected item change to do anything
if (port.IsOpen) port.Close();
port.PortName = (string)cmbPortSelect.SelectedItem;
System.Threading.Thread.Sleep(50);
try
{
port.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
cmbPortSelect.SelectedIndex = -1; // Clear the selected item box
}
}
}
}
If instead of using my C# program to open the port, I use the communications program PuTTY, it works every time.
In addition, if I plug in a device with an FDTI USB virtual COM port, it also works every time.
I'm using Windows 7, with the STMicro VCP drivers ver 1.3.1, but the same behaviour occurs with Windows 10 and the generic Microsoft drivers, which STMicro recommend we use.
There is a version 1.5.1 drivers for Windows 7, but when I installed them, it reported that they had installed correctly, but the Device Manager still reported ver 1.3.1.
Has anyone noted any similar behaviour?
That is seemed to be a timing issue. Try to increase your delay from 50 to, say, 200 ms and check the difference. As the doc says: The best practice for any application is to wait for some amount of time after calling the Close method before attempting to call the Open method, as the port may not be closed instantly., sadly, there is no actual time specified.

Problems enabling dtr in my serial communication program

I'm making a program which communicates with a serial port(RS232 mainly but in this instance I'm using a usb device). Right now I'm having a problem when enabling DTR.
private void CheckBox_DTR_CheckedChanged(object sender, EventArgs e)
{
if(COMport != null)
{
if (CheckBox_DTR.Checked)
{
COMport.DtrEnable = true;
}
else
{
COMport.DtrEnable = false;
}
}
}
In this part of my code I'm enabling DTR if checkbox gets checked. When I checked the pin voltage everything seems to be ok because voltage increases when I enable it. But there's the problem: when I enable DTR using other terminals the device throws out some info but when I do this with my program it doesn't send that info.
My program
Other Serial Terminal
As you can see other terminal has some additional info that device sends out upon enabling DTR. So I'm not completely sure what should I do to receive that info from the device(do I need some additional code or something)...
Generally, when using DTR you need to turn hardware handshaking on. I would try setting COMport.Handshake = Handshake.XOnXOff;.
According to MSDN here:
Data Terminal Ready (DTR) is typically enabled during XON/XOFF software handshaking and Request to Send/Clear to Send (RTS/CTS) hardware handshaking, and modem communications.

how to detect whether a device is connected to serial port or not in c#

I've developed a simple windows form application in c# which is used to send and receive data using serial ports. but when I click my READ button while there is no device connected, the whole application stops working an I have to close it with force! so I need a method to recognize whether a device is connected or not before I click on READ button. please help me get through it.
private void button2_Click(object sender, EventArgs e)
{
try
{
textBox2.Text = serialPort1.ReadLine();
}
catch (TimeoutException)
{
textBox2.Text = "Timeout Exception";
}
}
In this case I found my way out of it! I just Changed ReadLine to ReadExisting in try block and application didn't stop working even with no device connected! But still no way to find whether a device is connected!

IO operation aborted error thrown while reading serial port

We are trying to read data written by an external device (weighing scale in this case) connected to serial port using .Net serial port class.
First we initialize the serial port as below:
InitializeSerialPort()
{
if ((serialPort != null) && (serialPort.IsOpen))
{
serialPort.Close();
serialPort.Dispose();
serialPort = null;
}
serialPort = new SerialPort("COM2", 9600, Parity.None, 8,
StopBits.One) { Handshake = Handshake.None };
serialPort.DataReceived += serialPort_DataReceived;
serialPort.NewLine = "\r";
}
We are using background worker thread to poll the device on continuous interval by sending a command(understood by the weighing scale) on the serial port. As soon as we send the command the device connected to serial port reacts with a response output. We call ReadLine API of SerialPort class to get the data present on the serial port written by the device in the DataReceived event as shown in the code snippet below :
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
data = serialPort.ReadLine();
}
catch(System.IO.IOException ex)
{
//since serial port reading threw an error so there is no value to be parsed hence exit the function.
return;
}
//if no error then parse the data received
}
I'm using System.IO.Ports.SerialPort class of .Net framework 4.0. I can see a number of people posting this issue on other forums but with no specific resolution. Some of them terming .Net Serial port class as buggy which has not been fixed by Microsoft till date. One of the forums where this error is mentioned is here
I also tried the solution posted here but of no help. I need some input if any one else has come across this issue or its resolution.
We were able to solve this problem by locking the code inside serialPort_DataReceived method.
Object lockObject = new Object();
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
lock(lockObject)
{
try
{
data = serialPort.ReadLine();
}
catch(System.IO.IOException ex)
{
//since serial port reading threw an error so there is no value to be parsed hence exit the function.
return;
}
}
//if no error then parse the data received
}
We had set the polling interval to poll the device connected on serial port as 10 seconds. Possibly the entire code present inside serialPort_DataReceived method was sometimes taking more than 10 seconds. We were not able to exactly establish this fact as it was not happening every time may be.
So we locked the entire piece of code inside serialPort_DataReceived method using lock keyword in C# to ensure that the new execution for new data received from serial port doesn't start unless the older reading hasn't finished. The issue got resolved after implementing this code on trial and error basis. Hope this helps others as well if they come across such an issue.

GPS serial port searcher

I try to search my serial port of my GPS on my tablet (Windows CE).
I know that this is on "COM 3" but I want the program to find this by itself. I mean run in a loop (for) on all ports and search for this.
My question is which "if" I need to write to tell the program "this is my GPS port".
Thank you all.
Gps as i know works with a physical or virtual serial com port (ie com via usb). Since only one application can open a com port at a time there should be no program using gps while searching for the gps-port.
You already gave the answer "loop (for) on all ports and serche for".
Note the example below is an untested scetch how it could work. Feel free to update this wiki page to fix possible errors and add missing functionality.
public string FindGpsPort()
{
foreach(string portname in System.IO.Ports.SerialPort.GetPortNames())
{
// using to make shure that the testport is closed after test
using (SerialPort testport = new SerialPort(){PortName = portname})
{
// maybe neccessary to set baudrate, parity, ... of com port
testport.Open();
// to do if error or exception this is not the
// gps port or some software already uses the gps-port
// to do: read some data from port and verify if it is GPS-Data
// if valid return portname ;
}
}
// All com ports tried but not found. throw exception or return error code
return null;
}

Categories

Resources