EtherCAT IO 與尋原點

以 ICPDAS ECAT-2055 為單軸讀取範例 — 為什麼 ORG/OT 這些輸入一定要先「註冊 + 綁定」,否則馬達根本不會動。以 SuperCAT 主站實作(安川伺服 + ECAT-2055 為 slave),附實際的 APS168 呼叫順序。

還沒建置匯流排?先看 匯流排建置:掃描、ESI 與設備識別 — 說明 slave 怎麼被識別,以及下面用到的 0001.csv 從哪來。

1 · EtherCAT 是什麼

EtherCAT 是一種 master/slave 工業匯流排。一個 master 跑在即時作業系統(RTOS)上,每個 cycle 送一張 frame 依序穿過所有 slave,邊走邊寫輸出、讀輸入。Cycle time 從約 1 ms 一路可到微秒等級,這種確定性(deterministic)正是運動控制需要的。

本文的 master 是 SuperCAT,slave 有一顆安川伺服(軸)和一顆 ICPDAS ECAT-2055(8 DI/8 DO),限位與原點開關就接在它上面。

2 · 一張表,兩種存取方式

每顆 slave 都有一張 物件字典(Object Dictionary,OD) — 表裡每個值都有一個 index(例如 0x6000 = 8 顆 DI、0x6200 = 8 顆 DO)。存取這些物件有兩條路,差別很關鍵:

Object Dictionary 0x6000 8x DI ro 0x6200 8x DO rw PDO · cyclic (fast) every bus cycle, real-time IO deterministic period ~ 1 cycle SDO · acyclic (slow) on demand, via Mailbox ~ 324 cycles / transfer no mailbox -> -4101

ECAT-2055 沒有 Mailbox,所以用 SDO 讀它的 DI 直接失敗回 -4101。它的 IO 只活在 cyclic 的 PDO process image 裡 — 記住這句,後面全靠它。

3 · SuperCAT master — 硬體或純軟體

SuperCAT 是 ADLINK 的 EtherCAT master 軟體。要運行它有兩種擇一方式,而且上層程式(APS168)兩種寫法完全一樣:

software · EtherCAT master SuperCAT hardware PCIe-8338 or pure software dongle PDO / SDO slave ECAT-2055 8x DI / 8x DO read DI (verified) APS_get_field_bus_d_port_input(board,0,MOD1,…) write DO APS_set_field_bus_d_port_output(…) – 同法,本專案未用

4 · 註冊與綁定 IO(最容易卡的地方)

你最先會遇到的症狀: 馬達完全不動,而且畫面顯示 +OT 和 −OT 同時觸發。其實限位沒壞 — 是軸還沒讀到 DI。因為 OT 開關是 B 接點(NC),沒讀到的輸入值當 0,反相邏輯下 0 就變成「觸發」,於是兩端同時亮。

讀到 DI 值,不等於讓運動引擎能拿它去尋原點與擋限位。要做到這件事,引擎必須把 ECAT-2055 看成一顆 已註冊的 DIO 模組。註冊的方法是用一張設定檔「宣告」它 — 不需要 scan、不需要特殊權限。

步驟 ★ — 註冊模組

APS_load_config_from_file(board, "E:\...\MCPRO2\0001.csv", 0)

整份設定檔只有兩行 — 「slave 1 有一顆 8-bit DI 和一顆 8-bit DO」:

SlaveID, Type, Port/Ch, SubMod, ODIndex, AccessLength, ...
1,       1,    0,       0,      0,       8,   ...   # slave1 8-bit DI
1,       2,    0,       0,      0,       8,   ...   # slave1 8-bit DO

(Type 1 = DI、Type 2 = DO — 此對照取自實機 MiniJog 專案的實測:一列拿來讀輸入、一列拿來寫輸出。LowerBound/UpperBound/DataType = -1 對數位 IO 不使用。)

步驟 ★★ — 把訊號綁到軸

接著告訴軸:哪顆 DI 是 ORG/PEL/MEL、設定接點極性、然後開啟綁定:

APS_set_axis_param(ax, PRA_MOTION_SGN_ORG_MAP, (1<<8)|0)   # ORG <- DI0
APS_set_axis_param(ax, PRA_MOTION_SGN_MEL_MAP, (1<<8)|1)   # MEL <- DI1
APS_set_axis_param(ax, PRA_MOTION_SGN_PEL_MAP, (1<<8)|2)   # PEL <- DI2
APS_set_axis_param(ax, PRA_EL_LOGIC,           1)          # B 接點(NC),反相
APS_set_axis_param(ax, PRA_MOTION_SGN_MAP_EN,  0xE)        # 開啟 ORG/MEL/PEL

模組註冊好、訊號綁好之後,APS_home_move() 就抓得到 ORG、OT 看門狗能擋兩端,by-module 的 APS_get_field_bus_d_port_input() 也讀得到了。

依程式實際順序的完整呼叫流程

1 · 開機 開卡 APS_initial() 取軸號 APS_get_first_axisId() 啟動 EtherCAT 匯流排 APS_start_field_bus() ★ 註冊 ECAT-2055 為 DIO 模組 (MOD1) APS_load_config_from_file(…\MCPRO2\0001.csv) 2 · 綁定 選 IO 存取來源 APS_set_board_param(PRB_IO_ACCESS_SEL, 3) 把限位/原點對到 DI bit · PEL←DI2、MEL←DI1、ORG←DI0 APS_set_axis_param(PRA_MOTION_SGN_PEL/MEL/ORG_MAP, (1<<8)|bit) 設接點極性 · B 接點反相 APS_set_axis_param(PRA_EL_LOGIC, 1) APS_set_axis_param(PRA_ORG_LOGIC, 0) 開啟綁定 (bit1~3 = MEL/PEL/ORG) APS_set_axis_param(PRA_MOTION_SGN_MAP_EN, 0xE) 3 · 尋原點 Servo On APS_set_servo_on(ax, 1) 設 home 參數 (mode 0 = ORG、dir、EZ 對齊、shift…) APS_set_axis_param(PRA_HOME_MODE / DIR / EZA / ACC / VM / VO / SHIFT) 執行回原點 → 引擎抓到 ORG (需 ★ + 開啟綁定) APS_home_move(ax) 4 · 運行 讀 DI 顯示,100 ms (by-module,★ 之後才通) APS_get_field_bus_d_port_input(board,0,MOD1,…) 跳過註冊 (沒載 0001.csv) → 引擎讀 DI 為 0 → B 接點反相下 +OT/−OT 同時看似觸發 → 馬達不動,也永遠抓不到 ORG。根因是缺註冊,不是限位。

旁路。 APS_get_address_mapping_in_byte() 可以不經註冊,直接讀 process image 的原始 byte。手動看一下 DI 值很方便,但引擎在你完成註冊+綁定前不會拿它去 home。這是還沒走 config 檔路線前的早期繞法。

接點型式

  • OT(限位)= B 接點(NC) — fail-safe:idle 導通讀 1;觸發或斷線讀 0。設 PRA_EL_LOGIC = 1,讓 0 代表「觸發」。
  • ORG(home dog)= A 接點(NO) — idle 讀 0;碰到 dog 讀 1。

5 · 延伸閱讀