使用FTDI D2xx和Thorlabs APT通信协议会导致Linux出现延迟

时间:2018-04-04 15:53:26

标签: c++ linux delay ftdi d2xx

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

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

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

FTDI Programmer's Guide

Thorlabs APT Communication Protocol

初始化函数:

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功能,我只需要完成归位&#34;第一次尝试中的消息。当我再次尝试read_tdc时,我得到一个旧值(可能是之前的那个)。我不明白这里发生了什么。为什么这些旧数据甚至会留在队列中(延迟为10毫秒)。任何人都可以帮助我获得更快的反应和反应吗?

0 个答案:

没有答案