三菱電機#MXF-EtherCAT_PART05_FATEK SC3 Servoと接続しよう

こちらは新しい記事のシリーズで、三菱電機のMXF-EtherCATバージョンのCPUで様々な検証を行います。第5話ではMXF-EtherCATとFATEK社SC3 Series Single ServoをEtherCATで接続し、単軸のモーション制御を行います。

さ、FAを楽しもう!

Reference Link

https://soup01.com/ja/category/mitsubishi-jp/mxr/

https://soup01.com/ja/category/mitsubishi-jp/mxf/

https://soup01.com/ja/category/fatek/sc-series/

MC_SetPosition

このFBは、指定された軸の現在の位置(指令位置、実位置)を変更します。

VAR_INOUT

I/O variable

Type

Description

Axis

AXIS_REF

軸を指定します。

VAR_INPUT

I/O variable

Type

Description

Execute

BOOL

TRUEに設定すると、MC_SetPosition(現在位置変更)が実行されます。

Position

LREAL

指定軸の現在位置を変更するための目標位置を設定します。

Relative

BOOL

現在位置を相対距離で変更するか、絶対位置で変更するかを設定します。FALSE: 絶対位置で現在位置を変更します。
TRUE: 相対距離で現在位置を変更します。

ExecutionMode

INT(MC_EXECUTION_MODE)

MC_SetPosition(現在位置変更)の実行方式を設定します。
1: 完了時に実行(mcQueued)
3: 即時実行(mcSpeculatively)

Options

DWORD(HEX)

MC_SetPosition(現在位置変更)の機能オプションを指定されたビット位置に設定します。

VAR_OUTPUT

I/O variable

Type

Description

Done

BOOL

現在位置の変更が完了すると、TRUEになります。

Busy

BOOL

MC_SetPosition(現在位置変更)の実行中は、TRUEになります。

CommandAborted

BOOL

MC_SetPosition(現在位置変更)の実行が中断されると、TRUEになります。

Error

BOOL

エラーが発生すると、TRUEになります。

ErrorID

WORD(UINT)

エラーが発生した場合、エラーコードを出力します。エラーコードの詳細については、使用するコントローラのユーザーズマニュアルを参照してください。

CancelAccepted

BOOL

MC_SetPosition(現在位置変更)のキャンセルが受け付けられると、TRUEになります。

Implementation

FATEK SC3側

FATEK SC3 Servoのパラメータを設定します。

FATEKのSERVOツールProtunerを起動し、Pn20EとPn210を1に設定します。位置のスケーリングはMXF-EtherCAT PLCから行います。

MXF側

次は三菱電機のMXF-EtherCAT側を構築します。

EtherCATネットワーク構築

EtherCATネットワークを構築するにはModule Parameters→Module Extended Parametersをクリックします。

ESI Fileインストール

EtherCAT Configuration→ESI Managementをクリックします。

Add Fileをクリックします。

先程FATEK HPからダウンロードしたESI FILEを開きます。

FATEK SC3 Series Single 追加

SubDeviceを右クリック→Add SubDeviceします。

先程追加したFATEK SC3 Series Singleを選択し→OKで進みます。

Done!

Distributed Clocks設定

Distributed Clocks Tabを開き→Operation ModeをDC-Synchronします。

設定保存

Close with Reflecting the Settingをクリックしネットワーク設定を保存します。

軸割付

”Create”をクリックしFATEK SC3 Series SingleをAxisとして割り付けます。

Yesで進みます。

もう一度EtherCAT Configurationを開くとAxis→Number os Axesが1になります。

それはGXWORKS→Motion Setting→Axis→Axis001に該当します。

ラベル生成

Axisの制御はGXWORKSのAxis_Refを直接使用するので、特にラベルを作成する必要がありません。

軸設定

Axis→Axis001をクリックします。

Object Data

最初にReal Drive Axis→Basic Parameter→Object Dataを開き、右側のObject Dataリストを展開します。

こちらは実際ServoドライブのCoEと接続するIndexになります。

設定欄のとなりにある…ボタンをクリックします。

すべてのパラメータを修正できます。

MX-Fはこの設定によって、SDOで取得しようとします。FATEK SC3 Series SingleはSiUnitPosとSiUnitVelに対応しませんので、2つの設定を定数にする必要があります。

  • SiUnitPos:ドライブユニットのSI単位での位置を取得します。
  • SiUnitVel :ドライブユニットの SI 単位での速度を取得します。

三菱マニュアルの定義は以下で、定数を設定することができます。

三菱マニュアルの定義は以下で、定数を設定することができます。

OKで設定を保存することができます。

EncoderStatus1/HomeAbsCounter/HomeCycleCounter/InitAbsCounter/InitialCycleCounter/InitialPos/MaxAbsCounterがFATEK SC3 Series Single対応しませんので、空欄にしてください。

SupportControlDi/SupportControlDoがFATEK SC3 Series Single対応しませんので、空欄にしてください。

EncoderStatus2/ScaleCycleCounter/ScaleAbsCounterなどがFATEK SC3 Series Single対応しませんので、空欄にしてください。

こちらは設定のまとめになります。

SiUnitPos [CONST]0xFA010000

SiUnitVel [CONST]0x00000300

ControlDi1~7 空欄

StatusDo1~7 空欄

SupportedControlDi1~7 空欄

SupportedStatusDo1~7 空欄

EncoderStatus1 / 2 空欄

VelLimitValue 空欄

ScaleCycleCounter 空欄

ScaleAbsCounter 空欄

ScaleMeasurementEncoderResolution 空欄

ScaleMeasurementEncoderReceptionStatus 空欄

PositiveTorqueLimitValue 0x60E0 非対応なら空欄

NegativeTorqueLimitValue 0x60E1 非対応なら空欄

Absolute Position Control Setting

次はBasic Parameter→Absolute Position Control Settingを開きます。

Position Controlを1にします。

Position command unit

Position Command Unitをmmに設定します。

Drive unit Conversion Numerator

131072 Pulseを設定します。

Drive unit Conversion Denominator

Drive unit Conversion Denominatorを6mmに設定します。

Homing

Homing Required を0に設定します。

Start Permission at Homing Uncompleted

Start Permission at Homing Uncompleted設定を1にします。

Save保存

最後はApplyボタンで設定を保存します。

プログラム

次はプログラムを作成します。

dutServoCmd

fbAxisBasic FBにコマンドを発行するための構造体です。

dutServoMon

fbAxisBasic FBから情報を取得するための構造体です。

dutServo

こちらはdutServoCmdとdutServoMonをまとめた構造体です。

fc_Scale

スケーリングの関数を作成します。

ラベル
プログラム

fc_Scale:=((rRawInput-rRawMin)/rRawMax-rRawMin)*(rEngMax-rEngMin)+rEngMin;
IF fc_Scale <0.0 THEN
fc_Scale:=0.0;
END_IF;
;

fbAxisBasic

軸を制御するFBを作成します。

ラベル

こちらはfbAxisBasic FBで定義したラベルになります。

プログラム

こちらはfbAxisBasicのプログラムです。

xEnable:=ixEnable ;
xJogFWEnable:=xEnable
// AND NOT fbMC_Jog.Busy
AND NOT fbMC_MoveAbsolute.Busy
AND
NOT fbMC_MoveRelative.Busy
AND
NOT fbMC_MoveVelocity.Busy
AND
NOT fbMC_Home.Busy
AND
iodutServo.Monitor.xReadyStatus
AND NOT iodutAxis_REF.Md.Error
AND NOT iodutServo.Command.xServoJogBW
AND NOT fbMC_SetPosition.Busy
;
xJogBWEnable:=xEnable
//AND NOT fbMC_Jog.Busy
AND NOT fbMC_MoveAbsolute.Busy
AND
NOT fbMC_MoveRelative.Busy
AND
NOT fbMC_MoveVelocity.Busy
AND
NOT fbMC_Home.Busy
AND
iodutServo.Monitor.xReadyStatus
AND NOT iodutAxis_REF.Md.Error
AND NOT iodutServo.Command.xServoJogFW
AND NOT fbMC_SetPosition.Busy
;

xHomEnable:=xEnable
AND NOT fbMC_Jog.Busy
AND NOT fbMC_MoveAbsolute.Busy
AND
NOT fbMC_MoveRelative.Busy
AND
NOT fbMC_MoveVelocity.Busy
AND
NOT fbMC_Home.Busy
AND
iodutServo.Monitor.xReadyStatus
AND NOT iodutAxis_REF.Md.Error
AND NOT fbMC_SetPosition.Busy
;

xSetPosEnable:=xEnable
AND NOT fbMC_Jog.Busy
AND NOT fbMC_MoveAbsolute.Busy
AND
NOT fbMC_MoveRelative.Busy
AND
NOT fbMC_MoveVelocity.Busy
AND
NOT fbMC_Home.Busy
AND
iodutServo.Monitor.xReadyStatus
AND NOT iodutAxis_REF.Md.Error
AND NOT fbMC_Home.Busy
;

xMoveAbsEnable:=xEnable
AND NOT fbMC_Jog.Busy
// AND NOT fbMC_MoveAbsolute.Busy
AND
NOT fbMC_MoveRelative.Busy
AND
NOT fbMC_MoveVelocity.Busy
AND
NOT fbMC_Home.Busy
AND
iodutServo.Monitor.xReadyStatus
AND NOT iodutAxis_REF.Md.Error
AND NOT fbMC_SetPosition.Busy
;

xMoveRelEnable:=xEnable
AND NOT fbMC_Jog.Busy
AND NOT fbMC_MoveAbsolute.Busy
// AND NOT fbMC_MoveRelative.Busy
AND
NOT fbMC_MoveVelocity.Busy
AND
NOT fbMC_Home.Busy
AND
iodutServo.Monitor.xReadyStatus
AND NOT iodutAxis_REF.Md.Error
AND NOT fbMC_SetPosition.Busy
;

xMoveVelEnable:=xEnable
AND NOT fbMC_Jog.Busy
AND NOT fbMC_MoveAbsolute.Busy
AND
NOT fbMC_MoveRelative.Busy
// AND NOT fbMC_MoveVelocity.Busy
AND
NOT fbMC_Home.Busy
AND
iodutServo.Monitor.xReadyStatus
AND NOT iodutAxis_REF.Md.Error
AND NOT fbMC_SetPosition.Busy
;

fbMC_Power(
Axis:= iodutAxis_REF.AxisRef
,Enable:= xEnable AND iodutServo.Command.xServoEnb
,ServoON:= xEnable AND iodutServo.Command.xServoON
,Status=> iodutServo.Monitor.xPowerStatus
,ReadyStatus=> iodutServo.Monitor.xReadyStatus
// ,Busy=> ?BOOL?
// ,Error=> ?BOOL?
,ErrorID=> iodutServo.Monitor.wPowerONErrId
);

fbMC_Reset(
Axis:= iodutAxis_REF.AxisRef
,Execute:= iodutServo.Command.xServoReset
,Options:= 0
// ,Done=> ?BOOL?
// ,Busy=> ?BOOL?
// ,CommandAborted=> ?BOOL?
// ,Error=> ?BOOL?
// ,ErrorID=> ?WORD?
);


fbMC_Home(
Axis:= iodutAxis_REF.AxisRef
,Execute:= iodutServo.Command.xServoHome AND xHomEnable
,Position:= 0.0
,AbsSwitch:= ioudtMC_INPUT_REF
,Options:= 0
// ,Done=> ?BOOL?
// ,Busy=>
// ,Active=> ?BOOL?
// ,CommandAborted=> ?BOOL?
,Error=> iodutServo.Monitor.xHomeErr
,ErrorID=> iodutServo.Monitor.wHomeErrID
);

fbMC_SetPosition(
Axis:= iodutAxis_REF.AxisRef
,Execute:= iodutServo.Command.xServoSetPos AND xSetPosEnable
,Position:= iodutServo.Command.rSetPosition
,Relative:= FALSE
//,ExecutionMode:= ?INT?
//,Options:= ?DWORD?
//,Done=> ?BOOL?
//,Busy=> ?BOOL?
//,CommandAborted=> ?BOOL?
,Error=> iodutServo.Monitor.xSetPosErr
,ErrorID=> iodutServo.Monitor.wSetPosErrID
//,CancelAccepted=> ?BOOL?
);


fbMC_Jog(
Axis:= iodutAxis_REF.AxisRef
,JogForward:= xJogFWEnable AND iodutServo.Command.xServoJogFW
,JogBackward:= xJogBWEnable AND iodutServo.Command.xServoJogBW
,Velocity:= iodutServo.Command.rMoveJogVel
,Acceleration:= 10.0
,Deceleration:= 10.0
,Jerk:= 10.0
,Options:= 0
// ,Done=> ?BOOL?
,Busy=> iodutServo.Monitor.xJogBwBusy
// ,Active=> ?BOOL?
// ,CommandAborted=> ?BOOL?
,Error=> iodutServo.Monitor.xHomeErr
,ErrorID=> iodutServo.Monitor.wJogErrID
);


fbMC_Stop(
Axis:= iodutAxis_REF.AxisRef
,Execute:= iodutServo.Command.xServoStop
,Deceleration:= 10.0
,Jerk:= 10.0
,Options:= 0
,Done=> iodutServo.Monitor.xStopDone
,Busy=> iodutServo.Monitor.xStopBusy
// ,Active=> ?BOOL?
// ,CommandAborted=> ?BOOL?
,Error=> iodutServo.Monitor.xStopErr
,ErrorID=> iodutServo.Monitor.wStopErrID
);


fbMC_MoveAbsolute(
Axis:= iodutAxis_REF.AxisRef
,Execute:= iodutServo.Command.xServoMoveAbs
,ContinuousUpdate:= TRUE
,Position:= iodutServo.Command.rMoveAbsPos
,Velocity:= iodutServo.Command.rMoveAbsVel
,Acceleration:= 100.0
,Deceleration:= 100.0
,Jerk:= 100.0
,Direction:= 3
// ,BufferMode:= ?INT?
// ,Options:= ?DWORD?
,Done=> iodutServo.Monitor.xMoveAbsDone
,Busy=> iodutServo.Monitor.xMovAbsBusy
// ,Active=> ?BOOL?
// ,CommandAborted=> ?BOOL?
,Error=> iodutServo.Monitor.xMovAbsErr
,ErrorID=> iodutServo.Monitor.wMoveAbsErrId
);

fbMC_MoveRelative(
Axis:= iodutAxis_REF.AxisRef
,Execute:= iodutServo.Command.xServoMoveRel
,ContinuousUpdate:= TRUE
,Distance:= iodutServo.Command.rMoveRelPos
,Velocity:= iodutServo.Command.rMoveRelVel
,Acceleration:= 1000.0
,Deceleration:= 1000.0
,Jerk:= 1000.0
// ,BufferMode:= ?INT?
// ,Options:= ?DWORD?
// ,Done=> ?BOOL?
,Busy=> iodutServo.Monitor.xMovRelBusy
// ,Active=> ?BOOL?
// ,CommandAborted=> ?BOOL?
,Error=> iodutServo.Monitor.xMovRelErr
,ErrorID=> iodutServo.Monitor.wMoveRelErrId
);


fbMC_MoveVelocity(
Axis:= iodutAxis_REF.AxisRef
,Execute:= iodutServo.Command.xServoMoveVel
,ContinuousUpdate:= TRUE
,Velocity:= iodutServo.Command.rMoveVelVel
,Acceleration:= 100.0
,Deceleration:= 100.0
,Jerk:= 100.0
,Direction:= MC_DIRECTION__mcPositiveDirection
// ,BufferMode:= ?INT?
// ,Options:= ?DWORD?
,InVelocity=> iodutServo.Monitor.xMoveVelInVevl
// ,Busy=> ?BOOL?
// ,Active=> ?BOOL?
// ,CommandAborted=> ?BOOL?
,Error=> iodutServo.Monitor.xMovVelErr
,ErrorID=> iodutServo.Monitor.wMoveVelErrId
);


iodutServo.Monitor.rActualPos:=iodutAxis_REF.Md.CumulativePosition;
iodutServo.Monitor.rCommandPos:=iodutAxis_REF.Md.CommandedPosition;
iodutServo.Monitor.rCommandVel:=iodutAxis_REF.Md.CommandedVelocity;
iodutServo.Monitor.wErrorID:=iodutAxis_REF.Md.ErrorID;
iodutServo.Monitor.wWarningID:=iodutAxis_REF.Md.WarningID;


oxAbsDone:=iodutServo.Monitor.xMoveAbsDone;
oxError:=iodutServo.Monitor.xError;
oxWarning:=iodutServo.Monitor.xWarning;
oxMotionBusy:= fbMC_Jog.Busy
AND NOT fbMC_MoveAbsolute.Busy
AND
NOT fbMC_MoveRelative.Busy
AND
NOT fbMC_MoveVelocity.Busy
AND
NOT fbMC_Home.Busy
;
oxServoisReady:=iodutServo.Monitor.xPowerStatus;
orCurrentPosition:=iodutServo.Monitor.rActualPos;
owErrorID:=iodutServo.Monitor.wErrorID;
owWarningID:=iodutServo.Monitor.wWarningID;

pServo

最後は定周期のプログラムを作成します。

MAIN

こちらの構造化ラダーでWAGOのEtherCATカプラーから取得したアナログ入力データをスケーリングし、速度0-800に変換します。WAGOのEtherCATカプラーの入力ボタンと配線してる入力がONするたびに、相対位置決めを行います。

CPUと接続する

最後はPCとMXF-EtherCATをUSB-Cで接続します。

ダウンロード

プロジェクトをCPUにダウンロードし、電源を入れ直します。

結果

xServoONとxServoEnbをTRUEにします。

Done!Servoが現在Servo ONになりました。

こちらの動画から動作確認できます。

補足

Object Dataが設定を間違えると、よく以下のエラーが発生します。

H1A42 : SDO Communication Error

Parameter
:
PrConst
.SlaveObject.vSupportedControl…

シェアする

  • このエントリーをはてなブックマークに追加

フォローする