Отслеживание положения устройства Zaber во время движения

Я использую линейную сцену Zaber, управляемую Arduino с помощью шилда Zaber. Я пытаюсь сделать что-то похожее на этот вопрос (Отслеживать положение Устройство Zaber при его перемещении), но с использованием языка Arduino вместо Labview.

В ответе было предоставлено 3 варианта: интерполировать от начальной и конечной точек, опросить позицию по таймеру или включить режим устройства, сообщающий позицию каждые 250 мс.

Режим устройства, похоже, не существует для моей сцены (X-LSQ-075B-E01), и я не хочу полагаться на интерполяцию. Стол оснащен энкодером, и я могу легко получить от него точное положение; Я просто не знаю, как опрашивать сцену во время движения. Я придумал следующий код (немного упрощенный), но он относительно медленный и дает считывание только с 1 этапа (на самом деле мы используем 2), и отправка команды обоим на самом деле не работает.

#include <ZaberAscii.h>

ZaberShield shield(ZABERSHIELD_ADDRESS_AA);
ZaberAscii za(shield);

void setup() {
  shield.begin(115200);
  Serial.begin(115200);
  za.send(1, 1, "move rel", 20000);
  za.receive();

  while (za.isIdle(1) == false) {
    za.send(1, "get encoder.pos");
    ZaberAscii::reply reply = za.receive();
    if (!reply.isReply) {
      Serial.println("*** Received a non-reply message from device " + String(reply.deviceNumber) + ".");
    }
    else if (reply.isRejected) {
      Serial.println("*** A command was rejected by device " + String(reply.deviceNumber) + ".");
    }
    else {
      Serial.println( String(reply.deviceNumber) + ": " + String(reply.responseData));
    }
    delay(5);
  }

  za.pollUntilIdle(1);
  Serial.println("1 finished");
  za.send(2, 1, "move rel", 20000);

  while (za.isIdle(2) == false) {
    za.send(2, "get encoder.pos");
    Serial.println("Device 2 not idle");
    ZaberAscii::reply reply = za.receive();
    if (!reply.isReply) {
      Serial.println("*** Received a non-reply message from device " + String(reply.deviceNumber) + ".");
    }
    else if (reply.isRejected) {
      Serial.println("*** A command was rejected by device " + String(reply.deviceNumber) + ".");
    }
    else {
      Serial.println( String(reply.deviceNumber) + ": " + String(reply.responseData));
    }
    //delay(10);
  }
  Serial.println("2 finished");
}

void loop() {}

person Henry    schedule 04.02.2021    source источник


Ответы (1)


Чтобы это работало на обоих устройствах, вам нужно будет отправить обе команды движения перед запуском цикла while, а затем для цикла while вы хотите, чтобы условие повторялось до тех пор, пока обе оси не будут бездействовать. В цикле while вы должны прочитать положение обеих осей.

Что касается времени, можете ли вы примерно сказать, какая частота у вас сейчас? Время на связь обычно составляет около 5-10 мс. С текущими функциями вызов isIdle() принимает свою собственную команду, поэтому я ожидаю, что указанный выше цикл займет около 20-40 мс. Вы можете сократить его вдвое, вытащив информацию .IsBusy из ответа «get encoder.pos».

Майк Макдональд [email protected]

person ZaberCS    schedule 04.02.2021
comment
Большое спасибо за ваш ответ. Я не хочу перемещать обе оси одновременно, но после друг друга, поэтому мне не обязательно нужны оба считывания, когда движется только одна, но я подумал, что это будет удобно для постобработки. Я получал приложение положения. каждые 70 мс. Применяя ваши изменения, я сократил время до 35 мс, но все позиции отправляются дважды. - person Henry; 05.02.2021
comment
Я рад помочь. 35 мс звучит правильно для отправки двух отдельных команд для запроса encoder.pos. Один из способов, с помощью которого вы можете сделать это еще раз, состоит в том, чтобы отправить одну команду на устройство 0: za.send(0, get encoder.pos); Это побудит оба устройства в цепочке ответить. Затем вам нужно будет сделать два .receives, чтобы использовать оба ответа. Не будет гарантии в том, какое устройство ответит первым, поэтому вам также нужно будет проверять номер устройства каждого ответа, чтобы убедиться, что вы сопоставляете правильное устройство и позицию. - person ZaberCS; 05.02.2021