【问题标题】:COM port is deniedCOM 端口被拒绝
【发布时间】:2012-12-07 11:52:40
【问题描述】:

您好,我正在尝试使用 COM 端口使用 modbus 协议读取一些寄存器,一切正常,直到我重新启动 modbus 从设备,然后我有错误 com 被拒绝,我可以做的是或重新安装计算机或拔出并回到'usb to 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;
   }
}

【问题讨论】:

  • 你得到了什么错误(你从哪里得到的)?
  • 它工作得很好,但是当我重新启动我的 modbus 从站并尝试再次读取时,我遇到了这个 COM 端口被拒绝的异常
  • 您已将其包装在 using 语句中,因此端口应该关闭,但您可能需要检查 .IsOpen 以确保:msdn.microsoft.com/en-us/library/…
  • 我还注意到 using 语句中没有 SerialPort port。您将无法在此之外使用port,因为它将被丢弃。改成using (SerialPort port = ...是否有效
  • 关闭后多快尝试再次打开?

标签: c# serial-port


【解决方案1】:

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

请原谅我缺乏使用 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 包装器的文档:

与其他总线控制一样,有一个 等待 5-8 秒后 任何 API 调用的 CyclePort 需要直接连接到 设备,例如 GetSerialByIndex() 等,将因 FT_INVALID_HANDLE 而失败 直到完全稳定。 申请应考虑 这个等待期,或设置轮询 循环检测回报的变化 状态。

【讨论】:

  • 好的,我怎样才能在我的情况下使用这些 dll 来防止这个错误?
  • 即使这样也无济于事:FTDI myFtdiDevice = new FTDI(); myFtdiDevice.CyclePort(); myFtdiDevice.ResetDevice(); myFtdiDevice.ResetPort(); myFtdiDevice.RestartInTask(); myFtdiDevice.Rescan(); myFtdiDevice.Close();
  • 不,首先什么是目标?其次,我之前检查过很多次,ifIsOpen,没有打开,但是当我尝试打开时得到了被拒绝的异常,所以我什至在这个'if'statetmant中设置了true并且仍然无法打开端口,但是当我重置时转换器,拔出并重新插入,然后它就可以工作了。
  • target 是您遇到问题的通信端口的名称。这只是一个简单的检查,以确保您没有尝试将 FTDI 驱动程序与非 FTDI 设备一起使用。
【解决方案2】:

我有过类似的经历,即 FTDI 设备会进入我无法与之通信的状态,除非我物理拔掉它。 Greg 的回答帮助我想出了一个解决方法。

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

/// <summary>
/// Attempts to reset an attached FTDI device and returns true if successful.  Note that a
/// 5-8 second delay is recommended after the reset.
/// </summary>
/// <returns></returns>
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 对象是我的项目内部的,所以用适合你的东西替换。

还发现了一些进一步的研究this question。在答案中,Zach Saw 提到了他在 .NET SerialPort 通信中发现的一个问题。我将尝试他的解决方案,如果这完全解决了问题,我会在这里发帖,因为我认为上述内容是一种创可贴。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2019-05-16
    相关资源
    最近更新 更多