I have to record data like JobNo, processing time, JobID, process Number from a simulator governed by Beckhoff PLC and write this data in a form of CSV or excel file. for example if JobNo is 1 then after processing the all the data should be recorded under corresponding columns and when next job is encountered the data is recorded in next row. Following should be how the excel file should look like
Jobno | ProcessTime | JobID | ProcessNo |
---|---|---|---|
1 | 20 | 100 | 200 |
2 | 40 | 101 | 320 |
Till now I have followed online resources by Beckhoff and even contacted their support team, but the codes I got from them results in some sort of error. I also wrote my problems in some forums but the answers I got there were too complex and advanced. It would be helpful if you could provide a sample of file writing program Here are all the DUTs and GVLs and MAIN code I used for this purpose : DUT named 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 named 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 code Local Variables------------------------------------------------
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
code-----------------------------------------------------------------
//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=> );
EXPECTED FUNCTION OF PROGRAM counter counts the object and fills the values of JobID, Process No, and other values in the first row of the table and works only after these values for the second job are available