今回の記事ではTURCK社のTBEN-L5-PLC-11 Codesys PLCとCodesys SoftMotionを利用し、Delta社のASDA-A3 ServoドライブをEtherCATで制御します。
さ、FAを楽しもう。
CODESYS SoftMotion
CODESYS SoftMotionはIEC61131-3プログラミングシステムCODESYSに統合された、PLCopen®機能とCAMを備えたコントローラ用のモーションコントロールツールです。
CODESYS SoftMotionを使用することにより、使い慣れたIEC 61131-3プログラミング環境で、単軸から多軸の動作からCAMまで、すべてをロジックアプリケーションとともに直接開発できます。 CODESYS SoftMotionを搭載したモーションコントローラは、PLC開発システムに統合されたツールキットの形でモーション機能を実装できます。
ランタイムシステムCODESYS Control SoftMotionは、CODESYS SoftMotionツールキットでプログラムするために、モーションコントローラに実装する必要があります。
Platform requirements:
CODESYS SoftMotionコントローラを使用する場合、モーションタスクの実装に関して、ユーザにはさまざまなオプションがあります。例えば、提供されているPLCopenモーションPOUを利用したり、IEC 61131-3開発システムの全機能を利用したりすることができます。
- CODESYS Controlでサポートされている必要があります(FPUで最小32ビットを推奨)。
- アプリケーションに位置、速度、加速度データの計算に十分な性能を必要とする。
- アプリケーションに低ジッター値でハードなリアルタイム性を必要とする。
CODESYS SoftMotion contains…
CODESYS SoftMotionには以下のPackagesが含まれています。
- 単軸および多軸動作用の認定 PLCopen POU
- 診断、停止、CAM コントローラなどのアドオン機能用の認定 PLCopen POU
- 動的データのモニタリングやエラーフォロー、CAM および CAM コントローラの操作など、さまざまなタスク用の追加 POU
- CODESYSの可視化を使用して、POUを迅速かつ容易に試運転するための可視化テンプレート
- CAMとCAMコントローラをオンラインで変更できる可視化エレメント
- 豊富な設定オプションを備えた統合グラフィカルCAMエディタ
- 仮想軸と論理軸をサポート
- 多数のCAN、CANopen®、EtherCAT®ドライブ用の統合ドライバ
- ドライブを標準フィールドデバイスとして設定
- CODESYS SoftMotionプロジェクトの例
Servo ASDA-A3?
今回使用するのはDelta社のASDA-A3シリーズのServoになります。
Layout
EtherCAT Mode
ASDA-A3サーボシステムではEtherCATモードを使用でき、2つのEtherCATコネクタ (CN6) のピン配置は同じです。
注意するのはIN コネクタは受信用としてコントローラ(マスタ)または前のサーボドライブに接続でき、 OUT コネクタは出力用として次のサーボドライブにのみ接続できます。また、接続を誤ると通信ができなくなります。
Connection Example
下図では複数のASDA-A3 サーボシステムをEtherCAT ネットワークの接続例です、
Specification
こちらはASDA-A3サーボシステムのEtherCAT仕様になります。
Architecture
サーボドライブのEtherCATアーキテクチャは以下の通りです:
- Communication profile: このプロトコルには、通信オブジェクト(PDO、SDO、SYNC、緊急オブジェクト)と関連するcommunication object dictionaryが含まれる。
- DS402:ドライブとモーションコントロール用のデバイスプロファイルで、各モーションモードの動作と、実行に必要なオブジェクトパラメータ設定を定義します。
Synchronous mode
Delta社サーボドライブは2つの同期モードをサポートしています: それはFree ModeとDC-Synchronous modeです。
Free Run mode (Asynchronous)
Free Run modeでは、マスター局とスレーブ局は非同期で動作します。各ステーションは時間を計算する個別のクロックを持っており、マスターとスレーブのクロックは同期していません。マスターとスレーブ間のコマンドとフィードバックの送信は、正確な時間同期ではなく、シーケンシャルな順序に基づいている。例えば、マスターは時刻T1にPDOを送信し、スレーブはSM2イベント後のT2にPDOを受信する。
DC-Synchronous mode (SYNC0 synchronization)
マスタ局とスレーブ局の間には正確な時刻同期があり、マスターは制御プログラムを定期的に実行し、同期クロックに従って決まった時間にPDOパケットを送信するようになります。マスターはスレーブにコマンドを送信し、スレーブからのフィードバックを受信し、スレーブは同期クロックに従って一定時間ごとにPDOデータを受信し、更新するようになります。
PDO mapping configuration
PDOマッピング・オブジェクトは、object dictionaryの中にRxPDOはインデックスOD 1600からOD 1603まで、TxPDOはインデックスOD 1A00からOD 1A03まで割り当てられます。
RxPDOとTxPDOの各グループは、最大8セットの32ビットオブジェクトのPDOデータ更新をサポートできます。
Default PDO mapping configuration
下表はデータ交換のためのEtherCATサーボドライブのデフォルトPDOマッピング設定です。これはEtherCATスレーブのXMLファイルでも定義され、要求に応じてPDOマッピング設定を変更することができます。
Delta ASDA-x3-E rev0.03.xmlでは、PDOコンフィギュレーションの第1グループから第4グループは以下のようになっています:
ASDA-Software Tools
Delta社のServoとCommissioningするために、下記のLinkでASDA-SoftをDownloadしましょう。
インストールEXEを起動し、Next>で進みます。
ツールのインストール場所を設定し、Installで進みます。
しばらく待ちます…
USB Driverのインストール画面が表示され、InstallをクリックしてServo Driveと通信するDriverをインストールしましょう。
Done!
Implementation
Delta Drive Side
パラメータでP1.001を0x000Cに設定してください。こちらはEtherCAT通信する設定になります。
TURCK Side
Add EtherCAT Master
Deviceを右クリック>Add Deviceで通信Driverを追加します。
Fieldbus>EtherCAT>Master>EtherCAT Masterを追加します。
Done!EtherCAT Masterが追加されました。
Configure Adapter
先程追加されたEtherCAT Masterをクリックし、GeneralをTabでSelectをクリックします。
実際アプリケーションでEtherCAT Masterとして使用したいEthernet Adapterを設定してください。
Done!
Scan For Devices
先ほど追加したEtherCAT Masterを右クリック>Scan for Devicesをクリックし、EtherCATネットワーク内のスレーブを検索しましょう。
Done!Delta社のServo ドライブを確認できましたので、Copy All Devices to ProjectをクリックしネットワークのSlaveをプロジェクトに複製しましょう。
Done!
Configuration
今回記事で使用するDelta社のServoドライブの分解能は16777216=1回転なので、Scaling/MappingをTabを開き、Scalingを16777216に入力してください。
次はIncremenets<==>units in application の欄に1を入力します。つまり現在1回転は1mmになります。
Program
次はプログラムを作成します。今回はInterface・Function Block・Extendなど少しOOPのコンセプトを踏みながらプログラムを作成していきます。
Interface
まずはIntefaceの作成から始めます。Intefaceを使用すると、該当するFunction Blockが”なに”をすることだけに集中でき、”どう”やるかのプログラムと分割することができます。また、複数の異なるFunction BlockにもIntefaceだけ共通し、より統一的なプログラムを作成することが可能です。
ITF_SpeedAxis
こちらはServoを速度制御するときの”やること”を定義します。
METH_Half
こちらのMethodはServoが実行中のJOBを停止できます。
METHOD METH_Half : INT VAR_INPUT iCmd:BOOL; END_VAR |
METH_JogFWBW
こちらのMethodはServoのJOG操作になります。
METHOD METH_JogFWBW : INT VAR_INPUT iFw,iBw:BOOL; iVelSetpoint:LREAL; iVelAcc,iVelDec:LREAL; END_VAR |
METH_PowerON
こちらのMethodはServo ON操作になります。
METHOD METH_PowerON : INT VAR_INPUT iCmd:BOOL; END_VAR |
METH_Reset
こちらのMethodはServoのリセット操作になります。
METHOD METH_Reset : INT VAR_INPUT iCmd:BOOL; END_VAR |
METH_VelocityCmd
こちらのMethodはServoの定速運転操作になります。
METHOD METH_VelocityCmd : INT VAR_INPUT iCmd:BOOL; iVelSetpoint:LREAL; iVelAcc,iVelDec:LREAL; END_VAR |
PROPERTY Prop_CommunicationOK : BOOL
こちらのPROPERTYからServoの通信状態を取得できます。
PROPERTY Prop_Error : Bool
こちらのPROPERTYからServoのエラー状態を取得できます。
PROPERTY Prop_Ready : Bool
こちらのPROPERTYからServoの準備OK信号を取得できます。
PROPERTY Prop_Running : Bool
こちらのPROPERTYからServoの移動中信号を取得できます。
PROPERTY Prop_Stopped : Bool
こちらのPROPERTYからServoの停止中信号を取得できます。
ITF_PositionAxis EXTENDS ITF_SpeedAxis
新しいInterfaceを定義し、INTERFACE ITF_SpeedAxisから拡張しましょう。
METH_Home
こちらのMethodはServoをHomeすることができます。
METHOD METH_Home : INT VAR_INPUT iCmd:BOOL; END_VAR |
METH_MoveRelative
こちらのMethodはServoに相対位置決め操作を実装します。
METHOD METH_MoveRelative : INT VAR_INPUT iCmd:BOOL; iVelSetpoint:LREAL; iVelAcc,iVelDec:LREAL; iDistance:LREAL; END_VAR |
METH_MoveAbs
こちらのMethodはServoに絶対位置決め操作を実装します。
METHOD METH_MoveAbs : INT VAR_INPUT iCmd:BOOL; iVelSetpoint:LREAL; iVelAcc,iVelDec:LREAL; iPosition:LREAL; END_VAR |
DUT
次は構造体を定義します。
eAxisBasicReturnValue
こちらの列挙からMethodの戻り値になります。
{attribute ‘qualified_only’} {attribute ‘strict’} TYPE eAxisBasicReturnValue : ( init ,ERROR ,Done ,Busy ,nop ,InVelocity ); END_TYPE |
Function Block
FB_Delta_ASDA_A3_SpeedAxis
こちらのFunction Blockでは先ほど定義したITF_SpeedAxis Interfaceを実装します。
FUNCTION_BLOCK FB_Delta_ASDA_A3_SpeedAxis IMPLEMENTS ITF_SpeedAxis VAR_INPUT ioAxis :REFERENCE TO AXIS_REF_ETC_Delta_ASDA_A3; END_VAR VAR_OUTPUT END_VAR VAR_IN_OUT END_VAR VAR _MC_Power:MC_Power; _MC_Reset:MC_Reset; _MC_Half:MC_Halt; _MC_Jog:MC_Jog; _MC_MoveVelocity:MC_MoveVelocity; END_VAR |
METH_Half
こちらは実行中のJOBを停止するためのMethodの実装になります。
METHOD METH_Half : INT VAR_INPUT iCmd:BOOL; END_VAR VAR_INST R_TRIG:R_TRIG; END_VAR |
MC_Halfを使用しServo軸が実行中のJobを実行させ、またFunction Blockの実行状態・結果に沿って適切な戻り値を返します。
R_TRIG(CLK:=iCmd); _MC_Half( Axis:=ioAxis ,Execute:=iCmd ,Deceleration:=100.0 ); IF R_TRIG.Q THEN METH_Half:=eAxisBasicReturnValue.nop; END_IF; IF _MC_Half.Error THEN METH_Half:=eAxisBasicReturnValue.ERROR; ELSIF _MC_Half.Busy THEN METH_Half:=eAxisBasicReturnValue.Busy; ELSIF _MC_Half.Done THEN METH_Half:=eAxisBasicReturnValue.Done; END_IF |
METH_JogFWBW
こちらはSERVOのJOB操作するMethodの実装になります。
METHOD METH_JogFWBW : INT VAR_INPUT iFw,iBw:BOOL; iVelSetpoint:LREAL; iVelAcc,iVelDec:LREAL; END_VAR VAR_INST R_TRIG:R_TRIG; END_VAR VAR fw,bw:BOOL; END_VAR |
MC_Jogを使用しServo軸のJOG操作を実行させ、またFunction Blockの実行状態・結果に沿って適切な戻り値を返します。
fw:=iFw AND NOT iBw; bw:=iBw AND NOT iFw; R_TRIG( CLK:=(iFw AND NOT iBw) OR (iBw AND NOT iFw) ); _MC_Jog( Axis:=ioAxis ,JogForward:=fw ,JogBackward:=bw ,Velocity:=iVelSetpoint ,Acceleration:=iVelAcc ,Deceleration:=iVelDec ); IF R_TRIG.Q THEN METH_JogFWBW:=eAxisBasicReturnValue.nop; END_IF; IF _MC_Jog.Error THEN METH_JogFWBW:=eAxisBasicReturnValue.ERROR; ELSIF _MC_Jog.Busy THEN METH_JogFWBW:=eAxisBasicReturnValue.Busy; END_IF |
METH_PowerON
こちらはSERVO ON操作の実装になります。
METHOD METH_PowerON : INT VAR_INPUT iCmd:BOOL; END_VAR VAR_INST R_TRIG:R_TRIG; END_VAR |
MC_Powerを使用しServo軸のServo ON/OFFを実行させ、またFunction Blockの実行状態・結果に沿って適切な戻り値を返します。
R_TRIG(CLK:=iCmd); _MC_Power( Axis:=ioAxis ,Enable:=iCmd ,bRegulatorOn:=iCmd ,bDriveStart:=iCmd ); IF R_TRIG.Q THEN METH_PowerON:=eAxisBasicReturnValue.nop; END_IF; IF _MC_Power.Error THEN METH_PowerON:=eAxisBasicReturnValue.ERROR; ELSIF _MC_Power.Busy THEN METH_PowerON:=eAxisBasicReturnValue.Busy; ELSIF _MC_Power.Enable THEN METH_PowerON:=eAxisBasicReturnValue.Done; END_IF |
METH_Reset
こちらはSERVOのリセット操作の実装になります。
METHOD METH_Reset : INT VAR_INPUT iCmd:BOOL; END_VAR VAR_INST R_TRIG:R_TRIG; END_VAR |
MC_Resetを使用しServo軸のServo ON/OFFを実行させ、またFunction Blockの実行状態・結果に沿って適切な戻り値を返します。
R_TRIG(CLK:=iCmd); _MC_Reset( Axis:=ioAxis ,Execute:=iCmd ); IF R_TRIG.Q THEN METH_Reset:=eAxisBasicReturnValue.nop; END_IF; IF _MC_Reset.Error THEN METH_Reset:=eAxisBasicReturnValue.ERROR; ELSIF _MC_Reset.Busy THEN METH_Reset:=eAxisBasicReturnValue.Busy; ELSIF _MC_Reset.Done THEN METH_Reset:=eAxisBasicReturnValue.Done; END_IF |
METH_VelocityCmd
こちらはSERVOの定速運転の実装になります。
METHOD METH_VelocityCmd : INT VAR_INPUT iCmd:BOOL; iVelSetpoint:LREAL; iVelAcc,iVelDec:LREAL; END_VAR VAR_INST R_TRIG:R_TRIG; END_VAR |
MC_MoveVelocityを使用しServo軸のServo ON/OFFを実行させ、またFunction Blockの実行状態・結果に沿って適切な戻り値を返します。
R_TRIG(CLK:=iCmd); _MC_MoveVelocity( Axis:=ioAxis ,Execute:=iCmd ,Velocity:=iVelSetpoint ,Acceleration:=iVelAcc ,Deceleration:=iVelDec ); IF R_TRIG.Q THEN METH_VelocityCmd:=eAxisBasicReturnValue.nop; END_IF; IF _MC_MoveVelocity.Error THEN METH_VelocityCmd:=eAxisBasicReturnValue.ERROR; ELSIF _MC_MoveVelocity.Busy THEN METH_VelocityCmd:=eAxisBasicReturnValue.Busy; ELSIF _MC_MoveVelocity.InVelocity THEN METH_VelocityCmd:=eAxisBasicReturnValue.InVelocity; END_IF |
PROPERTY Prop_CommunicationOK : BOOL
こちらのPropertyはIodataInvalidの変数から通信OKかを判定します。
Prop_CommunicationOK:=ioAxis.bCommunication; |
PROPERTY Prop_Error : BOOL
こちらのPropertyはErrorの変数から通信OKかを判定します。
Prop_Error:=ioAxis.bError; |
PROPERTY Prop_Ready : BOOL
こちらのPropertyはReadyの変数からServoの準備OK状態を判定します。
Prop_Ready:=ioAxis.bDriveStartRealState; |
PROPERTY Prop_Running : BOOL
こちらのPropertyはReadyの変数からServoが移動してるかを判定します。
Prop_Running:= ioAxis.bAccelerating OR ioAxis.bDecelerating OR ioAxis.fActVelocity>1.0 OR ioAxis.fActVelocity<-1.0 ; |
PROPERTY Prop_Stopped : BOOL
こちらのPropertyはReadyの変数からServoが停止してるかを判定します。
Prop_Stopped:= NOT ioAxis.bAccelerating AND NOT ioAxis.bDecelerating AND NOT (ioAxis.fActVelocity >1.0) AND NOT (ioAxis.fActVelocity <-1.0) ; |
FB_Delta_ASDA_A3_PositionAxis
次は位置決め用のFBを作成しましょう。こちらのFB先ほど作ったFB_Delta_ASDA_A3_SpeedAxisを拡張し、またITF_PositionAxisを実装する形になります。
FUNCTION_BLOCK FB_Delta_ASDA_A3_PositionAxis EXTENDS FB_Delta_ASDA_A3_SpeedAxis IMPLEMENTS ITF_SpeedAxis, ITF_PositionAxis VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR _MC_MoveAbsolute:MC_MoveAbsolute; _MC_MoveRelative:MC_MoveRelative; _MC_Home:MC_Home; END_VAR |
METH_Home
こちらはSERVOのHOME操作するMethodの実装になります。
METHOD METH_Home : INT VAR_INPUT iCmd : BOOL; END_VAR VAR_INST R_TRIG:R_TRIG; END_VAR |
MC_Homeを使用しServo軸のHome操作を実行させ、またFunction Blockの実行状態・結果に沿って適切な戻り値を返します。
R_TRIG(CLK:=iCmd); _MC_Home( Axis:=ioAxis ,Execute:=iCmd ,Position:=0.0 ); IF R_TRIG.Q THEN METH_Home:=eAxisBasicReturnValue.nop; END_IF; IF _MC_Home.Error THEN METH_Home:=eAxisBasicReturnValue.ERROR; ELSIF _MC_Home.Busy THEN METH_Home:=eAxisBasicReturnValue.Busy; ELSIF _MC_Home.Done THEN METH_Home:=eAxisBasicReturnValue.Done; END_IF |
METH_MoveAbs
MC_MoveAbsoluteを使用しServo軸の絶対位置決めを実行させ、またFunction Blockの実行状態・結果に沿って適切な戻り値を返します。
METHOD METH_MoveAbs : INT VAR_INPUT iCmd:BOOL; iVelSetpoint:LREAL; iVelAcc,iVelDec:LREAL; iPosition:LREAL; END_VAR VAR_INST R_TRIG:R_TRIG; END_VAR |
R_TRIG(CLK:=iCmd); _MC_MoveAbsolute( Axis:=ioAxis ,Execute:=iCmd ,Position:=iPosition ,Velocity:=iVelSetpoint ,Acceleration:=iVelAcc ,Deceleration:=iVelDec ); IF R_TRIG.Q THEN METH_MoveAbs:=eAxisBasicReturnValue.nop; END_IF; IF _MC_MoveAbsolute.Error THEN METH_MoveAbs:=eAxisBasicReturnValue.ERROR; ELSIF _MC_MoveAbsolute.Busy THEN METH_MoveAbs:=eAxisBasicReturnValue.Busy; ELSIF _MC_MoveAbsolute.Done THEN METH_MoveAbs:=eAxisBasicReturnValue.Done; END_IF |
METH_MoveRelative
MC_MoveRelativeを使用しServo軸の相対位置決めを実行させ、またFunction Blockの実行状態・結果に沿って適切な戻り値を返します。
METHOD METH_MoveRelative : INT VAR_INPUT iCmd:BOOL; iVelSetpoint:LREAL; iVelAcc,iVelDec:LREAL; iDistance:LREAL; END_VAR VAR_INST R_TRIG:R_TRIG; END_VAR |
R_TRIG(CLK:=iCmd); _MC_MoveRelative( Axis:=ioAxis ,Execute:=iCmd ,Distance:=iDistance ,Velocity:=iVelSetpoint ,Acceleration:=iVelAcc ,Deceleration:=iVelDec ); IF R_TRIG.Q THEN METH_MoveRelative:=eAxisBasicReturnValue.nop; END_IF; IF _MC_MoveRelative.Error THEN METH_MoveRelative:=eAxisBasicReturnValue.ERROR; ELSIF _MC_MoveRelative.Busy THEN METH_MoveRelative:=eAxisBasicReturnValue.Busy; ELSIF _MC_MoveRelative.Done THEN METH_MoveRelative:=eAxisBasicReturnValue.Done; END_IF |
pServo
こちらはメインプログラムになり、先程作成したFunction Blockを呼び出し、CASE文を使用し絶対位置決めと相対位置決めの繰り返しをします。
PROGRAM pServo VAR Axis1:FB_Delta_ASDA_A3_PositionAxis; bError:BOOL; bRunning:BOOL; bStopped:BOOL; bPowerON:BOOL; bReset:BOOL; RetValue:INT; bReady:BOOL; bRun:BOOL; bStop:BOOL; fSetValue:REAL; bFw,bBw:BOOL; bHome:BOOL; bMoveAbs,bMoveRelative:BOOL; f32AbsPos,f32AbsVel,f32AbsAcc,f32AbsDec:REAL; f32RelativePos,f32RelativeVel,f32RelativeAcc,f32RelativeDec:REAL; bCommunicationOK:BOOL; iStep:INT; iCount:INT; start:BOOL; R_TRIG:R_TRIG; END_VAR |
//Axis of Delta Servo Axis1(ioAxis:=SM_Drive_ETC_Delta_ASDA_A3); // RetValue:= Axis1.METH_PowerON( iCmd:=bPowerON ); // bReady:=Axis1.Prop_Ready; bRunning:=Axis1.Prop_Running; bError:=Axis1.Prop_Error; bStopped:=Axis1.Prop_Stopped; bCommunicationOK:=Axis1.Prop_CommunicationOK; // // RetValue:=Axis1.METH_Reset( iCmd:=bReset ); // RetValue:=Axis1.METH_Half( iCmd:=bStop ); // RetValue:=Axis1.METH_Home( iCmd:=bHome ); IF RetValue = eAxisBasicReturnValue.Done THEN bHome:=FALSE; END_IF // RetValue:=Axis1.METH_VelocityCmd( iCmd:=bRun ,iVelSetpoint:=fSetValue ,iVelAcc:=100.0 ,iVelDec:=100.0 ); RetValue:=Axis1.METH_JogFWBW( iFw:=bFw AND NOT bBw ,iBw:=bBw AND NOT bFw ,iVelSetpoint:=fSetValue ,iVelAcc:=100.0 ,iVelDec:=100.0 ); RetValue:=Axis1.METH_MoveAbs( iCmd:=bMoveAbs ,iVelSetpoint:=f32AbsVel ,iVelAcc:=f32AbsAcc ,iVelDec:=f32AbsDec ,iPosition:=f32AbsPos ); RetValue:=Axis1.METH_MoveRelative( iCmd:=bMoveRelative ,iVelSetpoint:=f32RelativeVel ,iVelAcc:=f32RelativeAcc ,iVelDec:=f32RelativeDec ,iDistance:=f32RelativePos ); R_TRIG(CLK:=start); IF R_TRIG.Q THEN iStep:=10; END_IF CASE iStep OF 10: f32RelativePos:=10.0; bMoveRelative:=TRUE; iCount:=iCount+1; IF bRunning THEN iStep:=15; END_IF; 15: IF bStopped THEN iStep:=20; END_IF 20: bMoveRelative:=FALSE; IF iCount>=10 THEN iCount:=0; iStep:=30; ELSE iStep:=10; END_IF; 30: f32RelativePos:=-10.0; bMoveRelative:=TRUE; iCount:=iCount+1; IF bRunning THEN iStep:=35; END_IF; 35: IF bStopped THEN iStep:=40; END_IF 40: bMoveRelative:=FALSE; IF iCount>=10 THEN iCount:=0; iStep:=10; ELSE iStep:=30; END_IF; END_CASE |
Download
最後はプロジェクトをRuntimeにDownloadしてください。
Result
こちらはTURCK PLCからDelta社のServo ドライブをEtherCAT経由で制御する動画です。
Download Project
こちらのLinkから今回の記事のプロジェクトをDownloadできます。
https://github.com/soup01Threes/Codesys/blob/main/TURCK-EtherCAT-DeltaServo.projectarchive