CASE step OF
0: (* Wait for rising edge at bRead variable *)
IF bRead THEN
bRead := FALSE;
bBusy := TRUE;
bError := FALSE;
nErrId := 0;
hFile := 0;
nRow := 0;
nColumn := 0;
MEMSET( ADR( database ), 0, SIZEOF( database ) );
step := 1;
END_IF
1: (* Open source file *)
fbFileOpen( bExecute := FALSE );
fbFileOpen( sNetId := sNetId, sPathName := sFileName, nMode := FOPEN_MODEREAD OR FOPEN_MODETEXT,(* Open file in TEXT mode! *)
ePath := PATH_GENERIC, bExecute := TRUE );
step := 2;
2:(* Wait until open not busy *)
fbFileOpen( bExecute := FALSE, bError => bError, nErrID => nErrID, hFile => hFile );
IF NOT fbFileOpen.bBusy THEN
IF NOT fbFileOpen.bError THEN
step := 3;
ELSE(* Error: file not found? *)
step := 100;
END_IF
END_IF
3: (* Read single line (record) *)
fbFileGets( bExecute := FALSE );
fbFileGets( sNetId := sNetId, hFile := hFile, bExecute := TRUE );
step := 4;
4:(* Wait until read not busy *)
fbFileGets( bExecute := FALSE, bError => bError, nErrID => nErrID, sLine => sCSVLine );
IF NOT fbFileGets.bBusy THEN
IF NOT fbFileGets.bError THEN
IF fbFileGets.bEOF THEN
step := 10;(* End of file reached => Close source file *)
ELSE
(* F B_FileGets returns text line without the CR (carriage return) character.
We have to restore the CR character (replace the $L character with $R$L characters) *)
IF RIGHT( sCSVLine, 1 ) = '$L' THEN
sCSVLine := REPLACE( sCSVLine, '$R$L', 2, LEN( sCSVLine ) );
END_IF
step := 5;
END_IF
ELSE(* Error *)
step := 100;
END_IF
END_IF
5:(* Parse single line (record) *)
fbReader.eCmd := eEnumCmd_First;(* Read first field value *)
REPEAT
fbReader( pBuffer := ADR( sCSVLine ), cbBuffer := SIZEOF( sCSVLine ), getValue => sCSVField );
IF fbReader.bOk THEN
fbReader.eCmd := eEnumCmd_Next;(* Read next field value *)
IF ( nRow <= MAX_CSV_ROWS ) THEN
IF ( nColumn <= MAX_CSV_COLUMNS ) THEN
database[nRow, nColumn] := CSVFIELD_TO_STRING( sCSVField, FALSE );(* TODO: Save or use the field value in your application *)
GvAllg.sPrgNummer := (database[0, 0]); // Programmnummer
GvPara.iRezeptPG := STRING_TO_INT (database[0, 1]); // PH-Glas Rezeptur
GvPara.aiTempGlas[GvPara.iRezeptPG] := STRING_TO_INT (database[0, 2]); // Soll Temperatur PH-Glas
GvIn.iPyrometerB10In := STRING_TO_INT (database[0, 3]); // Ist Temperatur PH-Glas
GvPara.iParm2TolTemp := STRING_TO_INT (database[0, 4]); // Toleranz Temperatur PH-Glas
GvIn.Glas_Oberflaeche := STRING_TO_REAL (database[0, 5]); // Schwellenerkennung Glasoberfläche
GvPara.arTauchtiefe[GvPara.iRezeptPG] := STRING_TO_REAL (database[0, 6]); // Tauchtiefe
GvPara.aiTauchzeit[GvPara.iRezeptPG] := STRING_TO_INT (database[0, 7]); // Tauchzeit
GvPara.iRezeptGK := STRING_TO_INT (database[0, 8]); // Glasschaft Rezeptur
GvPara.arFotodiode[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 9]); // Variation Glaserkennung
GvAllg.rVorwaermzeit_Umr := STRING_TO_REAL (database[0, 10]); // Vorwärmzeit
GvPara.arPosGlasVor[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 11]); // Position Glas Vorwärmen
GvPara.arPos_Ausbl[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 12]); // Position Kuppe Ausblasen
GvPara.arKuppengr[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 13]); // Soll-Wert Kuppengrösse
GvAllg.rKuppeIstwert := STRING_TO_REAL (database[0, 14]); // Ist-Wert Kuppengrösse
GvPara.arTolKuppengr[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 15]); // Toleranz Kuppengrösse
GvPara.aiGlaslaenge[GvPara.iRezeptGK] := STRING_TO_INT (database[0, 16]); // Glaslänge
GvPara.rParm1Tiegelmax := STRING_TO_REAL (database[0, 17]); // Endpunkt im Tiegel
GvPara.iTimeOut := STRING_TO_DINT (database[0, 18]); // Zeit Glaserkennung
GvAllg.iKuppeCSV := STRING_TO_INT (database[0, 19]); // Glas OK = 1 / NIcht OK = 0
GvPara.rPAnteil1[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 20]); // P-Anteil für den PID Regler Glas formen
GvPara.rPAnteil2[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 21]); // P-Anteil für den PID Regler Glas formen
GvPara.rIAnteil1[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 22]); // I-Anteil für den PID Regler Glas formen
GvPara.rIAnteil2[GvPara.iRezeptGK] := STRING_TO_REAL (database[0, 23]); // I-Anteil für den PID Regler Glas formen
GvPara.iPowerAnteil1[GvPara.iRezeptGK] := STRING_TO_INT (database[0, 24]); // Power-Anteil für den PID Regler Glas formen
GvPara.iPowerAnteil2[GvPara.iRezeptGK] := STRING_TO_INT (database[0, 25]); // Power-Anteil für den PID Regler Glas formen
END_IF
END_IF
nColumn := nColumn + 1;(* Increment number of read columns *)
IF fbReader.bCRLF THEN(* CRLF == TRUE => End of reacord reached *)
nRow := nRow + 1;(* Increment number of read records *)
nColumn := 0;(* Reset number of columns *)
END_IF
ELSE(* Error: End of record reached or all fields read *)
step := 3;(* Try to read next line *)
END_IF
UNTIL NOT fbReader.bOk
END_REPEAT
10: (* Close source file *)
fbFileClose( bExecute := FALSE );
fbFileClose( sNetId := sNetId, hFile := hFile, bExecute := TRUE );
step := 11;
11:(* Wait until close not busy *)
fbFileClose( bExecute := FALSE, bError => bError, nErrID => nErrID );
IF ( NOT fbFileClose.bBusy ) THEN
hFile := 0;
step := 100;
END_IF
100: (* Error or ready step => cleanup *)
IF ( hFile <> 0 ) THEN
step := 10; (* Close the source file *)
ELSE
bBusy := FALSE;
step := 0; (* Ready *)
END_IF
END_CASE