# B&R AS: Daten in Datei speichern



## fighter (28 September 2008)

Erstmal Hallo an die ganze Forumgemeinde! 

Wie kann ich mit der Biblithek FileIO eine Datei auf die Compact Flash einer X20CP1484 schreiben? Kann ich auch eine Netzwerklaufwerk dazu verwenden? Wie konfiguriere ich das? 

Ich möchte dort eine CSV Datei erstellen mit Prüfdaten. 
Ist es möglich mit Hilfe von FileIO in eine bestimmte Zeile in der Datei zu schreiben (Datei sollte einen vorgegebene Struktur haben)? Gibt es dort einen Parameter den ich übergeben kann der die Zeile bestimmt (habe leider in der Hilfe nichts gefunden dazu). 

Kann ich auch eine externe Datei bzw. Programm aufrufen mit hilfe der Steuerung. Am Ende meines Prüfvorgangen möcht ich automatisch eine Excel datei öffnen wo das alles dann importiert wird (automatisch). 

mfg


----------



## harrylask (28 September 2008)

Hallo fighter,



> Wie kann ich mit der Biblithek FileIO eine Datei auf die Compact Flash einer X20CP1484 schreiben?



Habe im Moment nicht das AS zur Hand, morgen kann ich dazu mehr sagen. Nur soviel, ich kann mich dunkel erinneren das dazu ein Laufwerk eingerichtet werden muss (in den CPU Eigenschaften). Betreff Netzlaufwerk müsste da auch ein Reiter vorhanden sein (zumindestens ab ~V2.7.?.?).



> Ist es möglich mit Hilfe von FileIO in eine bestimmte Zeile in der Datei zu schreiben (Datei sollte einen vorgegebene Struktur haben)?



Das sollte mit dieser Library eigentlich kein Problem sein (Stichwort File Seek).



> Kann ich auch eine externe Datei bzw. Programm aufrufen mit hilfe der Steuerung. Am Ende meines Prüfvorgangen möcht ich automatisch eine Excel datei öffnen wo das alles dann importiert wird (automatisch).



Wie soll denn das gehen? Nö, das musst du PC seitig machen.

Grüsse, harrylask


----------



## fighter (28 September 2008)

Danke für die Antwort. 

Eine Funktion FileSeek habe ich nicht gefunden. Man kann zwar in der Funktion FileWrite einen Offset setzen aber der bezieht sich nur auf die aktuelle Zeile. 

Gibt es keine Möglichkeit vielleicht eine Batchdatei bzw. ect. aufzurufen? 

mfg


----------



## harrylask (29 September 2008)

Hallo fighter,



> Eine Funktion FileSeek habe ich nicht gefunden. Man kann zwar in der Funktion FileWrite einen Offset setzen aber der bezieht sich nur auf die aktuelle Zeile.



Was brauchst du mehr? Obwohl der _Offset_ den Abstand in *Bytes* angibt, aber ich denke du weisst das.



> Gibt es keine Möglichkeit vielleicht eine Batchdatei bzw. ect. aufzurufen?



Davon wären unsere Kollegen aus der IT sicher begeistert! Das muss vom PC ausgehen, oder möchtest du das einer mit seinem Handy das Automatikprogramm deiner Steuerung starten kann?

Grüsse, harrylask


----------



## fighter (29 September 2008)

hi, 
aber wie kann ich dan bestimmen in welche Zeile ich Daten schreiben will? 
ich kann ja so nur bestimmen wo in der aktuellen zeile. 

mfg


----------



## harrylask (29 September 2008)

Zeilenweise Positionierung des Filepointers wird von dieser Library nicht unterstützt, erzähl mal genauer was du vorhast.


----------



## fighter (29 September 2008)

hi, 
ja die einzelnen Werte sollen in einer CSV Datei abgespeichert werden. 
Z.B:
Wert1;Wert2;  //1 Zeile 
Wert3; // 2. Zeile
//3.Zeile
Wert4 //4Zeile
So sollte die Datei aussehen. 
Es geht zwar das ich in die nächste Zeile hüpfe (indem ich den ASCII Wert schreibe), aber ich möchte auch wenn die Datei schon vorhanden ist Daten überschreiben. 
lg


----------



## harrylask (29 September 2008)

Ich denke das du für die einzelnen Werte eine feste Länge hast, denn wenn nicht dann kannst du einen ziemlichen Murks in deine Datei bekommen wenn du da munter hineinschreibst.

Ich würde diese Sache anders angehen, und zwar würde ich die Daten zB. in einem Array halten, diese Werte zu überschreiben wäre dann kein Problem. Zum Schluss, oder wann auch immer, täte ich daraus die CSV Datei erstellen.

Was hältst du davon?


----------



## fighter (29 September 2008)

so werd ich es eh mach!

Eine Frage hätte ich noch:
Kann man ein Netzwerklaufwerk einbinden? Sodas ich die geschriebene Datei dort hinverschieben kann? 

mfg


----------



## harrylask (30 September 2008)

Du kannst per CIFS (habe ich noch nie gemacht) Laufwerke freigeben auf denen du dann von extern zugreifen kannst (so habe ich es verstanden, leider steht dafür in der Hilfe nicht viel drinnen) oder, so hat es mein Kollege probiert, die Datei auf ein eingerichtetes Laufwerk speichern und diese per FTP kopieren. Auf Umwegen könnte man es auch mit PVI Transfer Tool gehen. Ich selbst kopiere Messdaten eigentlich immer per PVI aber dazu muss man für den PC ein Programm schreiben.


----------



## da_kine (30 September 2008)

Wie willst du die Daten denn in ein CSV-File bringen? Die B&R Librarys unterstützen nämlich keine "printf" Funktionen. Du kannst wie gesagt nur Byteweise schreiben, und das gibt dann irgendwelche komischen Zeichenfolgen in der Datei. Hab das auch mal vor ner Zeit verusucht, bin damals aber auf keinen Grünen Zweig gekommen. Hab mir dann auf dem PC noch ein kleines :TOOL: geschrieben, um die Binary-Files in ein CSV umzuwandeln. Denke da wirst du auch nicht drum rumkommen.

MFG

Markus


----------



## harrylask (30 September 2008)

Hallo da_kine,
sieh dir mal die AsString Library an, da sind diverse Funktionen (ftoa, itoa, strcat) der Standard C Library für die Nicht-C Programmierer drinnen. Mit diesen sollte es eigentlich zu schaffen sein.

Abgesehen davon gebe ich dir naürlich recht, am PC sind :TOOL:s einfacher und sicherer zu programmieren. Ich denke aber das fighter diesen Weg, aus welchen Gründen auch immer, nicht gehen will.

Grüsse, harrylask


----------



## da_kine (30 September 2008)

Ja, diese diversen ftoa usw. hab ich auch gesehen, mich aber nicht näher damit beschäftigt, da ich das Tool sowieso zur Auswertung gebraucht habe. Drum hab ich es dann hier gleich mit umgewandelt und in ne CSV geschrieben.


----------



## fighter (30 September 2008)

mit FileIO müsste es schon möglich sein komplette Strings in die Datei zu schreiben. Zumindest habe ich es testweise schon probiert und da hat es funktioniert. 

mfg


----------



## harrylask (30 September 2008)

Das steht ausser Frage, da_kine meinte die Konvertierung deiner Werte in Strings die du ja machen musst bevor du sie in die Datei schreibst.


----------



## da_kine (1 Oktober 2008)

Ja, ich meinte die konvertierung in Strings. Am PC mache ich einfach ein File auf und schreibe via "fprintf" da rein. Aber da is B&R bei "C" sowas wie Siemens bei der 61131. Verstehe net warum man diese Funktion rausgenommen hat, da das ganze ja sowieso auf nem Unix basiert.

MFG

Markus


----------



## skyracer (8 Oktober 2008)

Hey,
ich erzeuge mit der Fileio nach Benutzereingabe "Macroprogramme" für eine CNC-Anlage und lege diese als File auf der CF ab. Siehe unten (Auszug aus dem QC).
Schreib doch einfach anstatt  strcpy(buffer,";"); 
und gut ist! Ich Sende auch Daten über TCP/IP mit Delemiter ";". String zusammenbasteln und weg damit.

			strcpy( buffer, "X" );
			ftoa( makro1.length+makro1.start_x, (UDINT) tempstring );
			strcat( buffer, tempstring );
			strcat( buffer, CRLF "G02 Y" );
			ftoa( makro1.act_y, (UDINT) tempstring );
			strcat( buffer, tempstring );
			strcat( buffer, " I0 J-" );
			ftoa( makro1.distance / 2, (UDINT) tempstring );
			strcat( buffer, tempstring );
			strcat( buffer, CRLF "X" );
			ftoa( makro1.start_x, (UDINT) tempstring );
			strcat( buffer, tempstring );
			strcat( buffer, CRLF "G03 Y" );
			ftoa( makro1.act_y - makro1.distance, (UDINT) tempstring );
			strcat( buffer, tempstring );
			strcat( buffer, " I0 J-" );
			ftoa( makro1.distance / 2, (UDINT) tempstring );
			strcat( buffer, tempstring );
			strcat( buffer, CRLF );

Hier noch das TCP/IP Beispiel zum String zusammensetzen:

				case '1':
					strcpy( tempstring, ";" );
					/* Art */
					ftoa( ART, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Jahr */
					ftoa( JAHR, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Monat */
					ftoa( MONAT, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Tag  */
					ftoa( TAG, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Stunde */
					ftoa( STUNDE, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Minute */
					ftoa( MINUTE, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Sekunde */
					ftoa( SEKUNDE, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );					
					/* Anlage */
					ftoa( ANLAGE, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );					
					/* Status */
					ftoa( STATUS, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Personalnummer */
					strcat( tempstring, PERSONAL );
					strcat( tempstring, ";" );
					/* Programm */
					strcat( tempstring, PROGRAMM );
					strcat( tempstring, ";" );
					/* Geschwindigkeit */
					ftoa( SPEED, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Soll_Temperatur */
					ftoa( SOLLTEMP, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );					
					/* Ist_Temperatur */
					ftoa( ISTTEMP, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );					
					/* Wellenfaktor */
					ftoa( WELLE, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Bremsfaktor vor */
					ftoa( BREMSVOR, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Bremsfaktor nach*/
					ftoa( BREMSNACH, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Niederhalter Zustand */
					ftoa( NIEDERSTAT, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Niederhalter + */
					ftoa( NIEDERPLUS, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Niederhalter - */
					ftoa( NIEDERMINUS, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Restdraht */
					ftoa( RESTDRAHT, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Meld_Notaus */
					ftoa( MELD1, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Meld_Phase */
					ftoa( MELD2, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );
					/* Meld_Drahtbruch */
					ftoa( MELD3, (UDINT) tempstring + strlen(tempstring));
					strcat( tempstring, ";" );

					client_.send.pData = (UDINT) tempstring;
					client.send.datalen = strlen( (char*) tempstring );
					client.send.enable = 1;


Zum Thema in Float in String oder CHR$ umwandeln habe ich mir folgendermassen geholfen:
(Lese über die Serielle Schnittstelle RFID-Chip's vom Personal aus (QS) Leseeinheit mit Chip's ca. 60 Euronen)
Die Wandlung im AS/Basic lässt eben zu Wünschen übrig!

strcpy(adr(PERSONAL),"")


		loop Index = 2 to 11 do 


		    if read_data[Index]=48 then
		    strcpy(ADR(PERS),"0")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=49 then
		    strcpy(ADR(PERS),"1")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=50 then
		    strcpy(ADR(PERS),"2")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

			if read_data[Index]=51 then
		    strcpy(ADR(PERS),"3")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

			if read_data[Index]=52 then
		    strcpy(ADR(PERS),"4")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=53 then
		    strcpy(ADR(PERS),"5")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=54 then
		    strcpy(ADR(PERS),"6")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=55 then
		    strcpy(ADR(PERS),"7")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=56 then
		    strcpy(ADR(PERS),"8")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=57 then
		    strcpy(ADR(PERS),"9")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=65 then
		    strcpy(ADR(PERS),"A")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=66 then
		    strcpy(ADR(PERS),"B")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=67 then
		    strcpy(ADR(PERS),"C")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=68 then
		    strcpy(ADR(PERS),"D")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=69 then
		    strcpy(ADR(PERS),"E")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		    if read_data[Index]=70 then
		    strcpy(ADR(PERS),"F")
		    strcat(adr(PERSONAL), adr(PERS))
		    endif

		endloop 






Vielleicht hilf es Dir ja.
Sende Dir gerne mehr QC!
Gruss Skyracer_


----------



## fighter (10 Oktober 2008)

Hi,
Gibt es eine Möglichkeit Variable vom Typ String(50) so zu beschneiden das die Leerzeichen rausgeslöscht werden und somit auch mit FileWrite nicht in die Datei geschrieben werden?

test1 := 'testtext'

bzw. gibt es eine Möglichkeit die Anzahl der genutzen Zeichen zu zählen? 

testtext => 8
mfg


----------



## fighter (10 Oktober 2008)

ich habe mir folgende Library geschrieben. Diese soll Werte die in einem Array stehen in eine CSV datei schreiben. 

Es funktioniert soweit, nur schreibt sie teilweise irgendwelche Buchstaben mit in die Datei und ich weiß nicht wo die herkommen. 
Steht in dem Arrayeintrag ein "-ln-" soll eine Eingabetaste eingefügt werden. 
Vom Quellstext her habe ich mich an die Hilfe von AS gehalten. 




```
IF EDGEPOS(start) THEN
 byStep := 1;
 bOK := FALSE;
 start := FALSE;
END_IF
CASE byStep OF
        0: (**** Error step ****)
                bOK := FALSE;
        1: (**** Try to open existing file ****)
                (* Initialize file open structrue *)
                FOpen.enable    := 1;
                FOpen.pDevice   := ADR(strDevice);
                FOpen.pFile     := ADR(strFile);
                FOpen.mode      := FILE_RW;  (* Read and write access *)
                (* Call FUB *)
                FOpen();
                (* Get FUB output information *)
                dwIdent := FOpen.ident;
                wStatus := FOpen.status;
                (* Verify status (20708 -> File doesn't exist) *)
                IF (wStatus = 20708) THEN
                        byStep := 2;
                ELSE
                        IF (wStatus = 0) THEN
                                byStep := 6;
                        ELSE
                                IF (wStatus <> 65535) THEN
                                        byErrorLevel    := 1;
                                        byStep          := 0;
                                        IF (wStatus = 20799) THEN
                                                wError := FileIoGetSysError();
                                        END_IF
                                END_IF
                        END_IF
                END_IF
                i := 0;
                offset := 0;
 
        2: (**** Create file ****)
                (* Initialize file create structure *)
                FCreate.enable  := 1;
                FCreate.pDevice := ADR(strDevice);
                FCreate.pFile   := ADR(strFile);
                (* Call FUB *)
                FCreate();
                (* Get output information of FUB *)
                dwIdent := FCreate.ident;
                wStatus := FCreate.status;
                (* Verify status *)
                IF (wStatus = 0) THEN
                        byStep := 3;
                ELSE
                        IF (wStatus <> 65535) THEN
                                byErrorLevel    := 2;
                                byStep          := 0;
                                IF (wStatus = 20799) THEN
                                        wError := FileIoGetSysError();
                                END_IF
                        END_IF
                END_IF
        3: (**** Write data to file ****)
                (* Initialize file write structure *)
    IF  i < 15 THEN
     byStep := 31;
    ELSE
     byStep := 5;
    END_IF
  31:
    IF data_to_file[i] = '-ln-' THEN
     write_int := 13;
           FWrite.enable   := 1;
                 FWrite.ident    := dwIdent;
                 FWrite.offset   := offset;
                 FWrite.pSrc     := ADR(write_int);
                 FWrite.len      := SIZEOF(write_int);
             ELSE
              write_string := CONCAT(data_to_file[i],';');
           FWrite.enable   := 1;
                 FWrite.ident    := dwIdent;
                 FWrite.offset   := offset;
                 FWrite.pSrc     := ADR(write_string);
                 FWrite.len      := SIZEOF(write_string);
             END_IF
                (* Call FUB *)
                FWrite();
                (* Get status *)
                wStatus := FWrite.status;
                (* Verify status *)
                IF (wStatus = 0) THEN
                 IF data_to_file[i] = '-ln-' THEN
      offset := offset + 3;
              ELSE
      offset := offset + SIZEOF(write_string);
              END_IF
               i := i +1;
                        byStep := 3;
                ELSE
                        IF (wStatus <> 65535) THEN
                                byErrorLevel    := 3;
                                byStep          := 0;
                                IF (wStatus = 20799) THEN
                                        wError := FileIoGetSysError();
                                END_IF
                        END_IF
                END_IF
 

        5: (**** Close file ****)
                (* Initialize file close structure *)
                FClose.enable   := 1;
                FClose.ident    := dwIdent;
                (* Call FUB *)
                FClose();
                (* Get status *)
                wStatus := FClose.status;
                (* Verify status *)
                IF (wStatus = 0) THEN
                        bOK := TRUE;
                        byStep := 7;
                ELSE
                        IF (wStatus <> 65535) THEN
                                byErrorLevel    := 5;
                                byStep          := 0;
                                IF (wStatus = 20799) THEN
                                        wError := FileIoGetSysError();
                                END_IF
                        END_IF
                END_IF
        6: (**** Delete file ****)
                (* Initialize file delete structure *)
                FDelete.enable  := 1;
                FDelete.pDevice := ADR(strDevice);
                FDelete.pName   := ADR(strFile);
                (* Call FUB *)
                FDelete();
                (* Get status *)
                wStatus := FDelete.status;
                (* Verify status *)
                IF (wStatus = 0) THEN
                        byStep  := 2;
                ELSE
                        IF (wStatus <> 65535) THEN
                                byErrorLevel    := 6;
                                byStep          := 0;
                                IF (wStatus = 20799) THEN
                                        wError := FileIoGetSysError();
                                END_IF
                        END_IF
                END_IF
END_CASE
```
 
mfg


----------



## harrylask (10 Oktober 2008)

Hallo fighter,



> gibt es eine Möglichkeit die Anzahl der genutzen Zeichen zu zählen?



AsString, strlen(), siehe hier



> Gibt es eine Möglichkeit Variable vom Typ String(50) so zu beschneiden das die Leerzeichen rausgeslöscht werden und somit auch mit FileWrite nicht in die Datei geschrieben werden?



Bei vielen Sparchen nennt man das trimmen. In der B&R Hilfe habe ich dazu nichts gefunden.

Servus, harrylask


----------



## harrylask (10 Oktober 2008)

Was fürn Datentyp ist denn _write_int_ (sollte ein SINT sein) und _offset := offset + 3_ kommt mir auch komisch vor (du schreibst doch nur ein Byte rein, oder?).


----------

