How to properly timeout when communicating with a serial-port device? - c#

I am using a serial port communication C# windows application. I wrote a program to get the data from the port, to manipulate it and write through the serial port.
My question is in case the unit is not powered on, the power supply is disconnected, or the unit is not responding to commands for a long time, how will I know? In my program, I have written for normal flow of execution. But in case there is no response for long time, the program keeps on waiting for a long time. I used a timer but it doesn't work properly.
Can anyone help me please?

If you are using the "SerialPort" object in C#, then you can use the ReadTimeOut and WriteTimeOut Properties.

You've got two options:
If you have a device which should be generating data you can listen on the serial port for data from and if nothing is received for a set period you can assume it is offline,
Periodically send data to your device over the serial port and if you get an exception then you will know your device is offline.

One thing that might help is if the cable you are using is wired with DTR / DSR crossed, meaning that when your program starts you raise DTR and the other device see's DSR go high, and in turn raises it's DTR, which raises your DSR.
If you are using unknown cables and communicating with devices you don't have control over, then you will have to use .Timeout.

Related

Detect if is serial port is disconnected C#

I am writing an application that uses virtual (shared) serial ports via a USB to RS232 adapter. If the user accidentally disconnects the USB adapter, my data stream stops (occasionally throwing an IO exception but not always). Normally, the user could just reconnect the port and the listener would continue. But all of the virtual port applications I have found need to be reset, then then my application must be re-initialized. I could put a read timeout in my listener but I'm curious if there isn't a clean way to detect the ports use the property changed event handler. Since it's a virtual port, I don't believe using hardware level commands will work. I have achieved the detection in a console app just using a while loop where I continually poll the ports using GetPortNames. But that just isn't practical in a forms app using a DataReceived Event Handler, especially considering all the parsing I do on the data stream. I have searched multiple sites (including this one) and no one has adequately addressed the issue. Please, any help appreciated.

Serial Port Constant Monitoring in C#

I have a program then when started looks for the serial ports available on the computer and if found would try to open those and listen to those for data.
As of now, I have a configuration file that has got all port settings along with the Port Number to listen to.
At first run I get the user to first enter the POrt No. on which the device is connected. That is recorded into the Config and is used from there one.
I would now like to change that so that when started, it scans the ports and gets the list of Serial Ports available. That part I can do with SerialPort.GetPortNames() method.
However, now I would like to ping each port and check which one has the device connected, open that port and keep listening to that port.
I can check with my device manufacturer to get the commands to ping and ACK back from device.
My Question to the experts is
Is it correct (archietecturally/technically) to keep the ports open all the time
Should that be done in a seperate thread and probably keep the thread for just serial port communications while main thread does all other jobs.
What if there are multiple devices connected to same PC. Should we keep seperate threads for each device ?
Any help or ideas would be greatly appreciated.
Thanks
Ashutosh
Is it correct (archietecturally/technically) to keep the ports open
all the time
It's normal to do that. Continually opening and closing ports is an expensive and wasteful operation. Sometimes is is used as a message framing protocol, ie. open/send/close, but a protocol that keeps the port open is surely going to perform better.
Should that be done in a seperate thread and probably keep the thread
for just serial port communications while main thread does all other
jobs.
It can be, yes. I have used such a design - create threads that attempt to open COM1-COM9 and, if the open succeeds, try to communicate with a peripheral. If the comms is successful, the handler thread messages the main thread with an object reference/pointer that can be used to communicate with the port, (and usually give user feedback, eg. check a checkbox and change its background colour from red to green).
What if there are multiple devices connected to same PC. Should we
keep seperate threads for each device ?
That's how I usually handle it, yes. I define a class that represents the port, it's protocol and state. Each port-handler thread then creates its own instance and so each port gets handled independently.

Serial port does not receive data

first of all sorry for my english :)
I have a PCI serial ports card with 2 COM ports. I am using it to receive data from another computer via serial cables. (That other computer will be named as "Sender" subsequently)
The problem is, when cables are plugged in to my computer and i reboot (Windows 7),(Sender is still running...), then my PC does not receive any data. But when i reboot and after that I connect the cables in my PC it starts to receive. I temporary solved it by firstly starting my PC and then the Sender PC, but it's really a terrible solution...
I tried to connect my PC with a different computer (different sender), and it works good.
So I think that the problem can be with my main Sender. Maybe it is waiting for some signal from my computer that the ports are ready? Or Windows 7 can block my serial ports card (standard COM1 which is not on that card works fine) during reboot? Maybe I have to manually send some signal to Sender that I'm ready? By the way, I cannot, in any way, make adjustments to the Sender PC; only turn it on or off.
I do not have any expertise on serial ports so I really don't know what to do, or what I'm currently doing wrong.
Any ideas? (my receiver application is programmed in C#)
UPDATE: I forgot to mention that when the cables are connected... reboot... then ports can't be even opened.
This is a problem caused by the handshake signals. The Sender's DSR (Data Set Ready) is wired to your DTR (Data Terminal Ready). It will see the signal turn off when you reboot, now it gets sulky about sending anything because it thinks that you are no longer connected. You can exacerbate this problem by not setting the SerialPort.DtrEnable to true in your program, that's very commonly overlooked.
Same story with the RTS and CTS signals, if you set the SerialPort.Handshake property to anything else than Handshake.RequestToSend (the recommended value) then it now becomes your job to control the signal. You must set the RtsEnable property to true explicitly in your code.
It tends to work by accident, you're apt to use another program to test the connection. Like HyperTerminal or Putty, they'll turn the signals on for you and your program will now operate correctly.
This kind of bug could of course also exist in Sender. If you can't fix that code then all you can do is rewire the cable. Connect RTS to DSR and CTS on the Sender side to it will always see the signals turned on.
Problem was in card... I changed for new one and now its working correctly. Looks like the card was too old for Windows 7.

How to autodetect connection of serial COM port c#

I have application to communication with device. Device is connected through serial COM port. My app can comunicate with device.
I need some method / event, that can scan COM ports through running app. When I'll connect device to PC - method / event will print MessageBox with message "connected", or something like that.
I found something like this:
comPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
But it doesnt work.
I'm not sure if you are trying to auto-detect which port a device is connected to, or auto-detect whether a device is connected to a specific port.
In both cases though, the principle is the same:
you enumerate the the serial ports using: SerialPort.GetPortNames if you need to determine the port, or skip to the Step 2 if you already know the port
for each port in the collection you open a connection by creating a new SerialPort object for it, and by calling Open
for each open connection you attempt to write/read from the port the sequence of data that determines whether your device is attached
for each open connection if the data read times out then there is no device attached to the port; otherwise, if you get back what you expect you know your device is attached
for each port, close the connection using Close on the SerialPort object.
Performing the above at any given point will tell you whether your device is attached at that point, and which port it is attached to.
If you need to do presence detection continuously, then you will probably want to create a timer and perform this test periodically (every 30 seconds, or every 2 minutes - depending on the latency you are willing to accept).
NOTE
As others have indicated in the answers, you will want to run the serial port detection code asynchronously so as not to block your main application while scanning the ports. The scanning is guaranteed to take a while because of the time-outs of the ports that have no device attached.

Getting error only first time I communicate with my SerialPort later on its working fine

I have a USB device (e.g. barcode scanner etc.)
I communicate with it using SerialPort (which is found nicely from toolbox of VS2008)
My problem is:
After starting my PC when starting my application for the first time it is hanging up or stuck up or going into not responding mode when it tries to sending a string to the serial port.
To come out of it I just remove the USB cable from the USB port of my PC.
As soon as I remove the cable I getting below error message:
If I press the Continue button plug the removed USB cable back in my application working fine.
Note: I am getting this error only when I start my app first time after starting or restarting my PC. Afterwards it's working fine as I wanted.
Note: Another thing to consider is that if I put my code in try and catch
I catch the exception only when I remove the USB cable from my PC.
Edit:
After restarting my PC, if I do
plug out and then plug in the USB cable from the USB Port of the PC, and then
I start my App then it's working fine
It seems to me that the control is going inside an infinite loop when i try sending a string to the serial port at the very first time after starting of the PC.
See the details of my code over here
The 90% odds here are that you are trying to work around a common deadlock scenario with SerialPort. It is common to get triggered when you use Invoke() in your DataReceived event handler. If you then use Close() in your main thread while the port is busy receiving data then a deadlock is common. Close cannot complete until the DataReceived event handler completed running, Invoke() cannot complete because the main thread is stuck in the Close call. Jerking out the connector works because the ThreadExceptionDialog pumps messages, allowing the Invoke to complete.
A simple workaround is to use BeginInvoke() instead. Just not calling Close is fine too, Windows takes care of it when your program terminates. Some sort of controlled shutdown of your app so that you don't lose anything sent by the serialport device is best.
You must close the serial port in the FormClose event. Because, port is once open your application and close the port on the application end

Categories

Resources