C# can fail to open STMicro virtual COM port - c#

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.

Related

Looping through com ports

I am writing an application that will loop through my computer's com ports. The issue I am having is one of the com ports is opened on PC startup by another process which causes an exception to be thrown:
System.InvalidOperationException: 'The port is already open.'
I have successfully handled the exception but it seems to break the foreach loop once it hits the exception and will not continue to the other ports. Am I handling the expectation correctly by having the try catch block inside of the foreach loop?
private void Rescan()
{
bool error = false;
int baud = 115200;
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
try
{
comPort.PortName = port;
comPort.BaudRate = baud; //convert Text to Integer
comPort.Open();
comPort.DtrEnable = true;
comPort.DataReceived += SerialPortDataReceived;
System.Windows.MessageBox.Show(port.ToString());
}
catch (InvalidOperationException e)
{
System.Windows.MessageBox.Show("");
}
}
}
I know it can be dangerous and poor programing practice to open ALL com ports that are not mine, so my end goal is to open each com port and write some string like "ID_DEVICE" which will then prompt a response from the firmware of the device I am trying to connect to (Arduino). If the com port does not have a proper response then my application will close that specific port and only leave open the ports that had the proper response.
I think John is right, you have to instanciate a new serial port for each port name. If you register an event, don't forget to unsubscribe. F.e. you can store the open comports in an collection to be able to close, deregister the event and dispose the serial port.

SerialPort.Write() method is hanging

I'm quite new with serial ports. And I'm trying to write some data to serial ports created by this tool called com0com. But like the title says, it hangs when it tries to write (both Write() & WriteLine()) to the serial port (opening and closing the port is working though). I can also find the port in the Device Manger.
I tried with different baud rates, but it is still hanging. I also delayed the execution for 1 seconds before writing to the port but this didn't work either.
This is what I have tried so far:
SerialPort mySerialPort = new SerialPort("COM15", 115200, Parity.None, 8, StopBits.One);
mySerialPort.Handshake = Handshake.None;
mySerialPort.Open();
try
{
System.Threading.Thread.Sleep(1000);
mySerialPort.WriteLine("p");
}
catch (Exception ex)
{
throw;
}
finally
{
mySerialPort.Close();
}
The exception was not thrown at all. It just hangs at mySerialPort.WriteLine("p");. I've been trying to solve this for days. I would be really appreciated if you could point me out what I've been missing here. Thanks.

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.

SerialPort.Open() throws IOException - Insufficient system resources exist to complete the requested service

I have a .NET 4 Windows service I've written that periodically (usually once a day) communicates with an external device over a serial port. All in all the service works great, but for one customer, every now and then, a call to SerialPort.Open() throws the following exception:
System.IO.IOException: Insufficient system resources exist to complete the requested service.
at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
Based on the exception, would would think that the server is running low on resources, but that doesn't seem to be the case. The CPU is more or less idle and there's plenty of memory and disk.
There are lots of mentions online of SerialPort.Open() throwing other IOExceptions and I have implemented Zach Saw's SerialPortFixer, but it appears it fixes a different issue.
Here's an example of what I'm doing (greatly simplified). A couple of instances of this class (using different serial port names) are in memory at all times and then the Run() method is called approximately once a day for each instance.
public class Collector
{
private SerialPort _port;
private string _portName;
public void Run()
{
try
{
// Run Zach Saw's IOException workaround
SerialPortFixer.Execute(_portName);
using (_port = new SerialPort(_portName, 9600, Parity.None, 8, StopBits.One))
{
_port.DataReceived += PortDataReceived;
_port.ErrorReceived += PortErrorReceived;
_port.Handshake = Handshake.None;
_port.DtrEnable = true;
_port.RtsEnable = true;
_port.Open();
// Do the stuff
_port.Close();
}
}
catch (Exception e)
{
// Handle exception
}
}
private void PortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
// Do other stuff
}
private void PortErrorReceived(object sender, SerialErrorReceivedEventArgs e)
{
// Log error
}
}
Any help would be appreciated.
The answer to this question is that the serial port server used by the client was a wi-fi version (Moxa NPort W2150 Plus) and it turns out the exception occurs when the serial port server has wi-fi connectivity problems.
Had the same problem with NPort 5150. Increasing Network timeout (in NPort Administrator) solved my problem.
I recently had the same problem, the resolution for me was that I was accidentally using a straight-through DB9 cable with a device that required a null modem DB9 cable. Once I swapped to a null modem cable the error disappeared and the device functioned properly.
When I called Moxa, they suggested some other things to try that might lead to this problem:
Anti-virus software could be interfering with the communication
Try using the Driver Manager Utility rather than Nport Administrator when setting up the COM ports (on Windows machines)
I had this error and my problem was that the NPort Administration found and programmed the serial ports but the IP4 Address of the network card was set to DHCP. I think this happened during a system update.
Recovery from that:
Add a TCP/IP address in the subnet of the network interface
Reassign the serial ports in NPort Administration

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