1

我正在尝试通过在 Linux 上使用 FTDI D2xx 驱动程序与 Thorlabs TDC001 控制器(apt - dc 伺服控制器)进行通信。但是,当我发送写入命令时,会出现很大的延迟(1-2 秒),直到命令在 TDC001 上实际执行。特别是,当连接的线性平台正在移动并发送新的位置命令时,可以观察到这一点。舞台真正改变方向需要 1-2 秒。此外,如果我请求 DCSTATUSUPDATE(它给出位置和速度)然后读出 FTDI 的队列,我没有得到正确的数据。只有当我在请求和读取之间等待 1 秒时,我才会得到(正确的)数据,但只是过去的数据。我为此案例添加了 C++ 代码。我需要实时数据和更快地执行闭环控制的编写命令。

我不确定问题出在 Thorlabs 还是 FTDI 一方。一切正常,除了大的延迟。还有其他命令,例如 MOVE_STOP,它们会立即响应。此外,如果我在完成归位后立即发送新的位置命令,它会立即执行。每当我请求 FT_GetStatus 时,Tx 或 Rx 队列中除了 DCSTATUSUPDATE 的 20 个字节外,没有其他内容。

D2XX 和 APT 通信协议的参考资料可以在这里找到:

FTDI 程序员指南

Thorlabs APT通信协议

初始化函数:

bool CommunicationFunctions::initializeKeyHandle(string serialnumber){
  //INITIALIZATION//
  /*
   * This function initializes the TDC motor controller and finds its corresponding keyhandle.
   */
  keyHandle = NULL;

  // To open the device, the vendor and product ID must be set correctly
  ftStatus = FT_SetVIDPID(0x403,0xfaf0);
  }

  //Open device:
  const char* tmp = serialnumber.c_str();
  int numAttempts=0;
  while (keyHandle ==0){
    ftStatus = FT_OpenEx(const_cast<char*>(tmp),FT_OPEN_BY_SERIAL_NUMBER, &keyHandle);
    if (numAttempts++>20){
      cerr << "Device Could Not Be Opened";
      return false;
    }
  }

  // Set baud rate to 115200
  ftStatus = FT_SetBaudRate(keyHandle,115200);

  // 8 data bits, 1 stop bit, no parity
  ftStatus = FT_SetDataCharacteristics(keyHandle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);

  // Pre purge dwell 50ms.
  usleep(50);

  // Purge the device.
  ftStatus = FT_Purge(keyHandle, FT_PURGE_RX | FT_PURGE_TX);

  // Post purge dwell 50ms.
  usleep(50);

  // Reset device.
  ftStatus = FT_ResetDevice(keyHandle);

  // Set flow control to RTS/CTS.
  ftStatus = FT_SetFlowControl(keyHandle, FT_FLOW_RTS_CTS, 0, 0);

  // Set RTS.
  ftStatus = FT_SetRts(keyHandle);

  return true;
}

我如何读出我的数据:

bool CommunicationFunctions::read_tdc(int32_t* position, uint16_t* velocity){    
  uint8_t *RxBuffer = new uint8_t[256]();
  DWORD RxBytes;
  DWORD BytesReceived = 0;

  // Manually request status update:
  uint8_t req_statusupdate[6] = {0x90,0x04,0x01,0x00,0x50,0x01};
  ftStatus = FT_Write(keyHandle, req_statusupdate, (DWORD)6, &written);
  if(ftStatus != FT_OK){
    cerr << "Command could not be transmitted: Request status update" << endl;
    return false;
  }

//  sleep(1); //**this sleep() would lead to right result, but I don't want this delay**

  // Get number of bytes in queue of TDC001
  FT_GetQueueStatus(keyHandle,&RxBytes);

  // Check if there are bytes in queue before reading them, otherwise do
  // not read anything in
  if(RxBytes>0){
    ftStatus=FT_Read(keyHandle,RxBuffer,RxBytes,&BytesReceived);
    if(ftStatus != FT_OK){
      cerr << "Read device failed!" << endl;
      return false;
    }
  }

  // Check if enough bytes are received, i.e. if signal is right
  if(!(BytesReceived >= 6)){
    cerr << "Error in bytes received" << endl;
    return false;
  }

  // Look for correct message in RxBuffer and read out velocity and position
  getPosVel(position,velocity,RxBuffer);

  // Delete receive buffer
  delete[] RxBuffer;
  RxBuffer = NULL;

  return true;
}

如果我在归位后和移动到绝对位置期间使用 read_tdc 功能,我只会在第一次尝试时收到“归位完成”消息。当我再次尝试 read_tdc 时,我得到一个旧值(可能是之前的那个)。我不明白这里发生了什么。为什么这个旧数据甚至保留在队列中(延迟为 10 毫秒)。任何人都可以帮助我获得更快的响应和反应吗?

4

0 回答 0