Logging von Meldungen oder Variablen in Datei

Für Themen rund um logi.RTS und logi.CAD 3
User avatar
Walter
Official 3rd Party Support logi.cals
Posts: 77
Joined: 15 Dec 2016, 12:56
Answers: 0

Re: Logging von Meldungen oder Variablen in Datei

Post by Walter »

Hallo Kai,


Folgendes Programm sollte für deine Anforderungen geignet sein:

Code: Select all

PROGRAM RevolutionPiFilewriteProgram
	VAR CONSTANT
        /* Append new information to the end of the file. */
        Linux_O_APPEND : DINT := 1024;
        /* If the file does not exist, create it. If the O_CREAT option is used, then you must include the third parameter (mode). */
        Linux_O_CREAT  : DINT := 64;
        /* Combined with the O_CREAT option, it ensures that the caller must create the file. If the file already exists, the call will fail. */
        Linux_O_EXCL   : DINT := 128;
        /* Open the file so that it is read only. */
        Linux_O_RDONLY : DINT := 0;
        /* Open the file so that it can be read from and written to. */
        Linux_O_RDWR   : DINT := 2;
        /* Initially clear all data from the file. */
        Linux_O_TRUNC  : DINT := 512;
        /* Open the file so that it is write only. */
        Linux_O_WRONLY : DINT := 1;
	END_VAR
	
	VAR
		INIT : BOOL:=TRUE;
		writeCounter : DINT := 0;
		fileDescriptor : DINT := 0;
		data : ARRAY[0..63] of BYTE;
        flagsWriteAppend : DINT := -1;
    	flagsCreateTruncWrite : DINT := -1;
		flags : DINT :=-1;
        mode : DINT := 0;
		my_string : STRING[64] := 'Hello World';
	END_VAR
		
	IF INIT THEN	
		/* write access, append to file content */
       	flagsWriteAppend := IOR(LINUX_O_WRONLY, LINUX_O_APPEND);
       	/* write access, create file and truncate file to length 0 */
       	flagsCreateTruncWrite := IOR(LINUX_O_WRONLY, LINUX_O_CREAT, LINUX_O_TRUNC);
       	/* read and write access for the user */
		
 	  	fileDescriptor := System_open(pathname := '/tmp/file.log', flags := flagsWriteAppend, ENO => ENO);
        IF NOT(ENO) THEN                            /* file does not exist yet */
        	fileDescriptor := System_open(pathname := '/tmp/file.log', flags := flagsCreateTruncWrite, mode := mode, ENO => ENO);
        END_IF;
	  	
		INIT:=FALSE;
	END_IF;
	
	/* Transfering string to BYTE array */
	  data := StrToByteArr(my_string);	  
    
      System_write(fd := fileDescriptor, data := data, count := LEN(my_string));     
    
      System_close(fd := fileDescriptor);
		
END_PROGRAM

Für das Transferieren des Strings in ein Byte-Array ist folgender C-Baustein geeignet:

Code: Select all

#ifndef LC_PROT_LCFU___STRTOBYTEARR__C
#define LC_PROT_LCFU___STRTOBYTEARR__C

#include <lcfu___strtobytearr.h>
#include "stdio.h"

/*                            Functions                        */
void  lcfu___STRTOBYTEARR(LC_TD_Function_STRTOBYTEARR* LC_this, LcCgChar LC_VD_MYSTRING[65], struct _lcoplck_epdb_1_impl* pEPDB)
{
	memcpy(LC_this->LC_VD_STRTOBYTEARR, LC_VD_MYSTRING, 64);
  /* Vendor Code */
}

#endif

freundliche Grüße
Walter
Qi Wang
Posts: 13
Joined: 23 Aug 2018, 14:09
Answers: 0

Re: Logging von Meldungen oder Variablen in Datei

Post by Qi Wang »

Hallo Ingo,

Ich möchte mein Messwerte exportieren. Und ich finde Ihre Antwort.

Ich denke, dass es ein sehr günstig Methode ist.

Aber ich habe einige Frage. Könnten Sie mir sagen?
1. Wie kann das Funktion Block funktionieren, nach ich diese Funktion Block in mein Programm einfüge?
2. Wie kann ich das "Persistent.csv" machen? Wo kann ich das Datei finden?

Vielen Dank vorab!
Qi Wang

Ingo wrote: 16 May 2018, 18:18 Hallo Kai.
Ich weiss ja nicht was du für Variablenwerte schreiben und wieder lesen willst. Aber sollte es sein das du nur bestimmte sachen Sichern willst und beim fall eines aussfalls wieder lesen möchtest?
Sollte es so sein dann benutze doch die Load_Save_retaindata.

Code: Select all

FUNCTION_BLOCK Load_Save_Retain_Data { vNameAlignment := "top"; width := 400; bgColor := "lightblue"; }

  VAR_INPUT
  	WRITE : BOOL :=false; // Zum Schreiben in die Persisten.csv / USV Anschluss oder anderen Schaltkontakt
  	READ  : BOOL :=false; 
  END_VAR
 
   VAR
    init          : BOOL;
    term          : BOOL;
    saveRetainRC  : UDINT;
    saveRetainENO : BOOL;
    nrNonLoaded   : INT;
    loadRetainRC  : UDINT;
    loadRetainENO : BOOL;
  END_VAR
  
  	RTSCycleInfo   ( Init => init, Term => term ); // RTSLoader abfragen ob start und ende
  	LoadRetainData ( EN := init, fileName := 'Persistent.csv', nrNonLoaded => nrNonLoaded, RC => loadRetainRC, ENO => loadRetainENO );
  	SaveRetainData ( EN := term, fileName := 'Persistent.csv', RC => saveRetainRC, ENO => saveRetainENO );
  	

    if (READ) THEN // Wenn gelesen werden soll !!
  		LoadRetainData ( EN := true, fileName := 'Persistent.csv', nrNonLoaded => nrNonLoaded, RC => loadRetainRC, ENO => loadRetainENO );
  	END_IF;
   	if (WRITE) THEN // Wenn geschrieben werden soll dann schreiben !!
  		SaveRetainData ( EN := true, fileName := 'Persistent.csv', RC => saveRetainRC, ENO => saveRetainENO );
  	END_IF;

END_FUNCTION_BLOCK
Sollte dies Passen wie du es haben willst kannst du das gerne verwenden.
die Variablen die du sichern möchtest müssen dann in einer extra variablenliste stehen.

Code: Select all

GLOBALS Retain_data
VAR_GLOBAL RETAIN
	rd_Variable   	: STRING[100];  (z.B.)
END_VAR

END_GLOBALS
User avatar
Walter
Official 3rd Party Support logi.cals
Posts: 77
Joined: 15 Dec 2016, 12:56
Answers: 0

Re: Logging von Meldungen oder Variablen in Datei

Post by Walter »

Hallo,


ich möchte in der Zwischenzeit dir 2 Antworten geben:

zu 1) Ein Funktionsblock muss zuerst im Programm deklariert werden und kann dann im PLC Code "aufgerufen/verwendet" werden
zu 2) Über die logi.CAD 3 Funktionalität "RetainData" wird eine Datei am Zielsystem geschrieben. Deren Speicherort und Dateiname wird in der Datei "RTSIO.cfg" (am Zielsystem) eingestellt:
AddSymbol RTSS_PERSISTENCE.DefaultPath /opt/RTS/PLC/
AddSymbol RTSS_PERSISTENCE.DefaultFilename persistence.csv


freundliche Grüße
Walter
Qi Wang
Posts: 13
Joined: 23 Aug 2018, 14:09
Answers: 0

Re: Logging von Meldungen oder Variablen in Datei

Post by Qi Wang »

Hallo Herr Walter,

Vielen Dank für Ihre Hilfe!

Ich werde das probieren.

Mit freundlichen Grüßen
QW

Walter wrote: 12 Oct 2018, 12:47 Hallo,


ich möchte in der Zwischenzeit dir 2 Antworten geben:

zu 1) Ein Funktionsblock muss zuerst im Programm deklariert werden und kann dann im PLC Code "aufgerufen/verwendet" werden
zu 2) Über die logi.CAD 3 Funktionalität "RetainData" wird eine Datei am Zielsystem geschrieben. Deren Speicherort und Dateiname wird in der Datei "RTSIO.cfg" (am Zielsystem) eingestellt:
AddSymbol RTSS_PERSISTENCE.DefaultPath /opt/RTS/PLC/
AddSymbol RTSS_PERSISTENCE.DefaultFilename persistence.csv


freundliche Grüße
Walter
TUC_SRT
Posts: 5
Joined: 27 Nov 2017, 08:25
Answers: 0

Re: Logging von Meldungen oder Variablen in Datei

Post by TUC_SRT »

Hallo Walter,

ich habe die von Ihnen bereitgestellte Variante zum Schreiben eines Strings in eine externe Datei getestet - bisher leider ohne Erfolg...

Das Programm entspricht dabei der von Ihnen geposteten Variante, wobei folgender Fehler ausgegeben wird:
"Ausruck hat keinen Ergebniswert" (markiert ist dabei der Funktionsaufruf von StrToByteArr)

Code: Select all

PROGRAM RevolutionPiFilewriteProgram
	VAR CONSTANT
        /* Append new information to the end of the file. */
        Linux_O_APPEND : DINT := 1024;
        /* If the file does not exist, create it. If the O_CREAT option is used, then you must include the third parameter (mode). */
        Linux_O_CREAT  : DINT := 64;
        /* Combined with the O_CREAT option, it ensures that the caller must create the file. If the file already exists, the call will fail. */
        Linux_O_EXCL   : DINT := 128;
        /* Open the file so that it is read only. */
        Linux_O_RDONLY : DINT := 0;
        /* Open the file so that it can be read from and written to. */
        Linux_O_RDWR   : DINT := 2;
        /* Initially clear all data from the file. */
        Linux_O_TRUNC  : DINT := 512;
        /* Open the file so that it is write only. */
        Linux_O_WRONLY : DINT := 1;
	END_VAR
	
	VAR
		INIT : BOOL:=false;
		writeCounter : DINT := 0;
		fileDescriptor : DINT := 0;
		data : ARRAY[0..63] of BYTE;
        flagsWriteAppend : DINT := -1;
    	flagsCreateTruncWrite : DINT := -1;
		flags : DINT :=-1;
        mode : DINT := 0;
		my_string : STRING[64] := 'Hello World';
	END_VAR
		
	IF INIT THEN	
		/* write access, append to file content */
       	flagsWriteAppend := IOR(LINUX_O_WRONLY, LINUX_O_APPEND);
       	/* write access, create file and truncate file to length 0 */
       	flagsCreateTruncWrite := IOR(LINUX_O_WRONLY, LINUX_O_CREAT, LINUX_O_TRUNC);
       	/* read and write access for the user */
		
 	  	fileDescriptor := System_open(pathname := '//home/pi/file.log', flags := flagsWriteAppend, ENO => ENO);
        IF NOT(ENO) THEN                            /* file does not exist yet */
        	fileDescriptor := System_open(pathname := '//home/pis/file.log', flags := flagsCreateTruncWrite, mode := mode, ENO => ENO);
        END_IF;
	  	
		INIT:=FALSE;
	END_IF;
	
	/* Transfering string to BYTE array */
	  data := StrToByteArr(my_string);	  // Fehler: Ausdruck hat keinen Ergebniswert

      System_write(fd := fileDescriptor, data := data, count := LEN(my_string));     
    
      System_close(fd := fileDescriptor);
		
END_PROGRAM
Die zugehörige C-Funktion entspricht ebenfalls ihrem Vorschlag:

Code: Select all

#ifndef LC_PROT_LCFU___STRTOBYTEARR__C
#define LC_PROT_LCFU___STRTOBYTEARR__C

#include <lcfu___strtobytearr.h>

/*                            Functions                        */
void  lcfu___STRTOBYTEARR(LC_TD_Function_STRTOBYTEARR* LC_this, LcCgChar LC_VD_MY_STRING[65], struct _lcoplck_epdb_1_impl* pEPDB)
{
	memcpy(LC_this->LC_VD_STRTOBYTEARR, LC_VD_MY_STRING, 64);
  /* Vendor Code */
}

#endif
Die C-Schnittstelle sieht folgendermaßen aus:

Code: Select all

{extern_c}

function StrToByteArr
Var_input
my_string : string[64];
end_var
Var_output
STRTOBYTEARR : array[0..63] of byte;
end_var
end_function
Liegt der Fehler gegebenfalls in dieser Schnittstelle vor?

Vorab bereits vielen Dank für ihre Hilfe!

Viele Grüße,

Chris
User avatar
Walter
Official 3rd Party Support logi.cals
Posts: 77
Joined: 15 Dec 2016, 12:56
Answers: 0

Re: Logging von Meldungen oder Variablen in Datei

Post by Walter »

Hallo Chris,

ich habe das eben nochmal mit dem bei uns im Haus verfügbaren Revolution Pi getestet.
Ergebnis (nach mehreren Programmläufen):
root@RevPi3422:/tmp# cat file.log
Hello WorldHello WorldHello WorldHello WorldHello Worldroot@RevPi3422:/tmp#
Mein Projekt findest du im angehängten ZIP. Nach dem ändern der IP-Adresse sollte das mit Deinen Komponenten funktionieren.


lg
Walter
Attachments
Schreibtest_RevolutionPi.7z
(130.98 KiB) Downloaded 685 times
User avatar
Walter
Official 3rd Party Support logi.cals
Posts: 77
Joined: 15 Dec 2016, 12:56
Answers: 0

Re: Logging von Meldungen oder Variablen in Datei

Post by Walter »

Hallo,


bitte ändere die "drittvorletzte Programmzeile" folgendermaßen um:

[..]
/* Transfering string to BYTE array */
StrToByteArr(my_string:=my_string,StrToByteArr=>data);

System_write(fd := fileDescriptor, data := data, count := LEN(my_string));

System_close(fd := fileDescriptor);

END_PROGRAM

lg
Walter
Post Reply