今回の記事ではBeckhoff TF6421を利用しPLCの変数をXML Fileにデータを書き込みます。さ、はじめよう!
Reference Link
Reference Video
Beckhoff.TF6421でXML Dataを読んでみよう
Beckhoff.TF6421でXML Dataを書き込んでみよう
Function Block
今回は記事で使用するFunction Blockを紹介します。
FB_XMLSRVWRITE
こちらのFB_XmlSrvWrite は、PLC 変数の値を XML ファイルに書き込むために使用できます。入力変数 sXPath は、sFilePath で指定された XML ファイルの有効なノードを指す必要があります。
VAR_INPUT
Variable | Data Type | Description |
sNetId | T_AmsNet_Id | TwinCAT 3 XMLサーバのネットワークアドレスであり、Local PCでは、空の文字列を指定してください。 |
ePath | E_OpenPath | ファイルを開くターゲットデバイス上のTwinCATシステムパスを指定する |
nMode | WORD | XMLファイルの評価方法を制御することができ、現在サポートするのはXMLSRV_SKIPMISSINGとXmlSrvReadのみになります。 |
pSymAddr | DWORD | XML ファイルに書き込む PLC 変数のアドレスOffset。 |
cbSymSize | UDINT | XML ファイルに書き込む PLC 変数のサイズ。 |
sFilePath | T_MaxString | FBが開くファイルのパスとファイル名を指定します。注意するのはパスはローカルコンピュータのファイルシステムのみで、ネットワークではパスは使用できません。 |
sXPath | T_MaxString | データアクセスする XML ドキュメント内のタグのアドレスになります。 |
bExecute | BOOL | 立ち上げ信号でFBを実行する |
tTimeout | TIME | FBの最大実行時間 |
VAR_OUTPUT
Variable | Data Type | Description |
bBusy | BOOL | True=FB実行中 |
bError | BOOL | True=FBエラーあり |
nErrId | UDINT | TC3 XML Serverから返答したエラーコード |
FB_XmlSrvWriteByName
こちらのFB_XmlSrvWriteByName は、PLC 変数の値を XML ファイルに書き込むために使用できます。入力変数 sXPath は、sFilePath で指定された XML ファイル内の有効なノードを指す必要があります。
VAR_INPUT
Variable | Data Type | Description |
sNetId | T_AmsNet_Id | TwinCAT 3 XMLサーバのネットワークアドレスであり、Local PCでは、空の文字列を指定してください。 |
ePath | E_OpenPath | ファイルを開くターゲットデバイス上のTwinCATシステムパスを指定する |
nMode | WORD | XMLファイルの評価方法を制御することができ、現在サポートするのはXMLSRV_SKIPMISSINGとXmlSrvReadのみになります。 |
sSymName | T_MaxString | XML ファイルに書き込む PLC シンボル名になります。 |
sFilePath | T_MaxString | FBが開くファイルのパスとファイル名を指定します。注意するのはパスはローカルコンピュータのファイルシステムのみで、ネットワークではパスは使用できません。 |
sXPath | T_MaxString | データアクセスする XML ドキュメント内のタグのアドレスになります。 |
bExecute | BOOL | 立ち上げ信号でFBを実行する |
tTimeout | TIME | FBの最大実行時間 |
VAR_OUTPUT
Variable | Data Type | Description |
bBusy | BOOL | True=FB実行中 |
bError | BOOL | True=FBエラーあり |
nErrId | UDINT | TC3 XML Serverから返答したエラーコード |
Implementation1
Implemenation1はFB_XmlSrvWrite Function Blockを利用しPLC変数をXML Fileに書き込みます。
DUT_XMLWrite
こちらはImplemenation1でXML Fileに書き込む変数の構造体になります。
TYPE DUT_XMLWrite : STRUCT myBool:BOOL; myReal:REAL; myInt:INT; myArray:ARRAY[0..41]OF DINT; END_STRUCT END_TYPE |
MAIN
VAR
こちらはImplemenation1で使用したした変数になります。
PROGRAM MAIN VAR //Example1 myValue1:DUT_XMLWrite; fbxmlSrvWrite:FB_XmlSrvWrite; bExecuteXMLWrite:BOOL; sFilePathXMLWrite: T_MaxString:=’C:\Users\threespc02\OneDrive\Desktop\myXML1.xml’; sXPathXMLWrite : T_MaxString:=’/dataentry/MAIN.value1′; iCoutner:INT; iCheck:INT; END_VAR |
Program
fbxmlSrvWrite( nMode:=XMLSRV_ADDMISSING ,pSymAddr:=ADR(myValue1) ,cbSymSize:=SIZEOF(myValue1) ,sFilePath:=sFilePathXMLWrite ,sXPath:=sXPathXMLWrite ,bExecute:=bExecuteXMLWrite ); IF bExecuteXMLWrite AND (fbxmlSrvWrite.bBusy OR fbxmlSrvWrite.bError) THEN iCheck:=iCheck+1; bExecuteXMLWrite:=False; END_IF; |
Result
bExecuteXMLWriteをTrueにし、Function Blockを実行します。
TwinCAT3 IPC上でmyXML1.xmlが生成されました。
XML Fileにもデータを書き込みました!
Implementation2
Implemenation2FB_XmlSrvWriteByName Function Blockを利用しPLC変数をXML Fileに書き込みます。
DUT_XMLWriteByName
こちらはImplemenation2でXML Fileに書き込む変数の構造体になります。
TYPE DUT_XMLWriteByName : STRUCT BoolData:BOOL; RealData:REAL; ArrayInt:ARRAY[0..3]OF INT; stData :DUT_XMLWrite; END_STRUCT END_TYPE |
MAIN
VAR
こちらはImplemenation2で使用したした変数になります。
PROGRAM MAINVAR //Example2 myValue2_XMLWriteByName:DUT_XMLWriteByName; bExecuteXMLWritebyName:BOOL; fbxmlSrvWriteByName:FB_XmlSrvWriteByName; sFilePathWriteByName: T_MaxString:=’C:\Users\threespc02\OneDrive\Desktop\myXML2.xml’; sXPathWriteByName : T_MaxString:=’/dataentry/value2′; sSymName: T_MaxString:=’MAIN.myValue2_XMLWriteByName’;END_VAR |
Program
myValue2_XMLWriteByName.BoolData:=TRUE; myValue2_XMLWriteByName.RealData:=3.14; myValue2_XMLWriteByName.stData.myBool:=TRUE; myValue2_XMLWriteByName.stData.myReal:=10.1234; myValue2_XMLWriteByName.stData.myInt:=5002; FOR iCoutner:=0 TO 41 DO myValue2_XMLWriteByName.stData.myArray[iCoutner]:=iCoutner+1; END_FOR; FOR iCoutner:=0 TO 3 DO myValue2_XMLWriteByName.ArrayInt[iCoutner]:=(iCoutner+1)*20; END_FOR; fbxmlSrvWriteByName( nMode:=XMLSRV_ADDMISSING ,sSymName:=sSymName ,sFilePath:=sFilePathWriteByName ,sXPath:=sXPathWriteByName ,bExecute:=bExecuteXMLWritebyName ); IF bExecuteXMLWritebyName AND (fbxmlSrvWriteByName.bBusy OR fbxmlSrvWriteByName.bError) THEN iCheck:=iCheck+1; bExecuteXMLWritebyName:=FALSE; END_IF; |
Result
bExecuteXMLWritebyNameをTrueにし、Function Blockを実行します。
TwinCAT3 IPC上でmyXML2.xmlが生成されました。
XML Fileにも構造体や配列のデータを書き込みました!
Implementation3
Implemenation3はTwinCAT3で乱数を生成し、その乱数を0.2より小さいであれば、TwinCAT3 Runtimeの時間を取得し、その乱数値と当時の時間をXML Fileに書き込みます。
DUT_XMLLogging
こちらはImplemenation3でXML Fileに書き込む変数の構造体になります。
TYPE DUT_XMLLogging : STRUCT logTime:STRING(50); Value:REAL; END_STRUCT END_TYPE |
MAIN
VAR
こちらはImplemenation3で使用したした変数になります。
PROGRAM MAIN //Example3 MyTimeStruct :TIMESTRUCT; ntGetTime :NT_GetTime; iState :INT; mytimer :TON; sMyLoggingFilePath :T_MaxString:=’C:\Users\threespc02\OneDrive\Desktop\myXMLLogging.xml’; sMyLogginXPath :T_MaxString:=’/dataentry/Logging’; sXPath4 :T_MaxString; myLoggintTime :T_MaxString; rand :DRAND; myLogValue :REAL; myXMLLoggingStructure :DUT_XMLLogging; fbxmlSrvWriteLogging :FB_XmlSrvWrite; bExecute2Log :BOOL; iDataCounter :INT:=0; END_VAR |
Program
CASE iState OF 0: ntGetTime(START:=FALSE); mytimer(IN:=FALSE,PT:=T#1S); rand(); myLogValue:=rand.Num; IF myLogValue<0.2 THEN iState:=10; iCheck:=iCheck+1; ELSE iState:=5; END_IF 5: mytimer(IN:=TRUE); IF mytimer.Q THEN mytimer(IN:=FALSE); iState:=0; END_IF 10: mytimer(IN:=TRUE); IF mytimer.Q THEN mytimer(IN:=FALSE); iState:=20; END_IF 20: ntGetTime(START:=TRUE,TIMESTR=>MyTimeStruct); IF NOT ntGetTime.ERR AND NOT ntGetTime.BUSY THEN iState:=30; END_IF 30: myLoggintTime:=SYSTEMTIME_TO_STRING(MyTimeStruct); iState:=40; 40: sXPath4:=CONCAT(sMyLogginXPath,INT_TO_STRING(iDataCounter)); iState:=50; iDataCounter:=iDataCounter+1; 50: myXMLLoggingStructure.logTime:=myLoggintTime; myXMLLoggingStructure.Value:=myLogValue; bExecute2Log:=TRUE; IF fbxmlSrvWriteLogging.bBusy THEN iState:=60; END_IF IF fbxmlSrvWriteLogging.bError THEN iState:=990; END_IF 60: bExecute2Log:=FALSE; IF NOT fbxmlSrvWriteLogging.bBusy THEN iState:=100; bExecuteXMLWrite:=FALSE; END_IF IF fbxmlSrvWriteLogging.bError THEN iState:=990; END_IF 100: iState:=0; 990: ; END_CASE fbxmlSrvWriteLogging( nMode:=XMLSRV_ADDMISSING ,bExecute:=bExecute2Log ,pSymAddr:=ADR(myXMLLoggingStructure) ,cbSymSize:=SIZEOF(myXMLLoggingStructure) ,sFilePath:=sMyLoggingFilePath ,sXPath:=sXPath4 ); |
Result
iStateが乱数になった現在値によりXML Fileに新たなデータを書き込めるようになります。
TwinCAT3 IPC上でmyXMLLogging.xmlが生成されました。
XML FileにもLogging時間とそのときの乱数値を構造体データとして書き込みました!