0

我正在用另一个人的代码接管一个项目。我有一个 PLC,目前有来自压力传感器和热电偶的输入。然后它将这些数据缩放为 PSI 和华氏温度。从这些传感器中的每一个设置数据的方式将被格式化为一个数组。因此,一旦数据被缩放,它就位于一个数组中,该数组也在程序的网络变量列表中。我试图从数组中获取这些值中的每一个,每隔一定时间记录一次值(为了清楚起见,每秒记录 1 次),然后每秒将每条数据导出到 CSV 文件。甚至不知道该去哪里。这是我留下的代码,但我觉得它似乎不必要地复杂?

//This is the support class for File_Handler
FUNCTION_BLOCK fileWrite
VAR_INPUT
    xWrite : BOOL;
    sData : STRING(200);
    uiLineLength : INT := 200;
    sDirectory : STRING := 'C:\ProgramData\CODESYS\CODESYSHMIWinV3\D5050FE1\PlcLogic\data';
    //sDirectory : STRING := '/home/cds-apps/PlcLogic/data/';
    sFilename : STRING;
END_VAR
VAR_OUTPUT
    BytesWritten : __XWORD;
    BytesWrittenTotal: DWORD;
    xDone: BOOL;
END_VAR
VAR
    hFile_: sysfile.RTS_IEC_HANDLE := sysfile.RTS_INVALID_HANDLE;
    FileWriteResult: sysfile.RTS_IEC_RESULT;
    FileOpenResult: sysfile.RTS_IEC_RESULT;
    state: INT;
    sys_Us_start: SYSTIME;
    sys_Us_end: SYSTIME;
    WriteTimeMS: ULINT;
END_VAR
sFilename := CONCAT(sDirectory, sFilename);
hFile_ := SysFileOpen(szFile:= sFilename, am:= ACCESS_MODE.AM_APPEND_PLUS, pResult:= ADR(FileOpenResult));
SysTimeGetUs(pUsTime:=sys_Us_start );
BytesWritten := SysFileWrite(hFile:= hfile_, pbyBuffer:= ADR(sData), ulSize:= uiLineLength, pResult:= ADR(FileWriteResult));    
BytesWrittenTotal := BytesWrittenTotal + BytesWritten;
SysTimeGetUs(pUsTime:=sys_Us_end );
WriteTimeMS := (sys_Us_end - sys_Us_start)/1000;
SysFileClose(hFile:= hFile_);

我不知道该去哪里使用此代码。它确实创建了一个 CSV 文件,但我希望能够每秒为一段数据创建一个 CSV 文件?如果有人有任何想法或资源,我可以检查一下,那就太好了。

4

1 回答 1

0

如何每秒调用此例程的基本示例如下:

1)

您创建一个 FuncBlock 负责调用您的记录器块。假设您将其称为 LoggerTask

FUNCTION_BLOCK LoggerTask
VAR_INPUT
     sData : STRING(200);
     sFilename : STRING;
     xExecute : BOOL;
END_VAR

VAR
    fbRepeatTask : TON;
    fbFileWrite : FileWrite;
    uiStep : UINT;
END_VAR

2)

之后创建一个简单的步骤链:(您显然可以根据需要扩展和自定义它,例如,当 FileWrite 无法写入文件或写入少于预期的情况下,您应该添加错误处理。)

实现部分:

fbRepeatTask(PT:=T#1S);
fbFileWrite(sData := sData, sFileName := sFileName);

IF  xExecute 
    AND uiStep = 0
THEN
    uiStep := 10;
ELSIF NOT xExecute 
THEN
    uiStep := 0;
    fbFileWrite.xWrite := FALSE;
    fbRepeatTask.IN := FALSE;
END_IF

CASE uiStep OF

    10:

        fbFileWrite.xWrite := TRUE;
        IF fbFileWrite.xDone
        THEN
            fbFileWrite.xWrite := FALSE;
            uiStep := 20;
        END_IF

    20: 

        fbRepeatTask.IN := TRUE;
        IF fbRepeatTask.Q
        THEN
            fbRepeatTask.IN := FALSE;
            uiStep := 10;
        END_IF

END_CASE

3)

正如你所看到的,只要 xExecute 设置为true ,这个块就会被执行。为了重置步骤链,将 xExecute 设置为false。只需循环运行此块,例如这样fbLoggerTask(xExecute := TRUE); 我认为您没有发布 FileWrite 块的所有代码,因为未设置 xDone 并且未在任何地方检查 xWrite。因此,请确保在将字符串写入文件后将 xDone 设置为 true 一个周期(如果尚未实现)。

于 2020-06-10T15:22:55.617 回答