# Werte in Textfile exportieren und importieren



## Jone (11 August 2020)

Hallo zusammen,

ich stehe vor der Aufgabe, Werte (welche in der Visu einstellbar sind) in einem Textfile auf einer WAGO microSD-Karte exportieren und importieren zu können.

Ich hab zum Testen eine 0750-8100 aufgebaut und hab in der eCockpit-Software ein DUT vom Typ "Export_Import" mit vier DINTs erstellt (zum Testen):

```
TYPE Export_Import :
STRUCT
    Variable1    : DINT := 60;
    Variable2    : DINT := 30;
    Variable3    : DINT := 45;
    Variable4    : DINT := 20;
END_STRUCT
END_TYPE
```

Im Hauptprogramm hab ich für das 'Schreiben' Folgendes programmiert:

```
VAR
    oWriteCfg    : FbWriteWholeFile_cpt;
    sWriteErrorInfo    : STRING;
    xMeinTrigger    : BOOL;
    xWriteError    : BOOL;
    
    oCfg        : Export_Import;
END_VAR

// Programm
oWriteCfg(
     xTrigger    := xMeinTrigger,
    xError        => xWriteError,
     sName        := 'datei.txt', 
     pTxBuffer    := ADR(oCfg), 
     udiTxNBytes    := SIZEOF(oCfg));
oWriteCfg.oStatus.ShowResult(sDescription => sWriteErrorInfo);
```


Dies hab ich nach folgendem "Vorbild" aufgebaut:
https://www.sps-forum.de/wago/90738-variablen-speichern-einlesen-pfc200-cockpit.html


Beim Triggern des Schreibbefehls kommt bei 'sWriteErrorInfo' nach dem Schreibvorgang immer die Meldung: 'OK' und mein Trigger wird automatisch auf FALSE gesetzt, also sieht für mich alles richtig aus (aus Hilfe: "The FB signals the finishing of the write process by setting xTrigger to FALSE again").

Eine Datei wurde auf der microSD-Karte jedoch nie erstellt.
Auch wenn ich eine leere Datei angelegt hab, wurde diese nicht gefüllt.


Wo könnte der Fehler liegen, dass keine Datei erstellt wurde?


----------



## oliver.tonn (11 August 2020)

Schon mal versucht einen führenden / beim Dateinamen oder einen vorhandenen Pfad + Dateiname anzugeben?


----------



## Jone (11 August 2020)

oliver.tonn schrieb:


> Schon mal versucht einen führenden / beim Dateinamen oder einen vorhandenen Pfad + Dateiname anzugeben?


Ja hab beides schon probiert. Hat leider nicht funktioniert.


----------



## Peter255 (11 August 2020)

Hallo,



> Zitat Jone
> Beim Triggern des Schreibbefehls kommt bei 'sWriteErrorInfo' nach dem  Schreibvorgang immer die Meldung: 'OK' und mein Trigger wird automatisch  auf FALSE gesetzt, also sieht für mich alles richtig aus (aus Hilfe:  "The FB signals the finishing of the write process by setting xTrigger  to FALSE again").



Es ist richtig, nach dem ersten Aufruf wird  xTrigger automatisch auf FALSE gesetzt.
Dir ist schon klar, dass die Instanz "oWriteCfg" von  FbWriteWholeFile_cpt mehrmals aufgerufen werden muss?
In dem Moment, wenn xTrigger auf FALSE gesetzt wird, wird der Ausgang  xBusy auf TRUE gesetzt.
In deinem Programm wird aber xBusy gar nicht verwendet. 
Jetzt muss "oWriteCfg" solange aufgerufen werden bis xBusy wieder auf FALSE gesetzt wird. 
Erst dann ist der Schreibvorgang beendet.

Bei mir sieht Abfrage für das Ende des Schreibvorgangs etwa so aus.

IF (xTrigger OR xBusy) = FALSE THEN
    //Fertig jetzt Aufrufe beenden
END_IF

Grüße

Peter


----------



## holgermaik (11 August 2020)

Hallo Jone
der Dateiname wäre 
	
	



```
'/home/codesys/Dateiname.bin'
```
Du hast standartmäßig nur hier Schreibrechte. Möchtest du woanders speichern muss das Verzeichnis vorhanden sein und Schreibrechte müssen gesetzt sein.
Den FB musst du in jedem Zyklus aufrufen. Zum Anstoßen des Schreibauftrages muss der Trigger auf TRUE gesetzt werden. Dieser wird vom FB wieder zurückgesetzt.
Die Auswertung von Busy ist zwar sinnvoll aber nicht zwingend notwendig.

Der FB erzeugt aber keine Textdatei die du bearbeiten kannst sondern ein Binärfile.
Holger


----------



## Jone (18 August 2020)

holgermaik schrieb:


> Hallo Jone
> der Dateiname wäre
> 
> 
> ...


Vielen Dank. Der Import/Export hat geklappt, aber es gibt offene Punkte (unten).

Ich hab das Tool "WinSCP" heruntergeladen und bin folgendermaßen vorgegangen:
1. WinSCP installiert, gestartet und IP-Adresse, Name und Passwort eingegeben.



2. Controller gestartet und in der Visu auf meinen Trigger für den Parameterexport (Export in '/home/codesys/Dateiname.bin') gedrückt, anschließend steht folgendes in datei.bin




Der Export und Import funktioniert bei INTs und REALs problemlos, andere Datentypen hab ich noch nicht probiert.


*Offene Fragen:*
*a) Gibt es eine Möglichkeit, die Werte nicht in ASCII-Werten sondern in Dezimalwerten o.ä. zu speichern, um die Werte in der .bin-Datei lesbar(er) zu machen?*
*b)* Der Import/Export-Test hat auch ohne SDcard funktioniert und auch die .bin-Datei ist ohne SDcard lesbar. Es sieht so aus, als würden die Ordner und Dateien irgendwo anders erstellt. *Wo?*
Die Vorgabe ist jedoch, die Parameter einer Anlage auf die SDcard zu exportieren und diese Parameter auf einer zweiten Anlage zu importieren.
*Wie kann man die Parameter auf der SDcard speichern?*


----------



## oliver.tonn (18 August 2020)

Zu a, dann müsstest Du die Zahlen in Strings wandeln und die Struktur entsprechend abändern, ist allerdings quick and dirty.


----------



## Peter255 (18 August 2020)

Hallo,

um Daten auf SD-Card zu speichern lautet der Path "/media/sd" => "/media/sd/MeinDateiname"  auch  "/media/sd/Verzeichnis/MeinDateiname" ist möglich.
Wenn "Verzeichnis" nicht vorhanden ist wird es beim Schreiben automatisch angelegt. Um Probleme mit Zugriffsrechten zu umgehen habe ich die SD.Card
mit dem Fat32 Dateisystem formatiert.

Noch ein Hinweis.
In der Bibliothek WagoAppFileDir aus der der Funktionsblock "FbWriteWholeFile_cpt" stammt, sind unter Modular auch
die Funktionsblöcke FbGeneralFile_WriteString und FbGeneralFile_ReadString zu finden.
Allerdings wird es dann etwas komplizierter da man sich vor dem schreiben und lesen jeweils um das öffnen und schließen der Datei
kümmern muss. Mit einem Schreibvorgang kann ein String mit max 255 Zeichen geschrieben werde.
Was sonst noch beachtet werden muss kann ich nicht sagen, da ich diese Funktionsblöcke bisher noch nicht genutzt habe.

Grüße

Peter


----------



## KLM (18 August 2020)

Mal nebenbei gefragt, warum eigentlich so umständlich über Schreiben und Lesen von Dateien? Warum nimmst Du nicht die fertige Rezeptverwaltung? Das sind doch auch Textdateien im Dateisystem. Nur dass die Handhabung deutlich einfacher ist und alle erforderlichen Funktionen schon vorhanden und auf Deine Zwecke zugeschnitten sind.


----------



## Jone (26 August 2020)

oliver.tonn schrieb:


> Zu a, dann müsstest Du die Zahlen in Strings wandeln und die Struktur entsprechend abändern, ist allerdings quick and dirty.


Hab ich nun bei einer Varablen versucht mit folgendem Ergebnis:


Die ersten 3 ASCII-Zeichen (M, N, O) sind rausgespuckt worden, als ich die DINTs 77, 78 und 79 eingegeben haben.
Meinen 4.DINT (92) hab ich vor dem Export in einen String umgewandelt. Es wird zwar die Zahl 92 ausgegeben, jedoch mit vielen anderen Zeichen hinterher (siehe Bild).
Die '33¢B' zum Schluss ist ein Realwert.



> // Export
> IF ExportTrigger THEN
> oCfg.STRINGvariable                   := DINT_TO_STRING(Parameterliste.DINTvariable);
> END_IF
> ...



*Gibt es Möglichkeiten, die Variablen im File besser darstellen zu können oder muss man mit den "Hieroglyphen" wie "³$/    ¹v³p·v³Ì¶v³    $·v³     ·v³x·v³$/    ¹v³p·v³ô¶v³    H·v³    ø¶v³" leben?*




Peter255 schrieb:


> Hallo,
> 
> um Daten auf SD-Card zu speichern lautet der Path "/media/sd" =>  "/media/sd/MeinDateiname"  auch  "/media/sd/Verzeichnis/MeinDateiname"  ist möglich.
> Wenn "Verzeichnis" nicht vorhanden ist wird es beim Schreiben  automatisch angelegt.[...]


Danke, hat geklappt.




KLM schrieb:


> Mal nebenbei gefragt, warum eigentlich so umständlich  über Schreiben und Lesen von Dateien? Warum nimmst Du nicht die fertige  Rezeptverwaltung? Das sind doch auch Textdateien im Dateisystem. Nur  dass die Handhabung deutlich einfacher ist und alle erforderlichen  Funktionen schon vorhanden und auf Deine Zwecke zugeschnitten  sind.


Ich wollte es nach diesem Beispiel aufbauen. Hat einfach ausgesehen und ist im Grunde eigentlich auch nicht kompliziert. Die Rezeptverwaltung schau ich mir dann auch an, danke.


----------



## oliver.tonn (26 August 2020)

Jone schrieb:


> Hab ich nun bei einer Varablen versucht mit folgendem Ergebnis:
> Anhang anzeigen 50836
> 
> Die ersten 3 ASCII-Zeichen (M, N, O) sind rausgespuckt worden, als ich die DINTs 77, 78 und 79 eingegeben haben.
> ...


Na ja, Du schreibst in die Datei die komplette Struktur oCfg und in dieser ist der String nur ein Teil davon, der Rest (Die Hieroglyphen) ist der Inhalt der anderen Elemente. Statt die Struktur komplett zu schreiben müsstest Du ein Array of Byte anlegen und in dieses dann alle Strings mit MEMCPY und LEN reinkopieren, falls Du einen Zeilenwechsel möchtest dessen ASCII-Codes hinzufügen und dann nicht die maximale Länge des Arrays beim Schreiben angeben, sondern nur die Länge der tatsächlichen Daten.


----------

