TwinCAT3读取CSV文件

读取CSV文件的用途

在使用TwinCAT3过程中,假如有些参数需要频繁的修改,或者是根据不同的制程要求设置不同的参数,这时候可以把这些参数放到一个CSV文件中,参数修改后,直接让TwinCAT plc重新读取参数就可以了,很方便。

本示例所使用到的功能块

FB_FileOpen, 用来打开CSV文件。
FB_FileGets, 用来取得CSV文件中的一整行数据。
FB_CSVMemBufferReader,更加数据分割符,把一整行数据解析成更小的数据单元。
FB_FileClose,用来关闭上文中打开的CSV文件。

所使用到的CSV文件

文件存放路径:C:\Temp\Demo.csv
CSV文件内容:
这里写图片描述
假定有四个参数Parameter1~Parameter4 需要经常调整,现场技术员不需要到plc程序里边,而只需要修改此CSV参数,然后重新读取数据就可以了。
在此,我把第一行Parameter1~Parameter4称为title行。
把100,110,120,132,成为参数行(Parameters)

具体代码

  1. 变量声明代码块
PROGRAM MAIN
VAR
    (*Huang HanSheng 2017-03-21*)   (* Read CSV file from computer*)
    fbFileClose: FB_FileClose;  
    fbFileGets: FB_FileGets;
    fbFileOpen: FB_FileOpen;
    fbCSVMemBufferReader: FB_CSVMemBufferReader;
    sCSVField,sCSVLine,tmpString: T_maxstring;  
    fileName:STRING := 'C:\Temp\Demo.csv';  //file directory
    lineIdx:INT;        //lineIdx=0-->Title, lineIdx=1-->Parameters
    Steps:eSteps;       // 自己定义的一个枚举变量
    bStart: BOOL;   
    strPara: ARRAY[1..4] OF STRING;  //输出参数数组   
    strTitle: ARRAY[1..4] OF STRING;  //输出参数Title数组
END_VAR

主程序代码段

DEFAULT_CSV_FIELD_SEP:= 16#2C;  //配置CSV文件的分割符,16#2C表明各个参数之间是用逗号分隔的。
IF bStart THEN      //bStart是总的开始变量,把bStart置位true,则程序开始读取数据

CASE Steps OF
    Step_Init:          //读取CSV文件初始步骤
        fbFileOpen(bExecute:=FALSE);
        fbFileClose(bExecute:=FALSE);
        fbFileGets(bExecute:=FALSE);
        lineIdx:= 0;            
        Steps:= Step_OpenFile;


    Step_OpenFile:      //FB_FileOpen 用打开csv文件  
            fbFileOpen(sNetId:='',sPathName:=fileName,nMode:=FOPEN_MODEREAD OR FOPEN_MODETEXT, 
                        ePath:=PATH_GENERIC,bExecute:=TRUE,tTimeout:=T#3S,bBusy=> ,bError=>,nErrId=>,hFile=> );
            IF NOT fbFileOpen.bBusy AND NOT fbFileOpen.bError THEN  //确保打开Demo.csv文件正确无错误的情况下执行下一步          
                Steps:= Step_Getfile;
            END_IF
    Step_Getfile:   //用FB_FileGets取得文件中的一行数据,并把数据存放到sCSVLine变量中
                fbFileGets(sNetId:='',hFile:=fbFileOpen.hFile,bExecute:=TRUE,tTimeout:=T#3S,bBusy=> , 
                            bError=>,nErrId=> ,sLine=>sCSVLine,bEOF=> );
                IF  NOT fbFileGets.bBusy AND NOT fbFileGets.bError THEN
                    (* FB_FileGets中sCSVLine读取到的数据是以一个换行符'$N'结尾的,但是在
                        FB_CSVMemBufferReader功能块中,需要使用回车换行符'$R$N'来作为一行数据结束的分割符,所以此处为读取的
                        数据添加'$R' 符号*)
                    IF RIGHT(STR:= sCSVLine,SIZE:= 1) = '$N' THEN
                        sCSVLine:= REPLACE(STR1:=sCSVLine, STR2:='$r$n',L:=2,P:= LEN(STR:=sCSVLine) );                    
                    END_IF
                    fbFileGets(bExecute:=FALSE);//读取一行完成后,就停止执行FB_FileGets功能块
                    IF lineIdx = 0 THEN         //此处如果lineIdx=0,则读取Title行
                        Steps:=Step_Title;
                    ELSIF lineIdx=1 THEN        此处如果lineIdx=1,则读取参数行
                        Steps:=Step_Para;
                    END_IF
                    lineIdx:= lineIdx+1;

                END_IF

    Step_Title: //读取参数的Title,并用FB_CSVMemBufferReader分解为单个的数据,存入strTitle数组中
                //--------------------read 1st title
                fbCSVMemBufferReader(eCmd:=eEnumCmd_First,pBuffer:=ADR(sCSVLine),cbBuffer:=SIZEOF(sCSVLine)-1, 
                    bOk=> ,getValue=>sCSVField, pValue=> ,cbValue=> ,bCRLF=> ,cbRead=> );
                strTitle[1]:= CSVFIELD_TO_STRING(in:= sCSVField,bQM:= FALSE);
                //--------------------read 2nd title
                fbCSVMemBufferReader(eCmd:=eEnumCmd_Next,pBuffer:=ADR(sCSVLine),cbBuffer:=SIZEOF(sCSVLine)-1, 
                    bOk=> ,getValue=>sCSVField, pValue=> ,cbValue=> ,bCRLF=> ,cbRead=> );
                strTitle[2]:= CSVFIELD_TO_STRING(in:= sCSVField,bQM:= FALSE);
                //--------------------read 3rd title
                fbCSVMemBufferReader(eCmd:=eEnumCmd_Next,pBuffer:=ADR(sCSVLine),cbBuffer:=SIZEOF(sCSVLine)-1, 
                    bOk=> ,getValue=>sCSVField, pValue=> ,cbValue=> ,bCRLF=> ,cbRead=> );
                strTitle[3]:= CSVFIELD_TO_STRING(in:= sCSVField,bQM:= FALSE);
                //--------------------read 4th title
                fbCSVMemBufferReader(eCmd:=eEnumCmd_Next,pBuffer:=ADR(sCSVLine),cbBuffer:=SIZEOF(sCSVLine)-1, 
                    bOk=> ,getValue=>sCSVField, pValue=> ,cbValue=> ,bCRLF=> ,cbRead=> );
                strTitle[4]:= CSVFIELD_TO_STRING(in:= sCSVField,bQM:= FALSE);
                // 让Step 重回到Step_Getfile,准备读取参数行
                Steps:= Step_Getfile;
    Step_Para: //读取参数行,并用FB_CSVMemBufferReader分解为单个的数据,存入strPara中
                fbCSVMemBufferReader(eCmd:=eEnumCmd_First,pBuffer:=ADR(sCSVLine),cbBuffer:=SIZEOF(sCSVLine)-1, 
                    bOk=> ,getValue=>sCSVField, pValue=> ,cbValue=> ,bCRLF=> ,cbRead=> );
                strPara[1]:= CSVFIELD_TO_STRING(in:= sCSVField,bQM:= FALSE);
                //--------------------read 2nd parameter
                fbCSVMemBufferReader(eCmd:=eEnumCmd_Next,pBuffer:=ADR(sCSVLine),cbBuffer:=SIZEOF(sCSVLine)-1, 
                    bOk=> ,getValue=>sCSVField, pValue=> ,cbValue=> ,bCRLF=> ,cbRead=> );
                strPara[2]:= CSVFIELD_TO_STRING(in:= sCSVField,bQM:= FALSE);
                //--------------------read 3rd parameter
                fbCSVMemBufferReader(eCmd:=eEnumCmd_Next,pBuffer:=ADR(sCSVLine),cbBuffer:=SIZEOF(sCSVLine)-1, 
                    bOk=> ,getValue=>sCSVField, pValue=> ,cbValue=> ,bCRLF=> ,cbRead=> );
                strPara[3]:= CSVFIELD_TO_STRING(in:= sCSVField,bQM:= FALSE);
                                //--------------------read 4th parameter
                fbCSVMemBufferReader(eCmd:=eEnumCmd_Next,pBuffer:=ADR(sCSVLine),cbBuffer:=SIZEOF(sCSVLine)-1, 
                    bOk=> ,getValue=>sCSVField, pValue=> ,cbValue=> ,bCRLF=> ,cbRead=> );
                strPara[4]:= CSVFIELD_TO_STRING(in:= sCSVField,bQM:= FALSE);
                // the steps go to Step_Close
                Steps:= Step_Close;
    Step_Close: //关闭打开的Demo.csv文件
                fbFileClose(sNetId:='',hFile:=fbFileOpen.hFile,bExecute:=TRUE,tTimeout:=T#3S,bBusy=> , 
                                bError=> ,  nErrId=> );

                (*Huang HanSheng 2017-03-21*)   (* Read CSV file from computer*)                
END_CASE

END_IF

Step的定义方法和具体代码:

TYPE eSteps :
(
    Step_Init := 0,
    Step_OpenFile:=10,
    Step_Getfile:=20,
    Step_Title:= 30,
    Step_Para:= 35,
    Step_Close:= 40,
    Step_Last:= 100
);
END_TYPE

TwinCAT3自带的Visualization功能检查程序

当点击bStart按钮后,就会下边的6个显示框会分别显示读取到的结果。
TwinCAT3读取CSV文件_第1张图片

你可能感兴趣的:(TwinCAT3功能)