連接狀態與進度列
點擊 Connect 後, KINGSTAR 子系統即開始連接到硬體,我們使用文字控制 (Text Control) 與進度列控制 (Progress Bar Control) 來顯示連接狀態。
文字控制:連接狀態及錯誤訊息
為監測連接狀態,OnInitDialog 類別中設置計時器以使文字控制規律地獲取 EtherCAT 連接的狀態,計時器 ID為 60,每 5 毫秒觸發一次。
SetTimer(60, 5, NULL);
當呼叫計時器後,我們檢查 EtherCAT 連結的狀態,EtherCAT 連結有四種狀態:Init, Pre-Operational (Pre-Op), Safe-Operational (Safe-Op), Operational (Op),當狀態為 Op,則連結及建立,m_MotorList.GetCurSel 擷取列表格 (List Box) 中當前所選的軸,欲在連接時顯示這狀態,我們使用 GetStatus 以獲取 EtherCAT 連結的狀態,接著使用 if 陳述來識別該狀態,文字控制即透過 SetWindowText 反映對應的狀態。
void CMFC_GUIDlg::OnTimer(UINT_PTR nIDEvent)
{
...........
if (nIDEvent == 60) //update timer ID
{
int Mindex = m_MotorList.GetCurSel();
//Gets the state of the EtherCAT link.
::GetStatus(&KSMStatus, NULL);
if (KSMStatus.State == ecatOffline)
{
GetDlgItem(IDC_NET_STATUS)->SetWindowText(L"Offline");
}
if (KSMStatus.State == ecatInit)
{
GetDlgItem(IDC_NET_STATUS)->SetWindowText(L"Init");
}
if (KSMStatus.State == ecatPreOP)
{
GetDlgItem(IDC_NET_STATUS)->SetWindowText(L"PreOP");
}
if (KSMStatus.State == ecatSafeOP)
{
GetDlgItem(IDC_NET_STATUS)->SetWindowText(L"SafeOP");
}
if (KSMStatus.State == ecatOP)
{
GetDlgItem(IDC_NET_STATUS)->SetWindowText(L"OP");
GetDlgItem(IDC_BTN_CONNECT)->SetWindowText(L"Disconnect");
...........
}
}
}
若函式未如預期運作,進度列上方會出現錯誤訊息,錯誤訊息依函式而有所不同,以下代碼為 SetCycleTime 失敗的錯誤訊息:
Str_Error.Format(_T("Failed to set SetCycleTime: %d\n"), Command.ErrorId);
GetDlgItem(IDC_ERROR_RETURN)->SetWindowText(Str_Error);
進度列控制:連接進度
進度列控制為展示需長時間完成的進度之進度列,使用前需先初始化進度列的一些屬性,在此範例中使用變數 m_progressbar 以代表該進度列,我們在OnInitDialog 中設定進度列的狀態及範圍。
BOOL CMFC_GUIDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_progressbar.SetState(PBST_NORMAL);
m_progressbar.SetRange(0, 100);
...........
}
在 Connect 中設定計時器以在進度列中使用,計時器 ID 為 55,每 100 毫秒觸發一次。點選連接鈕時將呼叫計時器,僅度列將根據我們傳送的位置重新繪製,在此範例中傳送變數 TimerCount,此變數會不斷增加一,當到達 100 時, TimerCount 將重置並再次開始增加,在建立 KINGSTAR 子系統和硬體之間的 EtherCAT 連結時,進度列的位置會不斷從零跑到 100。
SetTimer(55, 100, NULL);
我們使用 KSMStatus 以偵測狀態是否為 Op,若是,則連結即成功建立,進度列的位置設為零且偵測到計時器。
void CMFC_GUIDlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 55) //progress bar
{
m_progressbar.SetPos(TimerCount++);
if (TimerCount >= 100)
{
TimerCount = 0;
}
if (KSMStatus.State == ecatOP)
{
m_progressbar.SetPos(0);
KillTimer(55);
}
}
...........
}