拔下USB当COM端口将消失 [英] COM port disappears when unplugging USB

查看:403
本文介绍了拔下USB当COM端口将消失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我原型一种基于Arduino坞站的片剂,使用USB端口作为接口。这意味着我需要支持插入/拔出USB连接器上的平板电脑的应用程序运行时的能力。

I am prototyping a sort of Arduino-based docking station for a tablet, using the USB port as connector. This means I need to support to ability to plug/unplug the USB connector while the application on the tablet is running.

在平板电脑上运行C#应用程序(.NET 4.5的Win7 64位),其中我连接到Arduino乌诺。当应用程序启动我循环使用所有可用的COM端口:

The tablet runs a c# application (.net 4.5 on Win7 64 bit) in which I am connecting to the Arduino Uno. When the application is launched I loop all available COM ports using:

var ports = SerialPort.GetPortNames(); // -> [COM3,COM4,COM8]
foreach (var port in ports)
{
     var serial = new SerialPort(portname, baudRate);
     //attempt handshake and connect to right port
}

这做工精细,但如果我拔掉并重新插入USB电缆并重新尝试重新连接到Arduino(而应用程序仍在运行),Arduino的端口(COM8)不再列出:

This work fine, but if I unplug and replug the USB cable and reattempt to reconnect to the Arduino (while the application is still running), the Arduino port (COM8) is no longer listed in:

SerialPort.GetPortNames(); // -> [COM3,COM4] and no COM8

即使重新启动应用程序(与Arduino的重新插入),将导致只有[COM3,COM4]被列出。

Even restarting the application (with the Arduino replugged) will result in only [COM3,COM4] being listed.

只有这样,才能拿回来工作是拔出并重新插上Arduino的,而应用程序的没有运行

The only way to get it back to work is to unplug and replug the Arduino while the application is not running.

什么混淆我的是,当我插上Arduino的乌诺启动应用程序之后,SerialClass并识别新添加的端口,并允许我连接。

What confuses me is the fact that when I plug in the Arduino Uno after starting the application, the SerialClass does recognize the newly added port and allows me to connect.

当我拔下,并在应用程序运行时,重新插入该设备只出现问题。看来,尽管到(在设备管理器中手动在code或)重置COM端口的能力,在SerialClass(和本地Win32_SerialPort - 我查了这一点),不承认这一点,除非我重新启动应用程序

The problem only occurs when I unplug and replug the device when the application is running. It seems that despite the ability to reset the COM port (in code or manually in device manager), the SerialClass (and native Win32_SerialPort - I checked this too) do not recognize this, unless I restart the application

可能是什么原因呢?我怎样才能确保我的应用程序可以重新连接到该端口?是否有使用的SerialPort处理的USB连接器的任何替代方案?

What could be the reason for this? And how can I make sure that my application can reconnect to that port? Are there any alternatives to using the SerialPort to handle the USB connector?

推荐答案

我发现可以处理插拔一个的SerialPort的解决方案。

I found a solution that can handle plugging and unplugging a SerialPort.

首先,它需要使用 SafeSerialPort ,它允许你配置串行端口正确

First of all, it requires the use the SafeSerialPort, which allows you to dispose the serial port properly.

SafeSerialPort serialPort;

private void Connect()
{
    string portname = "COM8";
    serialPort = new SafeSerialPort(portname, 9600);
    serialPort.DataReceived += port_DataReceived;
    serialPort.Open(); 
}

其次,您需要使用 LibUsbDotNet 检测是否一个​​USB装置被连接或断开。这将让您选择是否连接到设备或重置的COM端口。

Second, you need to use LibUsbDotNet to detect whether a USB device is connected or disconnected. This will allow you to determine whether to connect to the device or reset the COM port.

public UsbDevice MyUsbDevice;

//Find your vendor id etc by listing all available USB devices
public UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x2341, 0x0001);
public IDeviceNotifier UsbDeviceNotifier = DeviceNotifier.OpenDeviceNotifier();
private void OnDeviceNotifyEvent(object sender, DeviceNotifyEventArgs e)
{
    if (e.Object.ToString().Split('\n')[1].Contains("0x2341"))
    {
        if (e.EventType == EventType.DeviceArrival)
        {
            Connect();
        }
        else if(e.EventType == EventType.DeviceRemoveComplete)
        {
            ResetConnection();
        }
    }
}

最后,处置的SerialPort将确保它是由Windows中的 HKEY_LOCAL_MACHINE \ HARDWARE注册\ DEVICEMAP \ SERIALCOMM ,即 SerialPort.GetPortNames()可以重新检测端口。

Finally, disposing the SerialPort will makes sure it is registered by Windows in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM, meaning that SerialPort.GetPortNames() can re-detect the port.

private void ResetConnection()
{
    try
    {
        //Send any data to cause an IOException
        serialPort.Write("Any value");
    }
    catch (IOException ex)
    {
        //Dispose the SafeSerialPort
        serialPort.Dispose();
        serialPort.Close();
    }
}

在这个过程中,你可以简单地重新连接到COM端口当USB设备连接,而不需要重新启动应用程序。

After this process, you can simply reconnect to the COM port when the USB device is connected without the need to restart the application.

全部code:

using LibUsbDotNet;
using LibUsbDotNet.DeviceNotify;
using LibUsbDotNet.Info;
using LibUsbDotNet.Main;    

SafeSerialPort serialPort;

            public SerialPortTest()
            {
                Connect();

                UsbDeviceNotifier.OnDeviceNotify += OnDeviceNotifyEvent;
            }

            private void Connect()
            {
                string portname = "COM8";
                serialPort = new SafeSerialPort(portname, 9600);
                serialPort.DataReceived += port_DataReceived;
                serialPort.Open(); 
            }

            private void ResetConnection()
            {
                try
                {
                    serialPort.Write("Any value");
                }
                catch (IOException ex)
                {
                    serialPort.Dispose();
                    serialPort.Close();
                }
            }


            void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                Console.WriteLine(serialPort.ReadExisting());
            }

            public UsbDevice MyUsbDevice;

            //Vendor ID etc can be found through enumerating the USB devices
            public UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x2341, 0x0001);
            public IDeviceNotifier UsbDeviceNotifier = DeviceNotifier.OpenDeviceNotifier();
            private void OnDeviceNotifyEvent(object sender, DeviceNotifyEventArgs e)
            {
                //if this is your usb device, in my case an Arduino
                if (e.Object.ToString().Split('\n')[1].Contains("0x2341"))
                {
                    if (e.EventType == EventType.DeviceArrival)
                    {
                        Connect();
                    }
                    else
                    {
                        ResetConnection();
                    }
                }
            }

这篇关于拔下USB当COM端口将消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆