You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求TwinCAT中Beckhoff PLC数据导出为Excel/CSV的可用示例代码

Beckhoff PLC作业数据CSV记录实现需求

需要将Beckhoff PLC控制的模拟器中JobNo、Processing Time、JobID、Process Number等数据记录为CSV/Excel文件,要求每个作业对应一行数据,示例格式如下:

JobnoProcessTimeJobIDProcessNo
120100200
240101320

已参考Beckhoff官方资料、联系技术支持,但现有代码运行出错;论坛解决方案过于复杂。现提供当前使用的DUT、GVL及MAIN程序代码,恳请提供可直接使用的文件写入示例程序。


现有DUT定义(ST_data)

TYPE ST_data :
STRUCT
    JOB_ID          : STRING(255);
    Processing_Time : STRING(255);
    Setup_Time      : STRING(255);
    Due_Date        : STRING(255);
END_STRUCT
END_TYPE

现有全局变量列表(GVL)

{attribute 'qualified_only'}
VAR_GLOBAL
    MACHINE : ARRAY[1..50] OF ST_data;
    sen5 : BOOL;
    sen2 : BOOL;
    state : BOOL;
    count :INT;
    hit: BOOL;
    tdelta : ULINT;
    tstart : ULINT;
    tend : ULINT;
    setuptime : LREAL;
END_VAR

现有MAIN程序变量定义

PROGRAM MAIN
VAR

    FB_FileOpen: FB_FileOpen;
    FB_FileWrite: FB_FileWrite;
    FB_FileClose: FB_FileClose;
    
    hFile: UINT;
    sPathName: T_MaxString;
    sWriteBuffer : STRING(5000);
    sBufferTemp : STRING(1000); // Temporary string that will hold the string that needs to be added to the full string
    bBuffTemp : BOOL ; //check if the strings have been concatinated
    sFormat : STRING(255);
    
    state: INT;
    bWrite: BOOL;
    NT_GetTime: NT_GetTime;
    
    bFill: BOOL;
    i: INT;
    FB_FormatString2: FB_FormatString2;
    
    trigger: BOOL;
END_VAR

现有MAIN程序逻辑代码

//counter code
//==========================================================================================
IF GVL.sen5 = FALSE AND GVL.hit = FALSE THEN
    GVL.count := GVL.count +1;
    GVL.hit := TRUE;
ELSIF GVL.sen5 = TRUE AND GVL.hit = TRUE THEN
    GVL.hit := FALSE;
END_IF

IF gvl.sen5= TRUE THEN
    GVL.tstart := F_GetSystemTime();
END_IF
IF GVL.sen2 = TRUE THEN
    GVL.tend := F_GetsystemTime();
    //trigger := TRUE; // this will trigger the file writing commands
END_IF
GVL.tdelta := GVL.tend - GVL.tstart;
GVL.setuptime := GVL.tdelta*EXPT(10,-7);
//Entering some value in array
//==========================================================================================
IF bFill THEN
    FOR i := 1 TO 50 BY 1 DO
        GVL.MACHINE[i].Due_Date :='10823'; //WORD_TO_STRING(NT_GetTime.TIMESTR.wDayOfWeek);
        GVL.MACHINE[i].JOB_ID := INT_TO_STRING(GVL.count) ;//INT_TO_STRING(i);
        GVL.MACHINE[i].Processing_Time := '125';//WORD_TO_STRING(NT_GetTime.TIMESTR.wMinute);
        GVL.MACHINE[i].Setup_Time := LREAL_TO_STRING(GVL.setuptime);//WORD_TO_STRING(NT_GetTime.TIMESTR.wSecond);
    END_FOR
    bFill := FALSE;
END_IF


//Functioin block to get local time
//===========================================
IF NT_GetTime.start AND NOT NT_GetTime.BUSY THEN
    NT_GetTime.START :=FALSE;
ELSE
    NT_GetTime.START := TRUE;
END_IF
NT_GetTime(
    NETID:='' , 
    START:= , 
    TMOUT:= , 
    BUSY=> , 
    ERR=> , 
    ERRID=> , 
    TIMESTR=> );
//CASE STATEMENT to handle writing
//===========================================
CASE state OF
    0:
        IF bWrite THEN // switch to true or false to control the execution
            State :=5;
            bWrite := FALSE;
        END_IF
    5:// creating the file 
        sPathName := CONCAT('C:\Users\Manjot Sanghera\Desktop\CSVRECORD',WORD_TO_STRING(NT_GetTime.TIMESTR.wDay));
        sPathName := CONCAT(sPathName,'.');
        sPathName := CONCAT(sPathName,WORD_TO_STRING(NT_GetTime.TIMESTR.wHour));
        //sPathName := CONCAT(sPathName,'.');
        //sPathName := CONCAT(sPathName,WORD_TO_STRING(NT_GetTime.TIMESTR.wMinute));
        sPathName := CONCAT(sPathName,'_TestFile.csv');
        State := 10;
        FB_FileOpen.bExecute := TRUE;
        
    10:
        FB_FileOpen.bExecute := TRUE;
        IF NOT FB_FileOpen.bBusy AND NOT FB_FileOpen.bError THEN
            FB_FileOpen.bExecute := FALSE;
            State := 15;
        END_IF
    15 :
        sWriteBuffer :='Due_Date, Job_ID, Processin_Time,Setup_Time $n';
        sFormat :='%s, %s, %s, %s $n';
        FOR i := 1 TO 50 BY 1 DO // loop is required so that you can loop through each line/row/arrayelement
            FB_FormatString2(
                pFormatString:=  ADR(sFormat), 
                arg1:= F_STRING(GVL.MACHINE[i].Due_Date), 
                arg2:= F_STRING(GVL.MACHINE[i].JOB_ID), 
                arg3:= F_STRING(GVL.MACHINE[i].Processing_Time), 
                arg4:= F_STRING(GVL.MACHINE[i].Setup_Time),  
                pDstString:= ADR(sBufferTemp) , 
                nDstSize:= SIZEOF(sBufferTemp), 
                bError=> , 
                nErrId=> );
            bBuffTemp := CONCAT2(   pSrcString1 := ADR(sWriteBuffer),//main string 
                                    pSrcString2 := ADR(sBufferTemp), //String to be added
                                    pDstString  := ADR(sWriteBuffer),//destinatioin of the string
                                    nDstSize := SIZEOF(sWriteBuffer));//size of the final string
        END_FOR
        //sWriteBuffer := 'Job_ID__|__Processing_Time__|__SetupTime';
        State := 20;
        FB_FileWrite.bExecute := TRUE;
    20:
        FB_FileWrite.bExecute := TRUE;
        IF NOT FB_FileWrite.bBusy AND NOT FB_FileWrite.bError THEN
            FB_FileWrite.bExecute := FALSE;
            State := 30;
            FB_FileClose.bExecute := TRUE;
        END_IF
    30:
        IF NOT FB_FileClose.bBusy AND NOT FB_FileClose.bError THEN
            FB_FileClose.bExecute := FALSE;
            State:= 0;
        END_IF      
END_CASE

//OPEN, WRITE, CLOSE FILE
//===========================================
FB_FileOpen(
    sNetId:= '', 
    sPathName:= sPathName , 
    nMode:= FOPEN_MODEWRITE OR FOPEN_MODEPLUS, 
    ePath:= PATH_GENERIC, 
    bExecute:= , 
    tTimeout:= , 
    bBusy=> , 
    bError=> , 
    nErrId=> , 
    hFile=> hFile);
    
FB_FileWrite(
    sNetId:= '', 
    hFile:= hFile, 
    pWriteBuff:= ADR(sWriteBuffer) , 
    cbWriteLen:= SIZEOF(sWriteBuffer), 
    bExecute:= , 
    tTimeout:= , 
    bBusy=> , 
    bError=> , 
    nErrId=> , 
    cbWrite=> );
    
FB_FileClose(
    sNetId:= '', 
    hFile:= hFile  , 
    bExecute:= , 
    tTimeout:= , 
    bBusy=> , 
    bError=> , 
    nErrId=> );

预期功能

计数器统计作业数量,完成一个作业后将对应数据写入CSV文件的一行;第二个作业数据就绪后,继续写入下一行。

内容的提问来源于stack exchange,提问作者manjot sanghera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:08:12