Beckhoff#Tc2_Utilities ライブラリでCSVを読み込む

今回はTc2_Utilitiesのライブラリを使用しCSV Filesを読み込みます。

Function Block

File処理するにはたくさんのFBありますので今回Exampleで使用してるFBだけを紹介します。

FB_FILEOPEN

このFB使用することによってFileを開きすることができます。

VAR_INPUT

sNetId T_AmsNetIdAMSネットワークID
sPathName T_MaxStringアクセスするFileのPath
nMode DWORDどんなModeでFileをアクセスするのか
ePath E_OpenPath PATH_GENERICThe variable of this type selects generic or one of the TwinCAT system paths on the target device to perform the file open operation.
bExecute BOOL立ち上げ=実行
tTimeout   TIME実行取り消すまでの時間

VAR_OUTPUT

bBusy BOOL1=実行中
bError BOOL1=エラーあり
nErrId UDINTエラーID
hFile UINTFile ID

nMode

FOPEN_MODEREAD“r”、Fileを開きます。もしFileが存在しないであればエラーになる。
FOPEN_MODEWRITE“w”、Empty Fileを開きデータ書き込みます。もしFile存在なら内容が破棄する。
FOPEN_MODEAPPEND“a”、FileをOpenし、データをいまのFileの一番最後に書き込む。Fileを事前に作成しておいでください。
FOPEN_MODEREAD OR FOPEN_MODEPLUS“r+”: Fileを読み書きModeで開きます。Fileは事前存在するのが前提条件。
FOPEN_MODEWRITE OR FOPEN_MODEPLUS“w+”: Empty Fileを読み書きModeで開きます。もしFile存在なら内容が破棄する。
FOPEN_MODEAPPEND OR FOPEN_MODEPLUS“a+”: FileをOpenし、データをいまのFileの一番最後に書き込む。Fileが存在しないなら新規作成されます。
FOPEN_MODEBINARY“b”: FileをBinary Modeで開く。
FOPEN_MODETEXT“t”: FileをテキストModeで開く。

Error ID

0x703nMode・ePathが無効
0x70CFileが見つからない
0x716使用可能なFile Handlesがない

FB_FILEGETS

そのFunction使うことによって開いたFileにOne Lineの文字列を読み込むことができます。そのOne Lineは Line Feed 文字までか、Fileの最後か(EOF)、読み込まれた文字数がsLineより多いのか。注意するのはFileは必ずText Modeで開く必要があります。

VAR_INPUT

sNetId T_AmsNetIdAMSネットワークID
hFile UINTFile ID
bExecute BOOL立ち上げ=実行
tTimeout   TIME実行取り消すまでの時間

VAR_OUTPUT

bBusy BOOL1=実行中
bError BOOL1=エラーあり
nErrId UDINTエラーID
sLine  : T_MaxString読み込まれた文字列
bEOFBOOL1=Fileを最後まで読み込まれた(cbRead=0)もしcbRead>0であればTrueになりません。

FB_CSVMemBufferReader

このFBを使用することによって読み込まれた文字列をCSVの間隔文字きりか分けて読むこむことができます。getValueのOutputやpValue/cbValueのOutputから転送先を指定する。

注意点:

CRLF (CR=Carriage Return, LF=Line Feed) を必ず使ってください。

Global変数DEFAULT_CSV_FIELD_SEP.からCSV Fileあkらの間隔文字を設定します。

VAR_INPUT

eCmdE_EnumCmdTypeeEnumCmd_First=Default,1つ目のData Field読み込む。eEnumCmd_Next=次のData Fieldを読み込む。
pBufferDWORD読み込みたいデータのPointer(ADRを使用すればOK)
cbBufferUDINT読み込みたいデータサイズ(SizeOF使用すればOK)

VAR_OUTPUT

bOkBOOL1=実行成功、0=Fault
getValueT_MaxString読み込んでたDataを文字列としての保存先
pValueDWORDDataの保存先のPointer値(ADR使用すればOK)
cbValueUDINTDataの保存先の変数サイズ(SizeOF使用すればOK)
bCRLFBOOL1=最後のデータが読み込まれまれた
cbReadUDINT読み込む成功したデータのサイズ

Library Import

Tc2_Utilitiesを検索しOKで追加します。

Example

Flowは以下になります。

まずプログラム内で使用する変数を初期化しRead Commandを待ち続けます。

Command来たらFileを読み込め、中にの文字列を一列ずつ読み込み、Bufferに転送します。

次はBufferをCSV Fieldことに切り分け、実数に変換し格納します。

もしEOFではなければ、次の列を読みます。

最後はFileをCloseします。


DUT

今回は前RoboGuideからExportされたPointデータをImportします。

まずXYZなどの変数を作成します。

TYPE DUT_Coordinates :
STRUCT
x:REAL;
y:REAL;
z:REAL;
xRot:REAL;
yRot:REAL;
zRot:REAL;
END_STRUCT
END_TYPE


GVL

GVLで余裕を持って101個分のPointデータを作成。

{attribute ‘qualified_only’}
VAR_GLOBAL
Process1:ARRAY[0..100]OF DUT_Coordinates;
END_VAR


Program

VAR

VAR
//Function Blocks
CSVMemBufferReader:FB_CSVMemBufferReader;
FileOpen:FB_FileOpen;
FileGet:FB_FileGets;
FileClose:FB_FileClose;
//
bReset:BOOL;
nCol:INT;
hFile:UINT;
value:STRING[300];
sBufferString:ARRAY[0..15]OF STRING;
iStep: INT;
sCSVLine:STRING;
sPathName:STRING;
nRow:INT;
bRead:BOOL;
bEOF:BOOL;
i:INT;
iCRLFCounter:INT;
END_VAR

VAR CONSTANT

VAR CONSTANT

cStepInit:INT:=0;
cStepOpenFile:INT:=10;
cStepGetLine:INT:=20;
cStepEOFCheck:INT:=25;
cStepReadLine:INT:=30;
cStepParseData:INT:=35;
cStepCloseFile:INT:=40;
cStepError:INT:=8000;
END_VAR

Code

CASE iStep OF

//Init the Configuration and Variables
cStepInit:
//* semicolon (;) := 16#3B => german field separator, comma (,) := 16#2C => US field separator
DEFAULT_CSV_FIELD_SEP:=16#2C;
//Varaibles using in the Program
nRow:=0;
nCol:=0;
iCRLFCounter:=0;
bEOF:=FALSE;
sPathName:=’C:\p2.csv’;
bReset:=FALSE;
//FB Reset
FileOpen(bExecute:=FALSE);
FileClose(bExecute:=FALSE);
FileGet(bExecute:=FALSE);
//Read
IF bRead
AND NOT fileopen.bBusy
AND NOT fileclose.bBusy
AND NOT fileget.bBusy
THEN

FOR i :=0 TO 99 DO
GVL_Points.Process1[i].x:=0.0;
GVL_Points.Process1[i].y:=0.0;
GVL_Points.Process1[i].z:=0.0;
GVL_Points.Process1[i].xRot:=0.0;
GVL_Points.Process1[i].yRot:=0.0;
GVL_Points.Process1[i].zRot:=0.0;

END_FOR
iStep:=cStepOpenFile;
bRead:=FALSE;
END_IF;

cStepOpenFile:
Fileopen(
sNetId:=’192.168.217.145.1.1′
,sPathName:=’C:\p.csv’
,nMode:=FOPEN_MODEREAD
,ttimeout:=T#3S
,ePath:=E_OpenPath.PATH_GENERIC
,bExecute:=TRUE
,hFile=>hfile
);
IF NOT fileopen.bBusy THEN
IF fileopen.bError THEN
iStep:=cStepError;
ELSE
iStep:=cStepGetLine;
END_IF
END_IF

cStepGetLine:
FileGet(
hFile:=hFile
,bExecute:=TRUE
,sLine=>scsvLine
);

IF NOT FileGet.bBusy THEN
IF FileGet.bError THEN
iStep:=cStepError;
ELSE IF FileGet.bEOF THEN
bEOF:=TRUE;
END_IF
(*
IF RIGHT( Fileget.sLine, 1 ) = ‘$N’ THEN
sCSVLine := REPLACE( sCSVLine, ‘$R$L’, 2, LEN( sCSVLine ) );
END_IF
*)
iStep:=cStepEOFCheck;
END_IF
END_IF

cStepEOFCheck:
FileGet(
bExecute:=FALSE
);
IF bEOF THEN
iStep:=cStepCloseFile;
ELSE
iStep:= cStepReadLine;
END_IF

cStepReadLine:
nCol:=0;
CSVMemBufferReader.eCmd:=E_EnumCmdType.eEnumCmd_First;
REPEAT
CSVMemBufferReader(
pBuffer:=ADR(sCSVLine)
,cbBuffer:=SIZEOF(sCSVLine)
,getValue=>value
);

IF CSVMemBufferReader.bOk THEN
sBufferString[ncol]:=value;
CSVMemBufferReader.eCmd:=E_EnumCmdType.eEnumCmd_Next;
ncol:=ncol+1;
IF CSVMemBufferReader.bCRLF THEN
iCRLFCounter:=iCRLFCounter+1;
END_IF
END_IF
UNTIL NOT CSVMemBufferReader.bOk
END_REPEAT
istep:=cStepParseData;

cStepParseData:
//Check EOF
IF FileGet.bEOF THEN
iStep:=cStepCloseFile;
ELSE
GVL_Points.Process1[nRow].x:=STRING_TO_REAL(sBufferString[0]);
GVL_Points.Process1[nRow].y:=STRING_TO_REAL(sBufferString[1]);
GVL_Points.Process1[nRow].z:=STRING_TO_REAL(sBufferString[2]);
GVL_Points.Process1[nRow].xRot:=STRING_TO_REAL(sBufferString[3]);
GVL_Points.Process1[nRow].yRot:=STRING_TO_REAL(sBufferString[4]);
GVL_Points.Process1[nRow].zRot:=STRING_TO_REAL(sBufferString[5]);
nRow:=nRow+1;
iStep:=cStepGetLine;
END_IF

cStepCloseFile:
FileClose(
hFile:=hFile
,bExecute:=TRUE
);
IF NOT FileClose.bBusy THEN
IF FileClose.bError THEN
iStep:=cStepError;
END_IF
ELSE
FileClose(
bExecute:=FALSE
);
iStep:=cStepInit;
END_IF

cStepError:
IF bReset THEN
iStep:=cStepInit;
END_IF
END_CASE

Sample Code Download

https://github.com/soup01Threes/TwinCAT3/blob/main/TwinCAT3%20Project%20CSV%20Read.7z

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

シェアする

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

フォローする