連接鈕
作為連接 (Connect) 或斷開連接 (Disconnect) 紐用,點選此鈕後 KINGSTAR 子系統將會連接至硬體,若硬體已連接,點擊鈕以斷連。
此鈕名稱為 btnConnect,擁有連接至位置 btnConnectClicked 之信號 clicked,點擊此鈕後使用 setEnabled 以停用之,如此當連接正在建立時即無法點擊該鈕,而 Timeout 為一決定 EtherCAT 連接是否耗費過長時間建立之變數。
以下代碼在 QtGui.cpp
中:
void QtGui::btnConnectClicked()
int Timeout = 0;
ui->btnConnect->setEnabled(false);
在連接至硬體前,使用 getecState 函式以檢查 EtherCAT 之連接狀態,getecState 回傳 maSts.State 之值,由此可知 EtherCAT 連結是否已建立,若已建立,則代表此鈕功能為 Disconnect 鈕;否則為 Connect 鈕。
不管鈕的功能為 Connect 或 Disconnect 皆會呼叫兩個函式:processEvents 和 commandConnect,processEvents 為當 EtherCAT 連結建立或故障時維持使用者介面 (UI) 運作的 QApplication 成員函式;commandConnect 為連接至位置 actionConnect 的信號,commandConnect 信號一旦發射,將立即觸發 actionConnect。
以下代碼在 QtGui.cpp
中:
while (ks->getecState() != ecatOP && Timeout < 2000)
{
QApplication::processEvents();
emit commandConnect();
actionConnect 寫在 ksworker.cpp 中,使用 switch 陳述式來測試 wkState,其為 workerState 列舉之變數,內含三種狀態:disconnected、connecting 及 connected。
連接 (Connect)
作為 Connect 鈕的狀態為 disconnected,其中我們將 wkState 設為 connecting,並在開關陳列式中執行 connecting 功能塊。
連接前
點選 Connect 將執行 disconnected
功能塊內的代碼,下列函式將初始化和建立 EtherCAT 連結,並開啟 KINGSTAR 子系統:
- Create:準備將程式連結至 KINGSTAR 子系統,此允許在有多主站套件 (Multiple Master Package) 時選擇欲使用的 KINGSTAR Runtime 實例,並配置執行的核心。
- SetAxisAccessMode:為 EtherCAT 驅動器設定資料傳輸模式,而模式可在 KsAccessMode 類型中選擇。
- SetCycleTime:設定 EtherCAT 循環時間,此範例中
cycle1000
代表 1 毫秒,若欲輸入一數字,請輸入 SetCycleTime(0.001),我們使用變數以代表數字,可在ksapi.h
中找到以下的定義,其位於C:\Program Files\IntervalZero\KINGSTAR SDK\4.0\Include
。欲使用低於 1 毫秒的循環時間,須備有高速計時器套件。 - SetConfiguredAxesCount:配置模擬軸隻數量,在此範例中使用一個模擬軸。
- ConfigureDc:配置分散式時鐘 (DC) 選項。
- WaitForCommand:等待命令完成,我們給 Start 0.2 秒執行,若未在時間內執行將執行下個命令。
- Start:開啟 KINGSTAR 子系統。
注意:Create置於 ksworker
建構函式中,將可比置於 actionConnect 中更快速呼叫。
變數 | 數字 |
---|---|
cycle100 | 0.0001 |
cycle125 | 0.000125 |
cycle250 | 0.000250 |
cycle500 | 0.0005 |
cycle1000 | 0.001 |
以下代碼在 ksworker.cpp
中:
ksWorker::ksWorker(QObject *parent)
: QObject(parent), dataTimer(new QTimer(this)), data({false, 0.0, 0.0}),
maSts({ ecatOffline, ecatOffline, 0, 0, 0, { ecatOffline }, { ecatOffline }, { axisOffline } }),
wkState(disconnected), currentIndex(-1), commandVelocity(360)
{
nRet = Create(0, 0);
if (nRet != errNoError) {
return;
}
......
}
void ksWorker::actionConnect()
{
switch (wkState)
{
case disconnected:
wkState = connecting;
nRet = SetAxisAccessMode(KsAccessMode::accessPos);
nRet = SetCycleTime(cycle1000);
nRet = SetConfiguredAxesCount(1);
nRet = ConfigureDc(TRUE, TRUE, TRUE, 0);
WaitForCommand(0.2, FALSE, Start());
GetStatus(&maSts, nullptr);
break;
case connecting:
GetStatus(&maSts, nullptr);
if (maSts.State == EthercatState::ecatOP)
{
wkState = connected;
SlaveStatus *ss = new SlaveStatus;
McProfileSettings Motion = {
3,
360,
5000,
50000,
50000,
5000000,
0
};
for (int i = 0; i < maSts.AxesCount; i++)
{
int Resolution = 10000;
DWORD InputVariables = 0;
DWORD OutputVariables = 0;
GetAxisByIndex(i, ss, &Resolution, &InputVariables, &OutputVariables);
SetAxisMotionProfile(i, profileUnitPerSecond, Motion);
SetAxisCountsPerUnit(i, Resolution, 360, FALSE);
EnableAxisUnitConversion(i, TRUE);
SetAxisPositionOffset(i, 0, FALSE, McExecutionMode::mcImmediately);
powerStatus.push_back(FALSE);
emit sendName(i, ss->Name);
}
delete ss;
dataTimer->start(100);
}
break;
...........
}
...........
}
連接中
connecting 功能塊中使用以下函式來初始化運動設定:
- GetStatus:獲取 EtherCAT 連結的狀態。
- McProfileSettings:為一包含有關軸運動設定(如加速度、減速度、加加速度)的結構。
- GetAxisByIndex:獲取軸資訊。
- SetAxisMotionProfile:配置軸的運動設定,其決定加速度、減速度及加加速度的單位,並套用在 McProfileSettings 中定義的運動值。
- SetAxisCountsPerUnit:將使用者自定義位置單位的轉換比例設定為軸使用的計數(脈衝)單位,在此範例中
Numerator
為 10000 而Denominator
為 360,因此比例為 250:9,而Reverse
為 FALSE,因此軸的方向非倒轉。 - EnableAxisUnitConversion:啟用軸使用真實世界單位。使用 SetAxisCountsPerUnit 設定轉換比率後,需使用此方法來起動轉換,此比率才會生效。
- SetAxisPositionOffset:使用相同值操控軸的設定點位置和實際位置來移動軸的坐標系統,而不會導致任何移動(使用相同的追蹤誤差重新校正)。
powerstatus
:定義於ksworker.h
中,為代表軸電力的變數,當 KINGSTAR 子系統連接至硬體,各軸的電力將設為 false(軸停用)。sendName
:定義於ksworker.h
中,為包含軸索引與名稱的信號,在QtGui.cpp
中,sendName
連接至位置 updateDevices,其將更新在列表中的裝置。
計時器
在 connecting 結尾使用 dataTimer 作為計時器,而 start 設定 dataTimer 之時間區間至 100 毫秒,每 100 豪秒 dataTimer 會發射 QTimer::timeout 信號,其連接 lambda 函式作為第三參數。
當觸發 timeout 時,lambda 函式將檢查 EtherCAT 連結狀態是否為操作中 (Op) 且 currentIndex 大於零,若是,將獲得所選軸的電力狀態並分配至 data.powerStatus,其中 currentIndex 為軸的索引,而 data 為用來獲取軸狀態的 axisData 結構之變數。接著使用 GetAxisPosition 與 GetAxisVelocity 來獲取軸的實際位置和實際速度,最後發射連接至位置 updateAxisData 的 sendData 信號,其將立即執行,而 updateAxisData 將依照狀態更新 GUI 元素。
以下代碼在 ksworker.cpp
中:
QObject::connect(dataTimer, &QTimer::timeout, [this]()
{
if (maSts.State == ecatOP && currentIndex >= 0)
{
double pos = 0.0;
double vel = 0.0;
data.powerStatus = powerStatus[currentIndex];
nRet = GetAxisPosition(currentIndex, McSource::mcActualValue, &pos);
if (nRet == KsError::errNoError)
data.actualPos = pos;
else
data.actualPos = (double)nRet;
nRet = GetAxisVelocity(currentIndex, McSource::mcActualValue, &(vel));
if (nRet == KsError::errNoError)
data.actualVel = vel;
else
data.actualVel = (double)nRet;
}
emit sendData(data);
});
以下代碼在 QtGui.cpp
中:
void QtGui::updateAxisData(axisData data)
{
if (!ui->btnEnable->isEnabled())
{
if (ui->btnEnable->text() == "Enable" && data.powerStatus)
{
ui->btnEnable->setText("Disable");
ui->btnEnable->setEnabled(true);
ui->btnJogForward->setEnabled(true);
ui->btnJogBackward->setEnabled(true);
}
else if (ui->btnEnable->text() == "Disable" && !data.powerStatus)
{
ui->btnEnable->setText("Enable");
ui->btnEnable->setEnabled(true);
ui->btnJogForward->setEnabled(false);
ui->btnJogBackward->setEnabled(false);
}
}
else
{
if (data.powerStatus)
{
...........
}
else
{
...........
}
}
ui->leActPosition->setText(QString::number(data.actualPos, 'f', 3));
ui->leActVelocity->setText(QString::number(data.actualVel, 'f', 3));
}
連結建立後,更改以下 GUI 元素之設定:
以下代碼在 QtGui.cpp
中:
ui->listDevices->setCurrentRow(0);
ui->leCommVelocity->setEnabled(true); //Enable the Command Velocity box.
ui->leCommVelocity->setText("360"); //Set the value to 360 in the Command Velocity box.
ui->btnEnable->setEnabled(true); //Enable the Enable button.
ui->btnReset->setEnabled(true); //Enable the Reset button.
ui->btnJogForward->setEnabled(true); //Enable the Jog Forward button.
ui->btnJogBackward->setEnabled(true); //Enable the Jog Backward button.
ui->btnConnect->setText("Disconnect"); //Change the text of the Connect button to "Disconnect."
statusLabel->setText("EC state: OP"); //Change the text of the Status label to "EC state: OP."
statusProgress->setMaximum(100); //Change the maximum step of the progress bar to 100.
statusProgress->setValue(100); //Set the current value of the progress bar to 100.
斷開連結 (Disconnect)
作為 Disconnect 鈕的狀態為 connected,我們將停止計時器,並使用 PowerAxis 來停用所有軸,再用 Stop 來停止 EtherCAT 網路及 KINGSTAR 子系統,WaitForCommand 用來給 PowerAxis 一些時間而 Stop 用來完成其工作,我們給 PowerAxis 5 秒而給 Stop 2 秒,wkState 設為 disconnected 以將鈕設為 Connect,而 currentIndex 設為 -1,代表沒有任何軸,maSts 將恢復為預設值。
以下代碼在 ksworker.cpp
中:
case connected:
dataTimer->stop();
for (int i = 0; i < maSts.AxesCount; i++)
{
KsCommandStatus Command = { 0 };
Command = WaitForCommand(5, FALSE, PowerAxis(i, FALSE, FALSE, FALSE));
}
WaitForCommand(2, FALSE, Stop());
wkState = disconnected;
currentIndex = -1;
maSts = { ecatOffline, ecatOffline, 0, 0, 0, { ecatOffline }, { ecatOffline }, { axisOffline } };
break;
default:
break;
}