I have created a plc program in TwinCat and its saving data into csv file. But variable values are not updating. Only one value is repeating in csv file again and and again. Where I am doing wrong !!! Here is my code:
PROGRAM MAIN
VAR
// Open, close and write function block
fbFileOpen: FB_FileOpen;
fbFileClose: FB_FileClose;
fbFileWrite: FB_FileWrite;
fbFormatString2: FB_FormatString2;
fbGetTime: NT_GetTime;
//file variables
nState : INT := 0;
nCounter : LREAL :=0;
hFile: UINT;
sPathName : T_MaxString;
sWriteBuffer : STRING(5000);
sBufferTemp : STRING(1000);
bBufferTemp : BOOL;
sFormat : STRING(255);
//General Variables
bFill: BOOL;
bWrite: BOOL;
rTimestamp : LREAL;
rCurrent: LREAL;
rActPos: LREAL;
nTimeMilli: INT;
i: ULINT;
END_VAR
// Input values
//------------------------------------------------------------------------------------------------------------------------
rTimestamp:= ULINT_TO_LREAL(F_GetSystemTime());
nCounter:= nCounter+1;
rCurrent:= (nCounter+1)/100;
rActPos:= (nCounter+1)/200;
IF bFill THEN
FOR i :=0 TO 10000000 BY 1 DO
GVL.arrLog[i].rTimestamp := rTimestamp;
GVL.arrLog[i].rCurrent := rCurrent;
GVL.arrLog[i].rActPos := rActPos;
END_FOR
END_IF
// Function Block for Current Date and Time
//------------------------------------------------------------------------------------------------------------------------
IF fbGetTime.START AND NOT fbGetTime.BUSY THEN // simple flip flop for quick update of time
fbGetTime.START := FALSE;
ELSE
fbGetTime.START := TRUE;
END_IF
fbGetTime(
NETID:= ,
START:= ,
TMOUT:= ,
BUSY=> ,
ERR=> ,
ERRID=> ,
TIMESTR=> ); // The TIMESTR is used to get times and dates
//Case Statements that will handle sequence of writing
//------------------------------------------------------------------------------------------------------------------------
CASE nState OF
0: //Wait for write trigger
IF bWrite THEN
nState := 10;
bWrite := FALSE;
END_IF
10: //Create file path and file using date
sPathName := CONCAT('D:\Data\', WORD_TO_STRING(fbGetTime.TIMESTR.wYear));
sPathName := CONCAT(sPathName,'_');
sPathName := CONCAT(sPathName,WORD_TO_STRING(fbGetTime.TIMESTR.wMonth));
sPathName := CONCAT(sPathName,'_');
sPathName := CONCAT(sPathName,WORD_TO_STRING(fbGetTime.TIMESTR.wDay));
sPathName := CONCAT(sPathName,'_');
sPathName := CONCAT(sPathName,WORD_TO_STRING(fbGetTime.TIMESTR.wHour));
sPathName := CONCAT(sPathName,'_');
sPathName := CONCAT(sPathName,WORD_TO_STRING(fbGetTime.TIMESTR.wMinute));
sPathName := CONCAT(sPathName,'_Datalog.csv');
nState:= 20;
fbFileOpen.bExecute := TRUE;
20: //Open and wait for file to open
fbFileOpen.bExecute := TRUE;
IF NOT fbFileOpen.bBusy AND NOT fbFileOpen.bError THEN
fbFileOpen.bExecute := FALSE;
nState := 30;
END_IF
30: // Write contents in file
sWriteBuffer := 'Name, fCurrentScaled, fActPos $n';
sFormat := '%F, %F, %F $n';
nTimeMilli := WORD_TO_INT(fbGetTime.TIMESTR.wMilliseconds);
IF WORD_TO_STRING(fbGetTime.TIMESTR.wMinute) <> INT_TO_STRING(40) THEN
FOR nTimeMilli:= 0 TO 999 BY 1 DO
fbFormatString2(
pFormatString:= ADR(sFormat),
arg1:= F_LREAL(GVL.arrLog[i].rTimestamp),
arg2:= F_LREAL(GVL.arrLog[i].rCurrent),
arg3:= F_LREAL(GVL.arrLog[i].rActPos),
pDstString:= ADR(sWriteBuffer),
nDstSize:= SIZEOF(sWriteBuffer),
bError=> ,
nErrId=> );
bBufferTemp := CONCAT2(pSrcString1 := ADR(sWriteBuffer),
pSrcString2 := ADR(sBufferTemp),
pDstString:= ADR(sWriteBuffer),
nDstSize := SIZEOF(sWriteBuffer));
END_FOR
ELSE
nState := 40;
fbFileWrite.bExecute := TRUE;
END_IF
40: // Write data in file and Wait for writing in the file
fbFileWrite.bExecute := TRUE;
IF NOT fbFileWrite.bBusy AND NOT fbFileWrite.bError THEN
fbFileWrite.bExecute := FALSE;
nState := 50;
fbFileClose.bExecute := TRUE;
END_IF
50: // close file and wait for it to close
fbFileClose.bExecute := TRUE;
IF NOT fbFileClose.bBusy AND NOT fbFileClose.bError THEN
fbFileClose.bExecute := FALSE;
nState:= 0;
END_IF
END_CASE
// FunctionBlocks for OPEN, WRITE and CLOSE
//------------------------------------------------------------------------------------------------------------------------
fbFileOpen(
sNetId:= '', //The netID does not need to be specified for local system
sPathName:= sPathName,
nMode:= FOPEN_MODEAPPEND OR FOPEN_MODEPLUS, // Open empty file for both read and write. If file exists then its content are destroyed
ePath:= PATH_GENERIC,
bExecute:= ,
tTimeout:= ,
bBusy=> ,
bError=> ,
nErrId=> ,
hFile=> hFile); // This file handle will be same for all function blocks.
fbFileClose(
sNetId:= '',
hFile:= hFile,
bExecute:= ,
tTimeout:= ,
bBusy=> ,
bError=> ,
nErrId=> );
fbFileWrite(
sNetId:= '',
hFile:= hFile,
pWriteBuff:= ADR(sWriteBuffer), // A pointer is used to get address
cbWriteLen:= SIZEOF(sWriteBuffer), // Needs to know to size of string going to be written
bExecute:= ,
tTimeout:= ,
bBusy=> ,
bError=> ,
nErrId=> ,
cbWrite=> );
I have created a counter and divided into smaller portion so that I get several values for one second. Is there update syntax I am missing?