String in Datei abspeichern / Save String to Textfile

bartsimpson

Level-1
Beiträge
8
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
Ich benutze seit einigen Tagen TwinCat XAE 3.1.0.0
Ich möchte einen String in einer Textdatei ablegen, jedoch funktioniert das nicht ganz so wie geplant:

english:
I have been using Twincat XAE 3.1.0.0 for a few Days now,
I want to save a String to a textfile. Anyway i tried for an entire day without getting it working:



Code:
FUNCTION_BLOCK FB_SaveStuff
VAR_INPUT
    inputstring:STRING;
    filepath:STRING;
END_VAR
VAR_OUTPUT
END_VAR
VAR
    fileinstance: FB_FileOpen;
    filewriter: FB_FileWrite;
    filecloser: FB_FileClose;
    sReceivedmessage: INT;
    Step       : DWORD:=1;;
    fileloser: INT;
END_VAR




CASE Step OF 
        1:
        fileinstance(bExecute:=FALSE);
        fileInstance(sNetId:='',sPathname:=filepath,nMode:=FOPEN_MODEWRITE OR FOPEN_MODEPLUS OR FOPEN_MODETEXT,tTimeout:=T#1S,bExecute:=TRUE );
        
        IF(NOT(fileinstance.bBusy)) THEN
            Step:=Step+1;
        END_IF
        2:
        filewriter(bExecute:=FALSE);
        filewriter(sNetId:='',hFile:=fileInstance.hFile,pWriteBuff:=ADR(inputstring),
        cbWriteLen:=SIZEOF(inputstring),tTimeout:=T#1S,bExecute:=TRUE);

        IF(NOT(filewriter.bBusy)) THEN
        Step:=Step+1;
        END_IF
        3:
        filecloser(bExecute:=FALSE);
        filecloser(sNetId:='',hFile:=fileInstance.hFile,tTimeout:=T#1S,bExecute:=TRUE);
    
        IF(NOT(filecloser.bBusy)) THEN
        Step:=Step+1;
        END_IF
        
        
END_CASE

Das Programm hängt seltsamerweise im ersten Case fest (fileinstance.bBusy=true)
der parameter blieb bisher bei jeder der drei Dateninstanzen auf true stehen.
Danke für die Hilfe

Strangely, the Program stands still at Case one: (fileinstance.bBusy=true)
The Parameter was always Stuck to true in every of the three instances.

Thanks in progress

bartsimpson
 
Ich kann es gerade nicht testen, aber ich denke der Fehler liegt darin, dass Du den FB dauernd mit einer steigenden Flanke befeuerst. Schalte nach dem Aufruf mit False und True mal in einen Zwischenschritt und ruf den FB da mal nur mit False auf.

Von irgendwas mit Internetzugang gesendet.
 
Dann hast Du meinen Tipp vermutlich nicht richtig umgesetzt.
Der FB sollte einmal mit False und dann mit True aufgerufen werden. Anschließend ohne die Ausgänge abzufragen in einen neuen Schritt springen, den FB mit False aufrufen und Busy abfragen.

Von irgendwas mit Internetzugang gesendet.
 
Danke für die Hilfe Oliver,
Der Code sieht jetzt so aus:

Code:
CASE Step OF 
        
        1:
        fileinstance(bExecute:=FALSE);
        fileInstance(sNetId:='',sPathname:=filepath,nMode:=FOPEN_MODEWRITE OR FOPEN_MODEPLUS OR FOPEN_MODETEXT);
        fileinstance(bExecute:=TRUE);
        Step:=Step+1;
        
        2:
        fileinstance(bExecute:=FALSE);
        IF(NOT(fileinstance.bBusy)) THEN
            Step:=Step+1;
        END_IF
        3:
        filewriter(bExecute:=FALSE);
        filewriter(sNetId:='',hFile:=fileInstance.hFile,pWriteBuff:=ADR(inputstring),
        cbWriteLen:=SIZEOF(inputstring));
        filewriter(bExecute:=TRUE);
        Step:=Step+1;
        4:
        filewriter(bExecute:=FALSE);
        IF(NOT(filewriter.bBusy)) THEN
        Step:=Step+1;
        END_IF
        5:
        filecloser(bExecute:=FALSE);
        filecloser(sNetId:='',hFile:=fileInstance.hFile);
        filecloser(bExecute:=TRUE);
        Step:=Step+1;
        
        6:
        filecloser(bExecute:=FALSE);
        IF(NOT(filecloser.bBusy)) THEN
        Step:=Step+1;
        END_IF
        
    END_CASE

Leider läuft jetzt der TimeOut über und alle drei funktionen liefern den Fehlercode 1861.
Eine Frage, die ich mir gestellt habe, ist ob dieser code solange widerholt werden muss, bis case 7 erreicht ist (While Schleife) , oder ob einmaliges Ausführen ausreicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

die Variable "Step" ist doch eine lokale Variable, d.h. sie wird bei jedem Aufruf wieder mit 1 initialisiert.
So kann die Weiterschaltung nicht funktionieren.

Gruß
Koslovski
 
Ich habe die Switch anweisung mit
Code:
WHILE (Step<7) DO
[I]Anweisungen wie oben
END_WHILE[/I]
umschlossen, funktioniert nach wie vor nicht.
Es wird jedoch eine Datei im Zielordner erzeugt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo bartsimpson,
ich habe gerade mal TC3 3.1.4018.26 installiert und Dein Programm getestet, so leid es mir tut, aber bei mir läuft die zweite Version fehlerfrei. Hast Du mal versucht den Timeout zu erhöhen.
Ergänze mal die Auswertung der Rückmeldung um das Error Flag, also wenn nicht Busy und kein Fehler anliegt springe in den nächsten Schritt, wenn nicht Busy und Fehler in den (nicht vorhandenen) Schritt aktueller Schritt + 10, dann kannst Du erkennen in welchem Schritt er hing.

Gruß

Oliver
 
Habe das Programm jetzt mal als Main ausgeführt, da funtioniert es auch ohne Probleme,
so wie es aussieht brauche ich eine Schleife, die mehrmals über die Case-Abfrage Läuft. Jedoch Ist das so im Programm nicht realisierbar, ich möchte das ganze eigentlich gerne in einer Funktion aufrufen, was aus irgendeinem Grund nicht funtioniert. :(
 
Zuletzt bearbeitet:
Als Funktionsblock, wie in Deinem Beispiel geht es, als Funktion nicht, aus dem Grund den Koslovski genannt hatte, dann müsstest Du Step als statische Variable deklarieren.
Ich hatte in Main eine Instanz Deines FBs angelegt und diesen da dann immer aufgerufen und es lief.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Problem scheint gerade zu sein, dass ich die Datei durch einmaliges aufrufen eines Befehls (steigende flanke) erzeugen möchte. jedoch funktioniert das ganze gerade nur, wenn es in der Hauptschleife der Main aufgerufen wird. Gibt es hier eine elegante Lösung, das irgendwie hinzukriegen?
 
Kannst Du da mal konkreter werden?
Dein FB kann nicht nur einmal aufgerufen werden, dieser muss immer wieder aufgerufen werden, bis alle Schritte durch sind.

Von irgendwas mit Internetzugang gesendet.
 
Das ganze sieht bisher wie folgt aus:

Ich habe in meiner Main eine Abfrage, ob eine Nachricht per UDP Protokoll eingegangen ist.
wenn dies der Fall ist, soll eine Routine ausgeführt werden, in der die empfangene Nachricht in einer Datei gespeichert wird.
Danach soll die Main wieder von vorne beginnen.
Das bedeutet für mich, dass ich in irgendeiner Form eine Schleife um meine Instanz des Funktionsblocks brauche.
Jedoch weiß ich nicht, wie ich das geschickt anstellen soll.
 
Das bedeutet für mich, dass ich in irgendeiner Form eine Schleife um meine Instanz des Funktionsblocks brauche.
Jedoch weiß ich nicht, wie ich das geschickt anstellen soll.
Die "Schleife" gibt es doch schon als "äußere Schleife", indem Deine Main immer wieder aufgerufen wird. WHILE-Schleifen werden in SPS nicht verwendet, SPS werden anders programmiert. Dein Programm muß sich nur merken, daß es mit der Erfüllung einer Aufgabe beschäftigt ist, daß es einen Prozess angestoßen hat und nun auf die Fertig-/Rückmeldung wartet - allerdings nicht tatenlos wartet. Da "guckt" das Programm einfach immer wieder kurz vorbei, ob die Rückmeldung vorliegt, schaltet ggf. zum nächsten Schritt der Aufgabe und wendet sich weiteren Aufgaben zu.

Harald
 
Ich habe die Switch anweisung mit
Code:
WHILE (Step<7) DO
[I]Anweisungen wie oben
END_WHILE[/I]
umschlossen, funktioniert nach wie vor nicht.
Das mußt Du anders formulieren, z.B. etwa so:
Code:
Main:
+--+
|  |
^  v
|  IF bUDP_Message_empfangen THEN bMessage_speichern_aktiv := true ; END_IF;
^
|  MyFB(bMessage_speichern_aktiv, ...)
^
|  IF NOT MyFB.busy THEN bMessage_speichern_aktiv := false ; END_IF;
^  |
+--+


FUNCTION_BLOCK MyFB

  IF Flanke(bMessage_speichern_aktiv) AND Step = 0 THEN Step := 1

  CASE Step OF
    1: fileinstance(bExecute:=FALSE); ...
    2: ...
    3: ...
    n: IF NOT filecloser.bBusy THEN Step:=0; END_IF
  END_CASE

  busy := Step <> 0;

END_FUNCTION_BLOCK

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke Oliver und Harald,
habe das Problem jetzt dank eurer Hilfe gelödt bekommen.
Die Lösung sah jetzt so aus, dass mein Functionblock die Variablen bExecute und bBusy enthält, und einfach immer wieder aufgerufen wird.
Gruß, Bart
 
Hallo, Bartsimpson!
Wenn Du die 3 instanzen außerhalb der case anweisung aufrufst, sollte es gehen:
fileinstance();
filewriter();
filecloser();
case step of
1: fileinstance.bExecute:=true;
....
else
....;
end_case
 
Hallo Caroli,
ist Dir aufgefallen, daß die Instanzen immer zweimal aufgerufen werden?
Wie würdest Du das lösen? Mehr CASEs?

Harald
 
Zurück
Oben