Project#SIMIT x TwinCAT x Profidrive Telegram111 Simulation

みなさんこんにちは。またsimit よ話になりますね。その前に、simulationのゴールは何でしょうか?私はよりによって現実世界の装置をできる限り再現できるようにすることが最終目的だと思います。なので、バーチャルのシミュレーションはどれほど実現できるかが重要になります。

SiemensのPLCSIM advancedを使用するか、

他社のplc のシミュレーターを使用する(ここでベッコフオートメーションのtwincat 3は実機なくても大分の機能も自分のパソコン上に実装でき、それも今回の記事がtwincat3を、使用する大きな理由です。)

Simit では様々なモデルを提供し、ほかの3Dモデルソフトと連携は可能です。

今回使用するドライブライブラリは標準のシーメンスdrive を拡張し、より多くのprofinet telegramをsupportできます。今回の記事ではその一つ、telegram 111を取り上げ説明します。

もちろんsimit のリリースによりさらに対応できるシミュレーションもふえますのでそこでsios (Siemens Industry Online Support)を見てください。

Simit のそれらのライブラリはprofinet telegramのベースで作成され、現地立ち上げやデバッグの時間短縮を期待できます。さらにオペレーターのトレーニングや新人研修なども活用できると思います。


Download

下記のリンク先にアクセスし、ライブラリをダウンロードしましょう。

https://support.industry.siemens.com/cs/document/109761007/drives-behavior-library-for-simit?dti=0&lc=en-BO

Configration

今回の構成はこうなります。PLCはTwinCATに置き換え、表示はTF1800表示します。SIMIT側がOPCUAServer立ち上げ、TwinCATがTF6100使用しアクセスします。

TwinCAT側のPLCプログラムはできるだけOOPのコンセプトを導入しProgram Exampleとしてみせます。みんな一緒に頑張りましょう。

Telegram111?

シーメンスの標準telegram 111は主にdrive のepos blocks とデータやり取りし、plc からdrive を制御することが可能になります。

そのtelegram 111はtelegram 110とすごく似ていて、さらにmessage frame が大きくなるイメージで、つまり交換できるデータ量が増えます。telegram 111 は12word のメモリを使用します。

そのtelegram111は以下の機能を提供します。

  • Basic positioner 位置決め機能
  • 32 bit 位置データ
  • 32 bit 速度データ
  • 16bit 加減速度データ
  • signs of lifeの監視
  • Error code warning code の周期受信

EPOS Operation Flow

TEL_111 Target

ここからtelegram111を説明します。

STW1

BitDeviceDescription
0Off1ONコマンド0=OFF1有効中 1=ON
1Off20=Off2 有効中
2Off30=Off3 有効中
3EncInverter 有効中
4RejTrvTask0=Travering Records使用1=MDI Discard travsering task使用
5IntMStop1=即停止しない
6TrvStartTraversing Task実行
7AckFaultFaultリセット
8Jog1Jog信号1
9Jog2Jog信号2
10LBLife Bit(1=PLC制御)
11RefStartHoming開始
12Bit12
13Bit13External block 変更(0>1)
14Bit14
15Bit15

STW2

BitDeviceDescription
0DDSBit0Drive data set bit0
1DDSBit1Drive data set bit1
2DDSBit2Drive data set bit2
3DDSBit3Drive data set bit3
4DDSBit4Drive data set bit4
5GlbStartGlobal start
6ReslCompSpeed ControllerのI-Component リセット
7ActPrkAxisParking axis有効する
8TrvFixedStpFixed endstopへ移動中
9GlbTrgComGlobal トリガーコマンド
10Bit10
11MotSwOverMotor Switchover完成
12MsZykBit0Master sign of life bit0
13MsZykBit1Master sign of life bit1
14MsZykBit2Master sign of life bit2
15MsZykBit3Master sign of life bit3

POS_STW1

BitDeviceDescription
0TrvBit0Selection Bit 0
1TrvBit1Selection Bit 1
2TrvBit2Selection Bit 2
3TrvBit3Selection Bit 3
4TrvBit4Selection Bit 4
5TrvBit5Selection Bit 5
6Bit6
7Bit7
8MdiTyp位置決めの種類0=相対位置決め1=絶対位置決め
9MdiPos回転軸がMDI Operationの位置決め・Setup Taskの回転方向1=正回転
10MdiNeg回転軸がMDI Operationの位置決め・Setup Taskの回転方向1=逆回転
11Bit11
12MdiTrTypMDI Task実行の信号種類設定0=立ち上げ1=Setpointが変わるだけで実行
13Bit13
14MdiSetupMDI Mode設定0=位置決め1=Setup
15MdiStart1=MDI Operation Mode

POS_STW2

BitDeviceDescription
0TrkModeTracking Mode開始
1SetRefPtReference Pointを設定する
2ActRefCamReference Camを有効する
3Bit3Fixed stopを有効する
4Bit4
5JogInc0=連続Jog1=パラメタからJog動作設定
6Bit6
7Bit7
8RefTypHomingの方法設定0=Reference Point approach1=Passive (on-the-fly) homing
9RefStDiReference pointと開始位置の方向0=プラス方向1=マイナス方向
10RefInpSPassive (on-the-fly) homingの信号ソース0=Probe 1有効1=Probe 2有効
11RefEdgePassive homingの検知方式設定0=立ち上げ1=たち下げ
12Bit12
13Bit13
14SftLimActSoftware Limit スイッチを有効する
15StpCmaActStop Cam有効する

OVERRIDE

Overrideです。

MDI_TARPOS

位置指令値になります。

MDI_VELOCITY

速度指令値になります。

MDI_ACC

加速度指令値です。

MDI_DEC

減速度指令値です。

User

1word のあまりがあり、アプリケーションに合わせて自由に割り当てることができます。


TEL_111 Actual

ZSW1

BitDeviceDescription
0RTS1=Power UP準備OK
1RDY1=Operation準備OK
2IOp1=Servo ONした、EPOS使用するの条件
3Fault1=重故障発生中
4NoOff2Act1=Off2が無効中
5NoOff3Act1=Off3が無効中
6PowInhbt1=Drive ONが無効中
7Alarm1=アラーム・Warning発生中
8NoFlwErr
9LbCr1=制御を要求
10TargPosDriveは目標位置に到着(Jog/相対位置決め/絶対位置決めでも使える)
11RefPSetDriveはReference Point設定された
12TrvTskAckTravering Block有効状態がDriveに承認された
13StndStill1=Driveは停止状態現在速度< Speed threshold3
14AccelDrive加速中
15DecelDrive減速中

ZSW2

BitDeviceDescription
0ActDDSBit0Drive data Set Bit0
1ActDDSBit1Drive data Set Bit1
2ActDDSBit2Drive data Set Bit2
3ActDDSBit3Drive data Set Bit3
4ActDDSBit4Drive data Set Bit4
5CmdActRelBrkRelease holding brake 有効
6TrqContModeトルク制御 Operation中
7ParkAxisActParking axis
8Bit8
9GibTrgReqGlobal Trigger Request中
10PulsEnServo ONのパルス信号受け、Drive Enable中
11MotSwOverActMotor Data set switchover Active
12SlvZykBit0Slave – Sign of life bit0
13SlvZykBit1Slave – Sign of life bit1
14SlvZykBit2Slave – Sign of life bit2
15SlvZykBit3Slave – Sign of life bit3

POS_ZSW1

BitDeviceDescription
0ActTrvBit0Activating Traveling Block Bit0
1ActTrvBit1Activating Traveling Block Bit1
2ActTrvBit2Activating Traveling Block Bit2
3ActTrvBit3Activating Traveling Block Bit3
4ActTrvBit4Activating Traveling Block Bit4 
5ActTrvBit5Activating Traveling Block Bit5
6Bit6
7Bit7
8StpCamMinActStop CAM Minus active
9StpCamPlsActStop CAM Plus active
10JogActJog mode有効中
11RefActReference mode有効中
12FlyRefActOn-the-fly homing有効中
13TrvBlActTraversing Blocks mode有効中
14MdiStupActMDI setup Mode有効中
15MdiPosActMDI 位置決めMode有効中

POS_ZSW2

BitDeviceDescription
0TrkModeActTracking Mode有効中
1VeloLimactSpeedリミット有効中
2SetPSたtSetpoint set
3PrntMrkOutPrint mark outside outer window
4FWD軸が正回転中
5BWD軸が逆回転中
6SftSwMinActSoftware リミット-が有効中
7SftSwPlsActSoftware リミット+が有効中
8PosSmCam1現在位置は<=Cam switch 位置1
9PosSmCam2現在位置は<=Cam switch 位置2
10TrvOut1Traversing block経由のDirect out 1
11TrvOut2Traversing block経由のDirect out 2
12FxStpRdFixed Stop reached
13FxStpTrRdFixed stop clamping torque reached
14TrvFxStpActTravel to fixed stop active
15CmdActTraversing Task有効された

MELDW

DriveのStatus -codeです。

XIST_A

現在の位置です。

NIST_B

現在の速度です。

FAULTCode

DriveのFault Codeです。

WARNCode

DriveのWarning Codeです。

user

1word のあまりがあり、アプリケーションに合わせて自由で割り当てることができます。

Block EPOS_Tel111


State

Simulation Block EPOS_Tel111は現在の状態を示す表示があります。

Test with Jog

01>02>08>1EこのようにServo OnからJogまでは01>02>08>1EのようにStatusをシフトしています、詳しくはManualみてください。

Test

Servo ON From Panel

ブログラムで動かす前に、まずcontrol panel から手で動かし動作確認するのが私のやり方です。simit simulationを起動し、block のところをクリックします。

そのような画面が表示されます。

Stw の強制on off やzsw の信号一覧やドライブのステータス確認できます。

最初はSTW1のLB信号をオンにします。

LBのとなりにある四角をクリックしてください。

そうすると、LBとなりにもう一つの四角が青色になります。もしエラーがあればまずAckFault 信号をいれてリセットしてください。

エラーがリセットされたら、次はservo を準備状態に移行します。

Enc、 ReqTrvTsk、IntMSop 信号をオンにします。 

次はOff2、 Off3をオンにします。

ドライブでZSW1のNoOff2Act NoOff3Actがオンになるはずです。あとRTS信号も返してくれます。

Servo on します。

Off1 をオンにしてください。


Servo onになったら、RTS、RDY、IOpはTrue になります。それでservo の準備OKです。

Absolute Positioning From Panel

絶対位置決めをpanel 上で行います。

Operation Mode settingsのエリアでValid のランプが赤くなってます。これは指令値が問題が有ることを示してます。

最後にこのエラーを解除するまで、続けてください。

POS_STW1 にあるMidTyp を1つ入れます。Mdiの絶対位置決めモードになり、そしMdiStartをオンし、Mdi mode にセットします。

さきvaild 赤ランプのエラー原因はMDI_VELOCITY MDI_ACC MDI_DECの3つのprofidrive data が0になってるからです。

Simulation block をクリックし、下のプロパティにあるinput をクリックします。

MDI_TARPOS MDI_VELOCITY MDI_ACC MDI_DECにそれぞれの指令値を入力します。

変数の隣にあるマイナスボタンをクリックします。

いまそれぞれのテスト値を入れてみました。

そしてblock 上に現在値が表示されるように123ボタンをクリックします。

よし、強制設定した値が入りましたね。

さっきのpanel をもう一度みますと、valid ランプが緑になりました。それで問題なし。

どこのメーカーでも同じだと思いますが、位置決めする前にまずreference point を決める必要があります。色々なhoming 方法がありますが、今回は一番簡単な直接reference point 指定する方法をしました。

POS_STW2のSetRelPt信号をオンにします。

もちろん、homing 方向きめ、STW1のRefStart 信号をオンする方法もありますが、ここで説明しませんので、きになる方manual を参考にしてください。

話に戻りますが、reference point がOKになった状態であれらZSW1のRefPSet がTrue になります。

最後は、Mdi task を実行するのみです。

TrvStart をオンにしてみてください。

下記のgif のように、servo が目標値に向かって加速したり減速したりします。

そして、目標値に到着するとZSW1のTargPos

信号がtrue になります。そのflag を位置決め完了信号として使用しましょう。


Relative Positioning From Panel

次は相対位置決めをします。

やり方はさっきの絶対位置決めと同じく、POS_STW1のMidTyp を0にします。

そうすると、いまservo が相対位置決めモードになります。

MDI_TARPOSをテスト値50にいれます。

つまり今いる位置が+50 になります。

逆に-50ならいまいる位置を50バックします。


以下のgif のように、相対位置決めを開始すると元が500はいま550になります。

Project

SIMIT SIde

ではSIMIT側から始めます。

Mapping

まずOPCUA Couplingを作成します。

Input/Outptを定義します。

Chart

最後は変数群をEPOS_Tel111割り付ければOKです。

TwinCAT Side

SIMT側が終わったら次はTwinCAT側です。このFunction BlockはSiemensのEPOS Library、あの有名なSINA_POSを分解した簡単バージョンです。よろしくおねがいします。

DUT

DUT_Telg111_ePos_HMI_P

このDUTではhim からのservo 操作に必要なデバイスを定義します。

TYPE DUT_Telg111_ePos_HMI_PB :
STRUCT
//PB
bOFF1 :BOOL;
bReset :BOOL;
bJogFw :BOOL;
bJogbw :BOOL;
bHome :BOOL;
bMoveAbs :BOOL;
bMoveRel :BOOL;
//Pars
d32CmdVel :DINT:=100;
d32CmdAcc :DINT:=10;
d32CmdDec :DINT:=10;
d32RelPos :DINT:=10;

//Station
arrStations :ARRAY[0..9]OF DINT;
d16CmdStations :INT;
//
bTableInput :BOOL:=True;
END_STRUCT
END_TYPE

DUT_Telg111_ePos_HMI_PL

Servo の状態をhim 表示させるためのデバイスです。

TYPE DUT_Telg111_ePos_HMI_PL :
STRUCT
bReady :BOOL;
bBusy :BOOL;
bError :BOOL;
bWarning :BOOL;
bFwing :BOOL;
bBwing :BOOL;
bHomed :BOOL;
bReached :BOOL;
bStopped :BOOL;

d32ActualSpeed :DINT;
d32ActualPos :DINT;
d16WarningCode :DINT;
d16ErrorCode :DINT;
d16StatusWord :DINT;

d16ActualStation :int;

END_STRUCT
END_TYPE

DUT_Telg111_ePos_HMI 

PBとPLを定義したあと、こちらのDUTでまとめて定義する。

TYPE DUT_Telg111_ePos_HMI :
STRUCT
PB:DUT_Telg111_ePos_HMI_PB;
PL:DUT_Telg111_ePos_HMI_PL;

END_STRUCT
END_TYPE

DUT_Telegram111_ePos_Pos_STW1

STW1のDUTです。

TYPE DUT_Telegram111_ePos_Pos_STW1 :
STRUCT
bTrvBit0 :BIT;
bTrvBit1 :BIT;
bTrvBit2 :BIT;
bTrvBit3 :BIT;
bTrvBit4 :BIT;
bTrvBit5 :BIT;
b6,b7 :BIT;
bMdiTyp :BIT; //0=Relative,1=absolute
bMdiPos :BIT;
bMdiNeg :BIT;
b11 :BIT;
bMdiTrTyp :BIT;
b13 :BIT;
bMdiSetup :BIT; //0=Position,1=Setup
bMdiStart :BIT; //Operating mode MDI / direct setpoint specification
END_STRUCT
END_TYPE

DUT_Telegram111_ePos_Pos_STW2 

STW2のDUTです。

TYPE DUT_Telegram111_ePos_Pos_STW2 :
STRUCT
bTrkMode :BIT;
bSetRefPt :BIT;
bActRefCam :BIT;
b3,b4 :BIT;
bJogInc :BIT;
b6,b7 :BIT;
bRefTyp :BIT;
bRefStDi :BIT;
bRefInpS :BIT;
bRefEdge :BIT;
b12,b13 :BIT;
bSftLimAct :BIT;
bStpCamAct :BIT;

END_STRUCT
END_TYPE

DUT_Telegram111_ePos_STW1 

POS_STW1のDUTです。

TYPE DUT_Telegram111_ePos_STW1 :
STRUCT
bOff1 :BIT;
bOff2 :BIT;
bOff3 :BIT;
bEnc :BIT; //Ivnerter Enable
bRejTrvTsk :BIT;
bIntMStop :BIT;
bTrvStart :BIT; //Activate traversing task
bAckFault :BIT;
bJog1 :BIT;
bJog2 :BIT;
bLB :BIT;
bRefStart :BIT;
b12,b13,b14,b15 :BIT;
END_STRUCT
END_TYPE

DUT_Telegram111_ePos_STW2 

POS_STW2のDUTです。

TYPE DUT_Telegram111_ePos_STW2 :
STRUCT
bDDSBit0 :BIT;
bDDSBit1 :BIT;
bDDSBit2 :BIT;
bDDSBit3 :BIT;
bDDSBit4 :BIT;
bGlbStart :BIT;
bResIComp :BIT;
bActPrkAxis :BIT;
bTrvFixedStp :BIT;
bGlbTrgCom :BIT;
b10 :BIT;
bMotSwOver :BIT;
bMsZykBit0 :BIT;
bMsZykBit1 :BIT;
bMsZykBit2 :BIT;
bMsZykBit3 :BIT;

END_STRUCT
END_TYPE

u_Telegram111_ePos_STW1 

Simit のopcua server がsupport てきるdata type と合わせる必要がありますのでunion type わ再定義します。

そうするとtwincat 側が割付け必要なのはそのrawだけになります。

TYPE u_Telegram111_ePos_STW1 :
UNION
STW :DUT_Telegram111_ePos_STW1;
raw :LINT;
END_UNION
END_TYPE

u_Telegram111_ePos_STW2 

u_Telegram111_ePos_STW1の定義理由と同じです。

TYPE u_Telegram111_ePos_STW2 :
UNION
STW :DUT_Telegram111_ePos_STW2;
raw :LINT;
END_UNION
END_TYPE

DUT_Telegram111_ePos_STW 

最後に、telegram 111のSTW message frame まとめで再定義するOKです!

TYPE DUT_Telegram111_ePos_STW :
STRUCT
STW1 :u_Telegram111_ePos_STW1;
Pos_STW1 :u_Telegram111_ePos_Pos_STW1;
Pos_STW2 :u_Telegram111_ePos_Pos_STW2;
STW2 :u_Telegram111_ePos_STW2;
OVERRIDE :LINT;
MDI_TAGPOS :LINT;
MDI_VELOCITY :LINT;
MDI_ACC :LINT;
MDI_DEC :LINT;
User :LINT;

END_STRUCT
END_TYPE

DUT_Telegram111_ePos_Pos_ZSW1 

ZSW1のDUTです。

TYPE DUT_Telegram111_ePos_Pos_ZSW1 :
STRUCT
bActTrvBit0 :BIT;
bActTrvBit1 :BIT;
bActTrvBit2 :BIT;
bActTrvBit3 :BIT;
bActTrvBit4 :BIT;
bActTrvBit5 :BIT;
b6,b7 :BIT;
bStpCamMinAct :BIT;
bStpCamPlsAct :BIT;
bJogAct :BIT;
bRefAct :BIT;
bFlyRefAct :BIT;
bTrvBlAct :BIT;
bMdiStupAct :BIT;
bMdiPosAct :BIT;

END_STRUCT
END_TYPE

DUT_Telegram111_ePos_Pos_ZSW2

ZSW2のDUTです。

TYPE DUT_Telegram111_ePos_Pos_ZSW2 :
STRUCT
bTrkModeAct :BIT;
bVeloLimAct :BIT;
bSetPStat :BIT;
bPrntMrkOut :BIT;
bFWD :BIT;
bBWD :BIT;
bSftSwMinAct :BIT;
bSftSwPlsAct :BIT;
bPosSmCam1 :BIT;
bPosSmCam2 :BIT;
bTrvOut1 :BIT;
bTrvOut2 :BIT;
bFxStpRd :BIT;
bFxStpTrRd :BIT;
bTrvFxStpAct :BIT;
bCmdAct :BIT;

END_STRUCT
END_TYPE

DUT_Telegram111_ePos_ZSW1 

POS_ZSW1のDUTです。

TYPE DUT_Telegram111_ePos_ZSW1 :
STRUCT
bRTS :BIT;
bRDY :BIT;
bIOp :BIT;
bFault :BIT;
bNoOff2Act :BIT;
bNoOff3Act :BIT;
bPowInhbt :BIT;
bAlarm :BIT;
bNoFlwErr :BIT;
bLbCr :BIT;
bTargPos :BIT;
bRefPSet :BIT;
bTrvTskAck :BIT;
bStndStill :BIT;
bAccel :BIT;
bDecel :BIT;

END_STRUCT
END_TYPE

DUT_Telegram111_ePos_ZSW2 

ZSW2のDUTです。

TYPE DUT_Telegram111_ePos_ZSW2 :
STRUCT
bActDDSBit0 :BIT;
bActDDSBit1 :BIT;
bActDDSBit2 :BIT;
bActDDSBit3 :BIT;
bActDDSBit4 :BIT;
bCmdActRelBrk :BIT;
bTrqContMode :BIT;
bParkAxisAct   :BIT;
b8 :BIT;
bGlbTrgReq :BIT;
bPulsEn :BIT;
bMotSwOverAct :BIT;
bSlvZykBit0 :BIT;
bSlvZykBit1 :BIT;
bSlvZykBit2 :BIT;
bSlvZykBit3 :BIT;

END_STRUCT
END_TYPE

u_Telegram111_ePos_Pos_ZSW1 

u_Telegram111_ePos_STW1の定義理由と同じです。

TYPE u_Telegram111_ePos_Pos_ZSW1 :
UNION
ZSW :DUT_Telegram111_ePos_Pos_ZSW1;
raw :LINT;
END_UNION
END_TYPE

u_Telegram111_ePos_Pos_ZSW2 

u_Telegram111_ePos_STW1の定義理由と同じです。

TYPE u_Telegram111_ePos_Pos_ZSW2 :
UNION
ZSW :DUT_Telegram111_ePos_Pos_ZSW2;
raw :LINT;
END_UNION
END_TYPE

u_Telegram111_ePos_ZSW1 

u_Telegram111_ePos_STW1の定義理由と同じです。

TYPE u_Telegram111_ePos_ZSW1 :
UNION
ZSW :DUT_Telegram111_ePos_ZSW1;
raw :LINT;
END_UNION
END_TYPE

u_Telegram111_ePos_ZSW2 

u_Telegram111_ePos_STW1の定義理由と同じです。

TYPE u_Telegram111_ePos_ZSW2 :
UNION
ZSW :DUT_Telegram111_ePos_ZSW2;
raw :LINT;
END_UNION
END_TYPE

DUT_Telegram111_ePos_ZSW 

最後に、telegram 111のZSW

 message frame まとめで再定義するOKです!

TYPE DUT_Telegram111_ePos_ZSW :
STRUCT
ZSW1 :u_Telegram111_ePos_ZSW1;
POS_ZSW1 :u_Telegram111_ePos_Pos_ZSW1;
POS_ZSW2 :u_Telegram111_ePos_Pos_ZSW2;
ZSW2 :u_Telegram111_ePos_ZSW2;
MELDW :LINT;
XIST_A :LINT;
NIST_B :LINT;
FAULTCode :LINT;
WARNCode :LINT;
User :LINT;
END_STRUCT
END_TYPE

DUT_Telegram111_ePos 

STW とZSWをそれぞれ分けてfunction block 定義するのは面倒だし名前ややこしくなりますので、STWはprocess output , ZSWはprocess input として更に定義します。

このデータタイブのfunction block内で使用します。

TYPE DUT_Telegram111_ePos :
STRUCT
STW AT %Q* :DUT_Telegram111_ePos_STW;
ZSW AT %I* :DUT_Telegram111_ePos_ZSW;
END_STRUCT
END_TYPE

FB_Telgram111_Basic

このfunction block はtelegram 111使用しMdi mode でservo on , home , jog ,相対位置決め,絶対位置決めと状態診断を最低限で実装したものです。なのでinterlock は絶対たりませんので、流用するのであればそのock extend しinterlock と機能を追加するか、参考にして書き直すかがおすすめです。

VAR

FUNCTION_BLOCK FB_Telgram111_Basic IMPLEMENTS ITF_Teleg111
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
IOs :DUT_Telegram111_ePos;
_bError :BOOL;
_bWarning :BOOL;
END_VAR

PROPERTY Busy : BOOL

GET

Servo がコマンド実行中か動いてる最中であればtrue 返しします。

Busy:=NOT Fwing
AND NOT Bwing
AND NOT IOs.ZSW.POS_ZSW2.ZSW.bCmdAct
;

PROPERTY Bwing : BOOL

GET

Servo が逆回転であればtrue 返しします。

Bwing:=IOs.ZSW.POS_ZSW2.ZSW.bBWD;

PROPERTY DriveErroCode : DINT

GET

Servo のerror code を返しします。

DriveErroCode:=LINT_TO_DINT(IOs.ZSW.WARNCode);

PROPERTY DriveStatusCode : DINT

GET

Servo のstatus code を返しします。

DriveStatusCode:=LINT_to_DINT(IOs.ZSW.MELDW);

PROPERTY DriveWarningCode : DINT

GET

Servo のwarning code を返しします。

DriveWarningCode:=LINT_TO_DINT(IOs.ZSW.WARNCode);

PROPERTY Error : BOOL

Servo がエラー中であればtrue 返しします。

GET
Error:=IOs.ZSW.ZSW1.ZSW.bFault;

PROPERTY Fwing : BOOL

Servo が正回転であればtrue 返しします。

GET
Fwing:=IOs.ZSW.POS_ZSW2.ZSW.bFWD;

PROPERTY Homed : BOOL

Servo がreferenceすみの状態であればtrue 返しします。

GET
Homed:=IOs.ZSW.ZSW1.ZSW.bRefPSet;

PROPERTY ReachPosition : BOOL

Servo が位置決め完了であればtrue 返しします。

GET
ReachPosition:=IOs.ZSW.ZSW1.ZSW.bTargPos;

PROPERTY Ready : BOOL

Servo がready の状態であればtrue 返しします。

GET
Ready:=IOs.ZSW.ZSW1.ZSW.bIOp;

PROPERTY Stopped : BOOL

Servo が停止中であればtrue 返しします。

GET
Stopped:=NOT Fwing AND NOT Bwing;

PROPERTY Warning : BOOL

Servo がwarning発生中であればtrue 返しします。

GET
Warning:=IOs.ZSW.ZSW1.ZSW.bAlarm;

PROPERTY ActualPos : DINT

Servo の現在位置を返します。

GET
ActualPos:=LINT_TO_DINT(IOs.ZSW.XIST_A);

PROPERTY ActualSpeed : DINT

Servo の現在速度を返します。

GET
ActualSpeed:=LINT_TO_DINT(IOs.ZSW.NIST_B);

METHOD Home : BOOL

呼び出すとservo がreference point をセットします。

VAR_INPUT
in : BOOL;
END_VAR
VAR_INST
R_TRIG:R_TRIG;
TON:TON;

END_VAR

R_TRIG(
CLK:=in
);

IF R_TRIG.Q  AND Stopped AND NOT Error THEN
IOs.STW.Pos_STW2.STW.bSetRefPt:=TRUE;
END_IF

TON(IN:=IOs.STW.Pos_STW2.STW.bSetRefPt
,PT:=T#1S
);
IF TON.Q THEN
IOs.STW.Pos_STW2.STW.bSetRefPt:=False;
END_IF

METHOD JogBW : BOOL

呼び出すとinがtrue であればservo がjog 逆回転し始めます。

VAR_INPUT
in:BOOL;
END_VAR


IOs.STW.STW1.STW.bJog2:=in AND NOT Error;
JogBW:=IOs.STW.STW1.STW.bJog2;

METHOD JogFW : BOOL

呼び出すとinごtrueてあればservo がjog 正回転し始めます。

VAR_INPUT
in:BOOL;
END_VAR


IOs.STW.STW1.STW.bJog1:=in AND NOT Error;
JogFW:=IOs.STW.STW1.STW.bJog1;


METHOD moveAbs : BOOL

呼び出すとservoがメソッドの位置、速度、加速度と減速度に沿って絶対位置決めします。

VAR_INPUT
in : BOOL;
pos:DINT;
vel:DINT;
Acc:DINT;
dec:DINT;
END_VAR
VAR_INST
StartCmd :R_TRIG;
CmdDelay :TON;
CmdOff :TON;
END_VAR
.

CmdDelay(
IN:=CmdDelay.Q AND NOT Busy AND Homed
,PT:=T#0.2S
);

StartCmd(
CLK:=in
);

IF   StartCmd.Q THEN
IOs.STW.Pos_STW1.STW.bMdiTyp:=TRUE;
IOs.STW.MDI_TAGPOS:=pos;
IOs.STW.MDI_ACC:=Acc;
IOs.STW.MDI_DEC:=dec;
IOs.STW.MDI_VELOCITY:=vel;
IOs.STW.STW1.STW.bTrvStart:=TRUE;
END_IF

CmdOff(
IN:=IOs.STW.STW1.STW.bTrvStart
,PT:=T#1S
);

IF CmdOff.Q THEN
IOs.STW.STW1.STW.bTrvStart:=FALSE;
END_IF

moveAbs:=IOs.STW.Pos_STW1.STW.bMdiTyp ;


METHOD moveRel : BOOL

呼び出すとservoがメソッドの位置、速度、加速度と減速度に沿って相対位置決めします。

VAR_INPUT
in : BOOL;
pos : DINT;
vel : DINT;
Acc : DINT;
dec : DINT;
END_VAR
VAR_INST
StartCmd :R_TRIG;
CmdDelay :TON;
CmdOff :TON;
END_VAR


CmdDelay(
IN:=CmdDelay.Q AND NOT Busy AND Homed
,PT:=T#0.2S
);

StartCmd(
CLK:=in
);

IF  StartCmd.Q THEN
IOs.STW.Pos_STW1.STW.bMdiTyp:=FALSE;
IOs.STW.MDI_TAGPOS:=pos;
IOs.STW.MDI_ACC:=Acc;
IOs.STW.MDI_DEC:=dec;
IOs.STW.MDI_VELOCITY:=vel;
IOs.STW.STW1.STW.bTrvStart:=TRUE;
END_IF

CmdOff(
IN:=IOs.STW.STW1.STW.bTrvStart
,PT:=T#1S
);

IF CmdOff.Q THEN
IOs.STW.STW1.STW.bTrvStart:=FALSE;
END_IF

moveRel:=NOT IOs.STW.Pos_STW1.STW.bMdiTyp ;

METHOD Reset : BOOL

呼び出すとリセットflag をservo に渡しします。

VAR_INPUT
in:BOOL;
END_VAR


IOs.STW.STW1.STW.bAckFault:=in;

METHOD ServoON : BOOL

呼び出すとin がオンしてる間servo off1 信号をservo へ渡しします。

VAR_INPUT
in : BOOL;
END_VAR
VAR_INST
TON:TON;
END_VAR

TON(IN:=in
,PT:=T#0.2S
);

IOs.STW.STW1.STW.bOff1:=TON.Q;

METHOD SetDefaultConfiguration : BOOL

最低限必要なビットをセットします。アプリケーションに合わせてそのメソッドをoverwriteしてください。

IOs.STW.STW1.STW.bOff2 :=TRUE;
IOs.STW.STW1.STW.bOff3 :=TRUE;
IOs.STW.STW1.STW.bEnc :=TRUE;
IOs.STW.STW1.STW.bIntMStop :=TRUE;
IOs.STW.STW1.STW.bRejTrvTsk :=TRUE;
IOs.STW.STW1.STW.bLB :=TRUE;
IOs.STW.Pos_STW1.STW.bMdiStart :=TRUE;

POU-MAIN

今回はあえてhmi のデバイスをfunction blockに組み込めないようにします。なぜかというと最近は色々組めすぎるになるとあとからの柔軟性が減ってしまうと感じた。でも、そのまま書くとプログラムが長くなり可読性が減少します。

Beckhoff Siemens codesys などライブラリを提供するときはあくまでもここまでで、そのあとのほかの操作の連携は自力で実装する必要があります。もちろんもっとかっつりの操作画面と自動手動インタフェースが提供されますが、カスタマイズするときにその分、難易度が上がります。

そのサンブルコードはまずopc ua 接続をチェック>function block呼び出し>servo on> reset >home > jog >error 検知>相対位置決めと絶対位置決め>hmi data とやり取りの順です。

PROGRAM MAIN
VAR
bEnable:BOOL;
OpcUaDeviceStatus AT %I*:OpcUaDeviceStatus;
OpcUaDeviceControl AT %Q*:OpcUaDeviceControl;
Servo1 :FB_Telgram111_Basic;
HMIs:DUT_Telg111_ePos_HMI;
bCmdsVaild:BOOL;
BackupCmd:INT;
d32Cmdpos:DINT;
bIL:BOOL;
R_TRIG,PosReached,AbsMoving:R_TRIG;
END_VAR


IF OpcUaDeviceStatus.Connected THEN
OpcUaDeviceControl.Write_Enable:=TRUE;
bEnable:=True;
ELSE
OpcUaDeviceControl.Write_Enable:=FALSE;
bEnable:=FALSE;
END_IF




Servo1();
Servo1.SetDefaultConfiguration();
Servo1.ServoON(in:=HMIs.PB.bOFF1 AND bEnable);
Servo1.Reset(in:=HMIs.PB.bReset);
Servo1.Home(in:=HMIs.PB.bHome);
R_TRIG(
CLK:=Servo1.Homed
);
IF R_TRIG.Q THEN
HMIs.PB.bHome:=FALSE;
END_IF;

bIL:= NOT HMIs.PB.bMoveRel AND NOT HMIs.PB.bJogbw AND NOT HMIs.PB.bMoveAbs;
IF Servo1.JogFW(in:=HMIs.PB.bJogFw AND bIL) THEN
HMIs.PL.d16ActualStation:=0;
END_IF

bIL:= NOT HMIs.PB.bMoveRel AND NOT HMIs.PB.bJogfw AND NOT HMIs.PB.bMoveAbs;
IF Servo1.JogBW(in:=HMIs.PB.bJogbw AND bIL) THEN
HMIs.PL.d16ActualStation:=0;
END_IF



bIL:= NOT HMIs.PB.bMoveRel AND NOT HMIs.PB.bJogbw AND NOT HMIs.PB.bJogFw;

bCmdsVaild:=HMIs.PB.d16CmdStations <>0 AND BackupCmd <> HMIs.PB.d16CmdStations;

AbsMoving(CLK:=HMIs.PB.bMoveAbs AND bCmdsVaild AND bIL);

IF AbsMoving.Q THEN
d32Cmdpos:=HMIs.PB.arrStations[HMIs.PB.d16CmdStations];
BackupCmd:=HMIs.PB.d16CmdStations;
HMIs.PB.d16CmdStations:=0;
HMIs.PL.d16ActualStation:=0;
END_IF

Servo1.moveAbs(
in:=HMIs.PB.bMoveAbs AND bCmdsVaild
,pos:=d32Cmdpos
,vel:=HMIs.PB.d32CmdVel
,Acc:=HMIs.PB.d32CmdAcc
,dec:=HMIs.PB.d32CmdDec
)
;
bIL:= NOT HMIs.PB.bMoveAbs AND NOT HMIs.PB.bJogbw AND NOT HMIs.PB.bJogFw;
IF
Servo1.moveRel(
in:=HMIs.PB.bMoveRel AND bIL
,pos:=HMIs.PB.d32RelPos
,vel:=HMIs.PB.d32CmdVel
,Acc:=HMIs.PB.d32CmdAcc
,dec:=HMIs.PB.d32CmdDec)
THEN
HMIs.PL.d16ActualStation:=0;
END_IF;

PosReached(CLK:=Servo1.ReachPosition);

IF PosReached.Q THEN

HMIs.PL.d16ActualStation:=BackupCmd;
HMIs.PB.d16CmdStations:=0;
BackupCmd:=0;

END_IF


//Status
HMIs.PL.bBusy:=Servo1.Busy;
HMIs.PL.bBwing:=Servo1.Bwing;
HMIs.PL.bFwing:=Servo1.Fwing;
HMIs.PL.bError:=Servo1.Error;
HMIs.PL.bHomed:=Servo1.Homed;
HMIs.PL.bReached:=Servo1.ReachPosition;
HMIs.PL.bReady:=Servo1.Ready;
HMIs.PL.bStopped:=Servo1.Stopped;
HMIs.PL.bWarning:=Servo1.Warning;
HMIs.PL.d32ActualPos:=Servo1.ActualPos/10;
HMIs.PL.d32ActualSpeed:=Servo1.ActualSpeed/100;
HMIs.PL.d16ErrorCode:=Servo1.DriveErroCode;
HMIs.PL.d16StatusWord:=Servo1.DriveStatusCode;
HMIs.PL.d16WarningCode:=Servo1.DriveWarningCode;

HMIs.PB.arrStations[1]:=-100;
HMIs.PB.arrStations[2]:=100;
HMIs.PB.arrStations[3]:=150;
HMIs.PB.arrStations[4]:=300;
HMIs.PB.arrStations[5]:=10;
HMIs.PB.arrStations[6]:=0;
HMIs.PB.arrStations[7]:=-40;
HMIs.PB.arrStations[8]:=60;
HMIs.PB.arrStations[9]:=90;

Visualization

こちらは操作画面です。


Result

必要なposition とコマンドに応じてservo が動きます。

Jog

Rel

Abs

Source Code

https://github.com/soup01Threes/TwinCAT3/blob/main/TwinCAT%20Project1_Telegram111_WithSIMIT.zip

Footer_Basic

Please Support some devices for my blog

Amazon Gift List

Find ME

Twitter:@3threes2
Email:soup01threes*gmail.com (* to @)
YoutubeChannel:https://www.youtube.com/channel/UCQ3CHGAIXZAbeOC_9mjQiWQ

シェアする

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

フォローする