codesys读取csv文件-CODESYS资源下载区-酷德网 - CoDeSys软件教程下载,CoDeSys工控资讯门户 

酷德网

HSC6490-cn中国制造,中国芯~
查看: 1113|回复: 0

codesys读取csv文件

[复制链接]
  • TA的每日心情
    开心
    2017-11-20 22:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2024-8-9 23:39:07 | 显示全部楼层 |阅读模式
    最近在项目遇到了需求:要求能够以可编辑文件的方式保存两百个运动和点位到位延迟时间,然后运动控制通过读取文件的方式将点位读出来。一个点位一个点位的执行,文件保存方式最好为Excel表格方式。查询了相关资料以后,发现Codesys是支持csv文件读写的,而恰好Excel也可以打开csv文件。于是,我开始了:本次测试环境基于3.5.12开发环境

    1、首先,你需要引入一些库,用于读写文件流

    29004529_66560a29495c665040.jpg

    2、其次,你需要指定你要读到数据格式,例如我要读X,Y,Z1,Z2,Z3,U1,U2,WaitTime。一行需要有这些数据,每个数据用逗号隔开。同时在首位添加1位占位标志。用来区分数据的开头和结尾。示例:1,101,301,1,2,3,4,5,1001$R$N(这个就是你会读到的数据)

    3、特别解释,$R$N是写进去时候的换行符。没有这个无法实现在Excel中的换行

    4、读文件源码:
    ----------------------------变量声明区域------------------
    [AppleScript] 纯文本查看 复制代码
    FUNCTION ReadFileToBuffer : BOOL
     VAR_INPUT
         strIniPath              :STRING;
         pBuffer                    :POINTER TO ARRAY[1..GVL.Cnst_MaxFileLine] OF STRING;
     END_VAR
     VAR
         hFile            :DWORD;
         dwFileSize        :DINT;
         strLine            :STRING;
         iLnCnt           :INT:=1;
         iFileLine        :INT;
         dwRead            :DWORD;
         STR                :STRING;(*读到的字符串*)
         iEndPos            :INT;
         dwFileCurPos    :DINT;(*当前文件光标位置*)
     END_VAR


    ----------------------------运行代码区域------------------

    [AppleScript] 纯文本查看 复制代码
    hFile     :=SysFileOpen(FileName:=strIniPath,Mode:='r');
     dwFileCurPos:=0;
     IF (hFile =0) THEN
         ReadFileToBuffer:=FALSE;
            SysFileClose(hFile);
         RETURN;
     END_IFdwFileSize:=SysFileGetSize(FileName:=strIniPath);
     IF (dwFileSize=0)  THEN
         ReadFileToBuffer:=FALSE;
            SysFileClose(hFile);
         RETURN;
     END_IFWHILE(TRUE) DO
           IF  (*(NOT SysFileEOF(hFile)) OR*) dwFileCurPos<dwFileSize   THEN
             dwRead:=SysFileRead(File:=hFile,Buffer :=ADR(STR),60);
             iEndPos:=FIND(STR1:=STR,STR2:='$N');
             dwFileCurPos:=dwFileCurPos+iEndPos;
             SysFileSetPos(hFile,dwFileCurPos);
                  pBuffer^[iLnCnt]:=LEFT(STR,iEndPos);
             iLnCnt:=iLnCnt+1;
         ELSE
             SysFileClose(hFile);
             EXIT;
         END_IF
     END_WHILE
     ReadFileToBuffer:=TRUE;


    此部分代码会执行一个过程,将按行数文件内容全部读取到一个指定到的字符串,每一行为一个字符串。

    5、因此,我们还需要通过一个方法来分解字符串来取数据

    ----------------------------变量声明区域------------------

    [AppleScript] 纯文本查看 复制代码
    FUNCTION_BLOCK GetPointData
     VAR_INPUT
         BuffStr:STRING;
     END_VAR
     VAR_OUTPUT
         OutDutData:DUT_XYZ_WaitTime;
     END_VAR
     VAR
         str1:STRING :='1,101,301,1,2,3,4,5,1001$R$N';     ///测试数据
         iStartPoint:INT;
         iEndPoint:INT;
         p,j:INT;
         listPoint:ARRAY [1..8] OF INT; //记录逗号位置
     END_VAR


    ----------------------------运行代码区域------------------

    [AppleScript] 纯文本查看 复制代码
    iStartPoint:=FIND(BuffStr,'1');  //获取起始位置
     iEndPoint:=FIND(BuffStr,'$R');  //获取数据结束位置
     //从字符位置1开始循环到数据结束位置,通过MID方法获得每一个逗号位置,并记录到数组中。
     j:=1;
     FOR p:=1 TO iEndPoint DO
         IF','=MID(BuffStr,1,p)THEN
         listPoint[j]:=p;
         j:=j+1;
         END_IF
         IF j>8 THEN
             EXIT;
         END_IF
     END_FOR
     //按照逗号位置取当前逗号到上一个逗号之间的字符串,转换为长实数类型数据
     OutDutData.X:=STRING_TO_LREAL( MID(BuffStr,(listPoint[2]-listPoint[1]-1),listPoint[1]+1));
     OutDutData.Y:=STRING_TO_LREAL( MID(BuffStr,(listPoint[3]-listPoint[2]-1),listPoint[2]+1));
     OutDutData.Z1:=STRING_TO_LREAL( MID(BuffStr,(listPoint[4]-listPoint[3]-1),listPoint[3]+1));
     OutDutData.Z2:=STRING_TO_LREAL( MID(BuffStr,(listPoint[5]-listPoint[4]-1),listPoint[4]+1));
     OutDutData.Z3:=STRING_TO_LREAL( MID(BuffStr,(listPoint[6]-listPoint[5]-1),listPoint[5]+1));
     OutDutData.U1:=STRING_TO_LREAL( MID(BuffStr,(listPoint[7]-listPoint[6]-1),listPoint[6]+1));
     OutDutData.U2:=STRING_TO_LREAL( MID(BuffStr,(listPoint[8]-listPoint[7]-1),listPoint[7]+1));
     //最后一个没有逗号,但是有换行标志,所以取换行标志到上一个逗号之前的数据,同理转化
     OutDutData.WaitTime:=STRING_TO_INT( MID(BuffStr,(iEndPoint-listPoint[8]-1),listPoint[8]+1));


    6、通过步骤5的方法。我们可以传一个字符串,从而得到一个我们协议好的数据集合

    这样我们在主程序中,这样调用,即可得到想要的值了

    [AppleScript] 纯文本查看 复制代码
    Cnst_MaxFileLine                :INT:=1000;(*文件的最大行数*)
    IF ReadFileToBuffer(strFilePath,ADR(Buffer))THEN
             FOR i:=1 TO GVL.Cnst_MaxFileLine DO 
                 fb_GetData(BuffStr:=Buffer[i],OutDutData=>PointData[i]);
             END_FOR
             iIndex:=1;
         END_IF


    对了,别忘了定义你的数据结构体:

    [AppleScript] 纯文本查看 复制代码
    TYPE DUT_XYZ_WaitTime :
     STRUCT
         X:LREAL;
         Y:LREAL;
         Z1:LREAL;
         Z2:LREAL;
         Z3:LREAL;
         U1:LREAL;
         U2:LREAL;
         WaitTime:INT;
     END_STRUCT
     END_TYPE


    好了。就是这样,程序中使用就调用OutDutData数组下的相应点位即可,给相应的XY运动点位赋值,即可达成想要的效果。

    +10
    不赞一个?
    打赏鼓励一下!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

    本版积分规则

    
    顶部qrcode底部
    关注酷德网订阅号,获取更多资讯!

    QQ|Archiver|手机版|小黑屋|酷德论坛 ( 苏ICP备16065247号-1 )|网站地图

    GMT+8, 2026-11-10 20:52 , Processed in 0.162479 second(s), 50 queries .

    酷德网

    © 2001-2013 Hicodesys. 技术支持 by 酷德网

    快速回复 返回顶部 返回列表