问题
I've been working with the SerialPort class a lot lately. Currently I'm trying to figure out the proper way to check if a device is connected to the comm port my application uses. Is there any proper way to check if a device is connected to the comm port? My current method is as follows:
while (isReading == true)
{
try
{
received += serialPort.ReadExisting();
if (received.Contains('>'))
isReading = false;
}
catch (Exception e)
{
}
if (tick == 10000)
if (received == "")
{
Console.WriteLine("No Data Received. Device isn't connected.");
isReading = false;
}
tick++;
}
Console.WriteLine(received);
It works but I feel it's a little hacky and unreliable. I can keep it if need be but I'd like it if there's a proper alternative to doing this.
Edit: I actually have to set the tick value to about 10,000 to ensure it's reliable. Otherwise I fail to receive data on occasion. Even setting it to 1000 or 5000 is unreliable. Even then, it's not guaranteed to be reliable across multiple machines.
回答1:
I too need to work with serial ports, and believe me they are a pain. My method to check if a device is connected usually revolves around issuing a polling command. While you method may work, I cant help but be reluctant to use a while loop when an event will suffice.
The .NET serial port class offers some useful events:
Serial.DataReceived
Serial.ErrorReceived
and Serial.Write
Usually I would issue a polling command at a specified interval to ensure the device is connected.
When the device responds it will fire the DataReceived
event, and you can deal with the response accordingly (along with any other neccessary data). This can be used in conjunction with a simple Timer or incremented variable to time the response. Note you will need to set the ReadTimeout
and WriteTimeout
value appropriately. This, along with the ReadExisting
and/or ReadLine
method may be of use in your DataReceived
event handler.
So, to summarize, (in pseudo code)
Send Polling command, Start Timer
Timer to CountDown for a specified time
If Timer fires, then assume no response
If DataRecieved fires (and expected response) assume connection
(of course handle any specific Exceptions (e.g TimeOutException, InvalidOperationException)
回答2:
Unfortunately with serial ports, there's no proper way to determine if a certain device is connected. You could write a magic message that only your device would respond correctly to, but as described in this answer, this method could cause problems for other connected devices.
Ultimately, you just have to depend on the user selecting the correct port.
Also, if you happen to lose connection to the device, you would only know when you fail to read/write to it. In this case, just throw a LostConnection event.
回答3:
I would agree that is a hacky because any device could be connected and sending '>'; but that doesn't mean its your device.
Instead, be dynamic and use something like SerialPort.GetPortNames and WMI Queries to interrogate the devices plugged into the COM ports.
You could use this example as a starting point.
After reading documentation and examples, you should be able to create a list of all device information that registers drivers on the computer and their connected COM port.
Edit:
Since the device doesn't register itself, consider looking at the product drivers for Visual Studio that might make your job a lot easier.
来源:https://stackoverflow.com/questions/17595992/c-sharp-serial-port-check-if-device-is-connected