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

如何在TwinCAT3中导入6000×2矩阵Excel数据并以数组使用?

我之前做项目时刚好处理过类似的需求,给你整理了两个简单易上手的方案,直接就能套用,不用纠结复杂的文档:

方案一:Excel转ST初始化代码(一次性导入,最省心)

这个方法适合不需要频繁更新数据的场景,直接把Excel数据转成TwinCAT能识别的ST代码,导入后就是静态数组,运行时不用额外读取文件。

步骤1:用Excel生成ST赋值语句

打开你的6000×2矩阵(A列时间,B列函数值,从A1到B6000):

  • 在C1单元格输入公式:
    ="DataArray["&ROW()-1&"] := (Time:="&A1&", FunctionValue:="&B1&");
    
  • 下拉填充C列到第6000行,这样每一行都会自动生成对应的ST赋值语句(比如第1行对应DataArray[0] := (Time:=0.0, FunctionValue:=1.23);)

步骤2:在TwinCAT里配置数组和初始化程序

  1. 新建全局变量列表,定义存储数据的数组:
    VAR_GLOBAL
        // 定义6000个元素的结构体数组,对应你的矩阵
        DataArray: ARRAY[0..5999] OF STRUCT
            Time: LREAL;  // 用LREAL保证时间精度,需求低也可以用REAL
            FunctionValue: LREAL;
        END_STRUCT;
    END_VAR
    
  2. 新建一个初始化程序块(比如命名为PRG_InitData),把Excel生成的所有C列语句粘贴进去:
    METHOD PRG_InitData
    VAR
    END_VAR
    
    // 粘贴从Excel生成的赋值语句
    DataArray[0] := (Time:=0.0, FunctionValue:=1.23);
    DataArray[1] := (Time:=0.1, FunctionValue:=1.25);
    // ... 剩下的5998行语句
    
  3. 在主程序MAIN里添加触发逻辑,确保初始化只执行一次:
    PROGRAM MAIN
    VAR
        bInitDone: BOOL := FALSE;
        rTrigInit: R_TRIG;  // 上升沿触发器
    END_VAR
    
    rTrigInit(CLK := NOT bInitDone);
    IF rTrigInit.Q THEN
        PRG_InitData();  // 执行初始化
        bInitDone := TRUE;  // 标记已完成,防止重复执行
    END_IF;
    

使用数据

下载程序到PLC后,初始化完成,你可以直接通过索引访问数组里的数据:

// 比如读取第100个数据的时间和函数值
sCurrentTime := DataArray[99].Time;
sCurrentValue := DataArray[99].FunctionValue;
方案二:ST读取CSV文件(支持动态更新数据)

如果需要经常替换数据,不用修改程序,这个方案更合适——把Excel存成CSV文件,用ST代码逐行读取到数组里。

步骤1:Excel转CSV文件

打开你的矩阵文件,选择「另存为」→ 格式选逗号分隔值(.csv),保存到PLC能访问的路径:

  • 本地运行TwinCAT:直接存到本地文件夹(比如C:\TwinCAT_Data\MyData.csv)
  • 远程PLC:把文件放到PLC的SD卡,路径用SD:\MyData.csv

步骤2:在TwinCAT里编写读取逻辑

  1. 定义全局变量:
    VAR_GLOBAL
        DataArray: ARRAY[0..5999] OF STRUCT
            Time: LREAL;
            FunctionValue: LREAL;
        END_STRUCT;
        hFile: RTS_IEC_HANDLE;  // 文件句柄
        sLine: STRING(50);      // 存储读取的每行内容
        iIndex: INT := 0;       // 数组索引计数器
        bReadDone: BOOL := FALSE;  // 读取完成标记
    END_VAR
    
  2. 新建读取程序块(比如PRG_LoadCSV):
    METHOD PRG_LoadCSV
    VAR
        sTimeStr: STRING(20);   // 存储分割后的时间字符串
        sValueStr: STRING(20);  // 存储分割后的函数值字符串
        iCommaPos: INT;         // 逗号位置索引
    END_VAR
    
    // 第一次执行时打开文件
    IF iIndex = 0 AND NOT bReadDone THEN
        hFile := FileOpen('C:\TwinCAT_Data\MyData.csv', FILE_MODE_READ, FILE_ACCESS_READ, FILE_SHARE_READ, FILE_OPEN_EXISTING);
        IF hFile = 0 THEN
            // 文件打开失败,可添加报错逻辑(比如触发报警)
            RETURN;
        END_IF;
    END_IF;
    
    // 逐行读取,直到数组填满或文件读完
    WHILE iIndex < 6000 AND FileReadLine(hFile, sLine) > 0 DO
        // 分割逗号分隔的字符串
        iCommaPos := FIND(sLine, ',');
        IF iCommaPos > 0 THEN
            sTimeStr := LEFT(sLine, iCommaPos-1);
            sValueStr := RIGHT(sLine, LEN(sLine)-iCommaPos);
            // 字符串转LREAL赋值给数组
            DataArray[iIndex].Time := STR_TO_LREAL(sTimeStr);
            DataArray[iIndex].FunctionValue := STR_TO_LREAL(sValueStr);
            iIndex := iIndex + 1;
        END_IF;
    END_WHILE;
    
    // 读取完成后关闭文件
    IF iIndex >= 6000 OR FileEOF(hFile) THEN
        FileClose(hFile);
        bReadDone := TRUE;
    END_IF;
    
  3. 在MAIN里触发读取:
    PROGRAM MAIN
    VAR
        bLoadDone: BOOL := FALSE;
        rTrigLoad: R_TRIG;
    END_VAR
    
    rTrigLoad(CLK := NOT bLoadDone);
    IF rTrigLoad.Q THEN
        PRG_LoadCSV();
        bLoadDone := TRUE;
    END_IF;
    
注意事项
  • 数组索引:我用的是0..5999对应6000个元素,和你的矩阵行数匹配,Excel公式里的ROW()-1刚好生成从0开始的索引,不用调整。
  • 数据类型:如果你的时间/函数值是整数,也可以把LREAL改成DINT或INT,节省内存。
  • 方案一的程序会因为6000行赋值语句变大,但TwinCAT完全能处理,而且运行时数据直接在内存里,访问速度最快。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:14:35