COM端口被拒绝

嗨我正在尝试使用COM端口使用modbus协议读取一些寄存器,一切正常,直到我重新启动modbus从设备,然后我有错误,com被拒绝,我可以做的是或重新启动计算机或插入并返回’ usb到com转换器’。 似乎此设备无法正确处理com端口。

using (port = new SerialPort(comPort)) { ushort[] registers = null; try { port.BaudRate = boudRate; port.DataBits = 8; port.Parity = Parity.None; port.StopBits = StopBits.One; port.Open(); // modbus reading registers port.Close(); return registers; } catch (Exception e) { Logs.AddToLog(e.Message); return registers; } } 

如果您使用的是FTDI USB /串行适配器,则可以直接从托管包装器( FTDI托管驱动程序包装器 )检索状态,并根据连接状态重新初始化串行端口。

原谅我对FTDI设备缺乏经验,但这应该重置你的R-232适配器:

 FTD2XX_NET.FTDI device = new FTD2XX_NET.FTDI(); string port; device.GetCOMPort(out port); if (!string.IsNullOrEmpty(port) && (port.Equals(target)) && device.IsOpen) { device.CyclePort(); device.ResetDevice(); device.ResetPort(); } 

根据我的理解, device.CyclePort()将关闭所有活动连接(调用FT_CLOSE ),卸载USB设备,并从usb总线重新枚举设备。 这应该与您物理移除并重新插入适配器完全相同。

另外,根据FTDI设备库的Perl包装器的文档:

与其他总线控件一样,在CyclePort之后有一个5-8秒的等待时间,其中任何需要直接连接到设备的API调用(如GetSerialByIndex()等)将在FT_INVALID_HANDLE失败,直到它完全稳定。 应用程序应考虑此等待时间,或设置轮询循环以检测返回状态的更改。

我有类似的经历,FTDI设备会进入一个我无法与之通信的状态,除非我实际拔掉它。 Greg的回答帮助我找到了解决方法。

Greg对FTDI托管包装器的引用非常有用,但他提供的代码片段并不完全存在,因为实际引用FTDI设备需要更多代码。 以他的想法为出发点,我从FTDI中修改了一些示例代码并编写了这个函数。 它能够在没有物理干预的情况下将我的FTDI设备恢复到工作状态。

 ///  /// Attempts to reset an attached FTDI device and returns true if successful. Note that a /// 5-8 second delay is recommended after the reset. ///  ///  private bool ResetFTDI() { UInt32 ftdiDeviceCount = 0; FTD2XX_NET.FTDI.FT_STATUS ftStatus = FTD2XX_NET.FTDI.FT_STATUS.FT_OK; // Create new instance of the FTDI device class FTD2XX_NET.FTDI myFtdiDevice = new FTD2XX_NET.FTDI(); // Determine the number of FTDI devices connected to the machine ftStatus = myFtdiDevice.GetNumberOfDevices(ref ftdiDeviceCount); // Check status if (ftStatus != FTD2XX_NET.FTDI.FT_STATUS.FT_OK) { Log.WriteLog("Failed to get number of FTDI devices [" + ftStatus.ToString() + "]"); return false; } // If no devices available, return if (ftdiDeviceCount == 0) { Log.WriteLog("Failed to find any FTDI devices [" + ftStatus.ToString() + "]"); return false; } // Allocate storage for device info list FTD2XX_NET.FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTD2XX_NET.FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount]; // Populate our device list ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList); if (ftStatus != FTD2XX_NET.FTDI.FT_STATUS.FT_OK) { Log.WriteLog("Failed enumerate FTDI devices [" + ftStatus.ToString() + "]"); return false; } // Open first device in our list by serial number ftStatus = myFtdiDevice.OpenBySerialNumber(ftdiDeviceList[0].SerialNumber); if (ftStatus != FTD2XX_NET.FTDI.FT_STATUS.FT_OK) { Log.WriteLog("Failed to open device [" + ftStatus.ToString() + "]"); return false; } // Finally, reset the port myFtdiDevice.CyclePort(); return true; } 

上面的Log对象是我项目的内部对象,所以替换任何适合你的对象。

一些进一步的研究也出现了这个问题 。 在答案中,Zach Saw引用了他在.NET SerialPort通信中发现的问题。 我将尝试他的解决方案,我将在这里回复,如果这完全解决问题,因为我认为上述是一个绑带。