Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 3 von 3

Thema: Messwerte mit Zeitstempel versehen und in eine CSV Datei schreiben

  1. #1
    Registriert seit
    09.09.2016
    Beiträge
    1
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    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!
    Zitieren Zitieren Messwerte mit Zeitstempel versehen und in eine CSV Datei schreiben  

  2. #2
    Registriert seit
    21.02.2014
    Ort
    Sachsen-Anhalt
    Beiträge
    1.093
    Danke
    155
    Erhielt 167 Danke für 154 Beiträge

    Standard

    Die Systemzeit holst Du Dir so in's Programm:

    Code:
    VAR
        systemzeit:FB_LocalSystemTime;
        datensatz:FB_FormatString;
        s_Datensatz_a: STRING(100);
    end_var
    (****************************************************************************************)
    (* windows systemzeit auslesen und mit rtc synchronisieren *)
    systemzeit(
        sNetID:= , (*default local*)
        bEnable:=TRUE ,
        dwCycle:=5 ,
        dwOpt:=1 ,
        tTimeout:= , (*default 5s*)
        bValid=> ,
        systemTime=> ,
        tzID=> );
    
    (****************************************************************************************)
    Den Datensatz kannst Du dann so zusammenbauen:

    Code:
    (*datensatz zusammenbauen*)
    
        datensatz(
            sFormat:='%2u.%2u.%4u;%2u:%2u:%2u:%3u;%5u;',  (*formatstring: Beispiel  12.09.2016;19:53:22:888;xxxxx;  *)
            arg1:=F_WORD(systemzeit.systemTime.wDay) ,            (* also Datum; Uhrzeit mit Millisekunden; Messwert *)
            arg2:=F_WORD(systemzeit.systemTime.wMonth) ,
            arg3:=F_WORD(systemzeit.systemTime.wYear) ,
            arg4:= F_WORD(systemzeit.systemTime.wHour),
            arg5:= F_WORD(systemzeit.systemTime.wMinute),
            arg6:=F_WORD(systemzeit.systemTime.wSecond),
            arg7:=F_WORD(systemzeit.systemTime.wMilliseconds),
            arg8:=F_WORD(normierter wert),
            arg9:= ,
            arg10:= ,
            bError=> ,
            nErrId=> ,
            sOut=>s_Datensatz_a);
    Bekommst Du wirklich jede Millisekunde neue Messwerte? In dem Falle würde ich die Messwerte in einer langsameren Task sammeln und in einem größeren Rutsch schreiben. Interessant wird dabei auch das Speichermedium. Eine SD-Karte würde das nicht lange überleben. Für die wäre es besser, in größeren Blöcken (min. 512Byte) zu schreiben. Ob für arg8 jetzt F_Word die richtige Konvertierung ist, mußt Du selbst entscheiden.

    s_Datensatz_a kannst Du dann in ein Array of String schreiben. Deinen Schritt "3* Convert one PLC record to CSV format *)" rationalisiere ich so mal eben weg.
    Der Datensatz wird dann bei mir noch mit CRLF ergänzt und so habe ich in jedem Schritt einen vollständigen Datensatz mit Zeit und Datum.

    Die Datei schreibe ich dann nicht mit fileputs sondern mit filewrite. Deine 10 Sekunden kannst Du locker in einem Array vorhalten und dann komplett in's File schreiben. Hast Du Angst vor Datenverlust wg. Stromausfall, dann ist Beckhoff's NOVRAM gut zu gebrauchen dafür.
    Geändert von weißnix_ (09.09.2016 um 14:32 Uhr)

  3. #3
    Registriert seit
    21.02.2014
    Ort
    Sachsen-Anhalt
    Beiträge
    1.093
    Danke
    155
    Erhielt 167 Danke für 154 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ich vergaß zu erwähnen:
    TcUtilities.lib muß für die Nutzung obengenannter FB's eingebunden werden. Sorry.

Ähnliche Themen

  1. Step 7 AktualWerte aus DB auslesen und in CSV Datei schreiben
    Von Toki0604 im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 16.12.2015, 02:35
  2. Antworten: 7
    Letzter Beitrag: 27.02.2015, 17:04
  3. String mit Timer in CSV Datei schreiben.
    Von umpalumpa im Forum CODESYS und IEC61131
    Antworten: 10
    Letzter Beitrag: 04.07.2014, 11:02
  4. Messwerte auf USB Stick in CSV schreiben
    Von blimaa im Forum CODESYS und IEC61131
    Antworten: 10
    Letzter Beitrag: 20.02.2013, 13:21
  5. csv-Datei schreiben mit XC201
    Von glunki im Forum CODESYS und IEC61131
    Antworten: 0
    Letzter Beitrag: 29.08.2011, 11:26

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •