簡體   English   中英

COM端口被拒絕

[英]COM port is denied

嗨我正在嘗試使用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設備會進入一個我無法與之通信的狀態,除非我實際拔掉它。 Greg的回答幫助我找到了解決方法。

Greg對FTDI托管包裝器的引用非常有用,但他提供的代碼片段並不完全存在,因為實際引用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對象是我項目的內部對象,所以替換任何適合你的對象。

一些進一步的研究也出現了這個問題 在答案中,Zach Saw引用了他在.NET SerialPort通信中發現的問題。 我將嘗試他的解決方案,我將在這里回復,如果這完全解決問題,因為我認為上述是一個綁帶。

如果您使用的是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而失敗,直到它完全穩定。 應用程序應考慮此等待期,或設置輪詢循環以檢測返回狀態的更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM