Использование протокола связи FTDI D2xx и Thorlabs APT приводит к задержкам в Linux

Я пытаюсь установить связь с контроллерами Thorlabs TDC001 (сервоконтроллер apt - dc) с помощью драйвера FTDI D2xx в Linux. Однако, когда я посылаю команды записи, возникают большие задержки (1-2 секунды) до тех пор, пока команда не будет фактически выполнена на TDC001. В частности, это можно наблюдать, когда подключенный линейный каскад движется и отправляется новая команда положения. Требуется 1-2 секунды, пока сцена фактически не изменит свое направление. Кроме того, если я запрашиваю DCSTATUSUPDATE (который дает положение и скорость), а затем считываю очередь FTDI, я не получаю правильные данные. Только если я жду 1 секунду между запросом и чтением, я получаю (правильные) данные, но для прошлого. Я добавил код C++ для этого случая. Мне нужны живые данные и более быстрое выполнение команд записи для управления с обратной связью.

Я не уверен, если проблема на стороне Thorlabs или FTDI. Все работает, кроме больших задержек. Есть и другие команды, например, MOVE_STOP, которые отвечают немедленно. Кроме того, если я отправляю новую команду положения сразу после окончания поиска, она выполняется немедленно. Всякий раз, когда я запрашиваю FT_GetStatus, в очереди Tx или Rx больше ничего нет, кроме 20 байтов в Rx для DCSTATUSUPDATE.

Ссылки на протоколы связи 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 после возврата в исходное положение и при перемещении в абсолютное положение, я просто получаю сообщение "Homing complete" в первой попытке. Когда я снова пытаюсь прочитать read_tdc, я получаю старое значение (вероятно, предыдущее). Я не понимаю, что здесь происходит. Почему эти старые данные даже остаются в очереди (задержка составляет 10 мс). Кто-нибудь может помочь мне получить более быстрые ответы и реакции?

0 ответов

Другие вопросы по тегам