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.
Related
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.
I have been struggling with commincations speeds with some code.
So i want to increase the baud rate for both the code & Arduino. But if i leave the 9600 baud rate, the data stops sending & reciving properly.
So i set up a simple test program.
Arduino Code:
void setup()
{
Serial.begin(9600);
Serial.setTimeout(10);
}
void loop()
{
if (Serial.available())
{
String Data = Serial.readStringUntil('#');
if (Data == "Test")
{
Serial.println("Recived");
}
}
delay(1);
}
c# Code:
SerialPort Port = new SerialPort("COM4", 9600);
Port.Open();
if (Port.IsOpen)
{
Port.Write("Test#");
System.Threading.Thread.Sleep(1000);
String Read = Port.ReadExisting();
Port.Close();
}
So running that String Read comes back with "Recived\r\n".
Change the baud rate to 19200 and it comes back with "".
Any ideas why this is occuring?
Edit: If I use the Arduino IDE's Serial Monitor Program, this works just fine regardless of baudrate used. Its as soon as i use c# that it that this issue occurs. Which rules out hardware issues I believe.
Try sending a character at a time from the PC and use Serial.read() to read a character into a buffer in the arduino. Sometimes sending the whole text from PC at high baud rate is too much for the arduino to handle.
Thankyou for you inputs.
Think i have found a solution, although not to clear about why.
I think it was due to the Serial.Avalible() Command. Appears i needed to send though some data first to make it register the port is open.
So modifying my C# code to this: Works
SerialPort Port = new SerialPort("COM4", 9600);
Port.Open();
if (Port.IsOpen)
{
Port.Write("#");
Port.Write("Test#");
System.Threading.Thread.Sleep(1000);
String Read = Port.ReadExisting();
Port.Close();
}
Thanks a lot
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.
I need to connect to a sensor through a serial port and read some data off it. I connect to it and send the command, but nothing is returned from the device, instead a Timeout exception is thrown. Similar questions here on stackoverflow use the OnDataReceived event, i tried that and it did not work. The parameters i used to initialize and the command i send work as expected on Putty.
-- what am i missing here
void Read()
{
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
try
{
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Encoding = new ASCIIEncoding();
serialPort.ReadTimeout = 1000;
serialPort.WriteTimeout = 900;
serialPort.Open();
serialPort.WriteLine("TEMP");
MessageBox.Show("Reading");
MessageBox.Show(serialPort.ReadLine());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
serialPort.Close();
}
}
Thank you
serialPort.Handshake = Handshake.XOnXOff;
Maybe that's correct, it is pretty unusual. But real devices almost always pay attention to the hardware handshake signals, in addition to an Xon/Xoff flow control protocol. The DTR (Data Terminal Ready) and RTS (Ready To Send) signals have to be turned on before the device is convinced that it is connected to a real computer. A program like Putty will always turn them on, your program does not.
Add these two required lines:
serialPort.RtsEnable = true;
serialPort.DtrEnable = true;
And ensure that the serialPort.NewLine property correctly matches the end-of-message character used by the device. Temporarily use ReadExisting() instead to avoid getting bitten by that detail, don't leave it that way.
I would suggest that the problem is with the encoding you're using. To check if that's the problem use a sniffer of your choice to see that the bytes transferred on your application are the same as on putty.
Only be sure that you're actually trying to read the bytes when using a sniffer because if you don't they won't be shown on the output.
If that doesn't show you anything you can try to change your ReadLine() method to ReadByte() to ensure that there's no problem with the reading type that you're using.
Serial port sniffers
http://www.serialmon.com/
virtual-serial-port.org/products/serialmonitor/?gclid=CInI2ZPL_bsCFaxr7Aod8S4A8w
www.hhdsoftware.com/device-monitoring-studio
Occasionally some of my integration tests are failing with the above message. I'm using the code below to ready the port.
for(int i = 0; i < 5; i++)
{
try
{
port.Open();
if (port.IsOpen)
break;
}
catch (Exception e)
{
try
{
port.Close();
}
catch (Exception)
{}
Thread.Sleep(300);
}
}
My assumption is that because it can't be the current thread blocking the port (because it will try to close it), it must be another thread or process that has died without cleaning up properly (one of the other tests - nothing else accesses this port). Is there a way to reset the state of the SerialPort so that the new thread / process can access it again?
Thanks,
Richard
This is a flaw in the SerialPort class, it uses an internal helper thread to wait for events on the port. The source of the DataReceived, PinChanged and ErrorReceived events. The flaw is in the Close() method implementation, it doesn't wait for this helper thread to terminate. That takes time, the exact amount of time is not predictable and could be many seconds when the machine is particularly busy. The physical port doesn't get closed until this happens, opening the port before the thread exits bombs with a 'port already in use' exception. The one you get. Sleeping for 300 msec is thus not good enough.
This is not normally an issue, serial ports are not sharable devices. Closing a serial port and not exiting your program is dangerous, another process could steal the port. Also giving you this exception when you try to open it again. The normal practice is to open the port when your app starts and not close it until it terminates.
I routinely verify that the port is closed just before I instantiate a serial port. This helps if you stop debugging code without closing the serial port. Also you should wait 250 msec after opening or closing the port before you continue with your code.
try
{
if (m_SerialPort != null)
{
if (m_SerialPort.IsOpen)
{
m_SerialPort.Close();
}
}
m_SerialPort = new SerialPort(portName, dataRate, parity, databits, stopBits.One);
m_SerialPort.Open();
if (!m_SerialPort.IsOpen)
{
MessageBox.Show(string.Concat(portName, " failed to open"));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
I can't see where you close the port.
The issue for me is not here (even if you should refactor a bit the code) but probably you are calling port.Open(); when the port is still open
From MSDN
Only one open connection can exist per SerialPort object.
(I can't tell you why because I don't have enough information) Bear also in mind the the close method takes some time to actually close the port in fact you should block the main thread until the port has been close (perhaps using Thread.Join)
From MSDN
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.
for more info
http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.open.aspx
GC.SuppressFinalize should be called passing the SerialPort instance BaseStream property as the parameter and not just the SerialPort instance.
public class SerialConnection : SerialPort
{
public new void Dispose()
{
if (_isDisposed)
return;
_isDisposed = true;
BaseStream.Dispose();
GC.SuppressFinalize(BaseStream);
base.Dispose();
GC.SuppressFinalize(this);
}
The new void Dispose() of course is not the recommended way to implement IDisposable. It's merely a fix for the odd behaviour of the SerialPort class.