Quantcast
Channel: SPS-Forum - Automatisierung und Elektrotechnik
Viewing all articles
Browse latest Browse all 47324

Messwerte mit Zeitstempel versehen und in eine CSV Datei schreiben

$
0
0
Hallo liebe Leute :),

ich komme momentan mit meinem Projekt nicht weiter und hoffe dass mir hier geholfen werden kann :)

Ich arbeite mit einer Wägezelle, die ich mit einer Beckhoff Klemme über TwinCAT2 anspreche. Ich habe schon ein Programm zur Kalibrierung geschrieben,und um die rohen Messdaten in Newton umzuwandeln und ich habe auch schon eine CSV Datei erstellt dazufolgender Code:

FUNCTION_BLOCK WriteCSV
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
bWrite : BOOL := FALSE;(* Rising edge starts program execution *)
sNetId : T_AmsNetId := ''; (* TwinCAT system network address *)
sFileName : T_MaxString := 'C:\Temp\Sensorauswertung.csv';(* CSV destination file path and name *)
sCSVLine : T_MaxString := '';(* Single CSV text line (row, record), we are using string as record buffer *)
sCSVField : T_MaxString := '';(* Single CSV field value (column, record field) *)
bBusy : BOOL;
bError : BOOL;
nErrId : UDINT;
nRow : UDINT := 0;(* Row number (record) *)
nColumn : UDINT := 0;(* Column number (record field) *)
hFile : UINT := 0;(* File handle of the source file *)
step : DWORD := 0;
fbFileOpen : FB_FileOpen;(* Opens file *)
fbFileClose : FB_FileClose;(* Closes file *)
fbFilePuts : FB_FilePuts;(* Writes one record (line) *)
fbWriter : FB_CSVMemBufferWriter;(* Helper function block used to create CSV data bytes (single record line) *)
MAX_CSV_COLUMNS :UINT :=1;
MAX_CSV_ROWS :UINT :=200;
MAX_CSV_FIELD_LENGTH :UINT:=250;
database : ARRAY[0..300, 0..1 ] OF STRING(250);
END_VAR


CASE step OF

0: (* Button bWrite muss aktiviert werden *)
IF bWrite THEN
bWrite := FALSE;
bBusy := TRUE;
bError := FALSE;
nErrId := 0;
hFile := 0;
nRow := 0;
nColumn := 0;
step := 1;
END_IF

1: (* Open source file *)
fbFileOpen( bExecute := FALSE );
fbFileOpen( sNetId := sNetId, sPathName := sFileName, nMode := FOPEN_MODEWRITE 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:(* Convert one PLC record to CSV format *)
sCSVLine := '';
fbWriter.eCmd := eEnumCmd_First;(* Write first field value *)
IF nRow <= MAX_CSV_ROWS THEN


FOR nColumn := 0 TO MAX_CSV_COLUMNS BY 1 DO


sCSVField := STRING_TO_CSVFIELD( database[ nRow, nColumn ], FALSE );(* TODO: Get field value from your application *)


(* Add new field to the record buffer *)
fbWriter( pBuffer := ADR( sCSVLine ),
cbBuffer := SIZEOF( sCSVLine ) - 1,
putValue := sCSVField, pValue := 0,
cbValue := 0,
bCRLF := ( nColumn = MAX_CSV_COLUMNS )
&nbsp;); (* bCRLF == TRUE => Write CRLF after the last field value *)
IF fbWriter.bOk THEN
fbWriter.eCmd := eEnumCmd_Next;(* Write next field value *)
ELSE(* Error *)
step := 100;
RETURN;
END_IF

END_FOR(* FOR nColumn := 0... *)

(* FB_FilePuts adds allready CR (carriage return) to the written line.
We have to replace the $R$L characters with $L character to avoid double CR. *)
IF RIGHT( sCSVLine, 2 ) = '$R$L' THEN
sCSVLine := REPLACE( sCSVLine, '$L', 2, LEN( sCSVLine ) - 1 );
END_IF

nRow := nRow + 1;(* Increment number of created records (rows) *)
step := 4;(* Write record to the file *)

ELSE(* All rows written => Close file *)
step := 10;
END_IF

4: (* Write single text line *)
fbFilePuts( bExecute := FALSE );
fbFilePuts( sNetId := sNetId, hFile := hFile, sLine := sCSVLine, bExecute := TRUE );
step := 5;

5:(* Wait until write not busy *)
fbFilePuts( bExecute := FALSE, bError => bError, nErrID => nErrID );
IF NOT fbFilePuts.bBusy THEN
IF NOT fbFilePuts.bError THEN
step := 3;(* Write next record *)
ELSE(* Error *)
step := 100;
END_IF
END_IF


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
END_FUNCTION_BLOCK


Wie kann ich nun meine Normierten Messwerte (rMesswertConv) mit einem Zeitstempel versehen und in mein Array (database) schreiben? Ich starte meine Messung über einen Button (bWrite) und beende diese dann auch drüber. Eine Messung dauert zwischen 3 und 10 Sekunden und ich kriege jede Millisekunde einen Messwert.

Ich bin noch recht neu in der SPS Programmierung, habe mir viel dazu selber angelesen aber noch kein "Profi" natürlich, kann also sein, dass die Lösung ziemlich einfach ist und ich einfach nur nicht das Wissen darüber verfüge, deswegen hoffe ich dass mir hier jemand helfen kann :)

Vielen Dank im Voraus!

Viewing all articles
Browse latest Browse all 47324


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>