FB_FileWrite Writeerror

Zuviel Werbung?
-> Hier kostenlos registrieren
Dein Beispiel wird nicht funktionieren. Du brichst in den Schritten 2, 4 und 31 mit deinem "bExecute := FALSE" die Bearbeitung der jeweiligen FBs ab. Nimm dieses bitte raus und ruf die FB mit leeren Klammern auf.

Testan kannst du das Ganze, indem du einen Pathname einsetzt, z.B. "C:/Test/Test.txt" und das Programm auf deinem PC laufen lässt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nachdem ich das Programm nun endlich zum laufen gebracht habe (danke Cerberus) habe ich nun direkt in Step2 einen error. Undzwar wechselt, bei step2, in der ersten Zeile
Code:
fbFileOpen( bExecute:=FALSE );
der Wert von
Code:
fbFileOpen.bBusy
von TRUE auf FALSE, dies ist soweit auch richtig (glaube ich). Das Problem ist, dass im selben moment
Code:
fbFileOpen.bError
von FALSE auf TRUE wechselt. Die entsprechende ErrId ist 1861, was wohl ein Problem mit dem Timer ist?! Dies sollte aber eigentlich nicht passieren, bzw ich verstehe nicht wieso :)
abermals danke im voraus =)

1:(* open file *)
fbFileOpen( bExecute := FALSE );
fbFileOpen( sNetId := '',
sPathName := 'C:\Dokumente und Einstellungen\Desktop\test.txt',
nMode := FOPEN_MODEWRITE OR FOPEN_MODETEXT
ePath := PATH_GENERIC,
tTimeout :=t#3s,
bExecute := TRUE );
Step := Step + 1;

2:
fbFileOpen(bExecute:=FALSE);
IF ( NOT fbFileOpen.bBusy ) THEN
IF ( fbFileOpen.bError ) THEN
nErrId := fbFileOpen.nErrId;
bError1 := TRUE;
Step := 50;
ELSE
hFileDatei := fbFileOpen.hFile;
Step := Step + 1;
END_IF
END_IF
 
Zuletzt bearbeitet:
Nachdem ich das Programm nun endlich zum laufen gebracht habe (danke Cerberus) habe ich nun direkt in Step2 einen error. Undzwar wechselt, bei step2, in der ersten Zeile
Code:
fbFileOpen( bExecute:=FALSE );
der Wert von
Code:
fbFileOpen.bBusy
von TRUE auf FALSE, dies ist soweit auch richtig (glaube ich). Das Problem ist, dass im selben moment
Code:
fbFileOpen.bError
von FALSE auf TRUE wechselt. Die entsprechende ErrId ist 1861, was wohl ein Problem mit dem Timer ist?! Dies sollte aber eigentlich nicht passieren, bzw ich verstehe nicht wieso :)
abermals danke im voraus =)

Dein Fehler 1861 heißt laut Beckhoff:
Dein Timeout hat also zugeschlagen. Verursacht wird das Ganze meiner Meinung nach von deinem Pfad. Ich glaube, dass der nicht korrekt ist. Oder hast du direkt unter "C:/Dokumente und Einstellungen/" einen Ordner "Desktop"? Bei mir kommt da noch der Benutzername.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ok, dann probier mal bitte folgendes:

1. Nimm mal im Step 2 das "bExecute:=FALSE" raus (ich trau dem nicht:rolleyes:).

2. Ich weiß nicht, ob "FOPEN_MODEWRITE" eine existierende Datei voraussetzt. Probiers mal indem du eine leere test.txt anlegst.

Wenn das alles nicht hilft, dann liegst höchst wahrscheinlich nicht an deinem Programm, aber das schauen wir dann wenn es soweit ist.
 
1. Nimm mal im Step 2 das "bExecute:=FALSE" raus (ich trau dem nicht:rolleyes:).
das hat wohl geholfen (obwohl ich mir sicher bin, dass ich es gestern auch schon einmal weg hatte =) )
Nun schreibt er mir in die datei aber nicht einfach die Zahlen 1 2 3 sondern einfach 3 kleine Rechtecke :) ist da noch irgendein Format falsch?
 
Ich vermute dass er deine Zahlen als ASCII interpretiert.

Ich selber schreibe immer Strings in meine Dateien. Du könntest dein Array in einen String umwandeln ala
Code:
LogString := DINT_TO_STRING(BuffRead[0]);
LogString := CONCAT(LogString, ' ');
LogString := CONCAT(LogString, DINT_TO_STRING(BuffRead[1])); 
LogString := CONCAT(LogString, ' ');
LogString := CONCAT(LogString, DINT_TO_STRING(BuffRead[2])); 
LogString := CONCAT(LogString, ' ');
LogString := CONCAT(LogString, DINT_TO_STRING(BuffRead[3])); 
LogString := CONCAT(LogString, ' ');
LogString := CONCAT(LogString, DINT_TO_STRING(BuffRead[4])); 
LogString := CONCAT(LogString, ' ');
LogString := CONCAT(LogString, DINT_TO_STRING(BuffRead[5]));
und diesen String dann wegschreiben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also bis ich herausgefunden hätte, dass ich das machen muss und wie das geht, wären wohl einige Monde vergangen :)
Also es klappt nun schon sehr gut und ich bin auch wirklich begeistert :)
nur habe ich nun noch das Problem, dass er immer wieder in den Step31 springt am ende, da muss es doch sowas wie ein
geben um aus der case anweisung zu springen oder?
 
Also ich mach das bei mir immer so, dass ich eine boolsche Variable und zwei Flankentrigger
Code:
bLogOn: BOOL := FALSE;
fbRTrig: R_TRIG;
fbFTrig: F_TRIG;
hab und während die Variable true ist, wird geloggt.
Ganz am Anfang von meinem Programm aktualisiere ich meine Flankentrigger
Code:
fbRTrig(CLK:= bLogOn);
fbFTrig(CLK:= bLogOn);
Um den File-Open-Code (bei dir Schritt 1) machst du dann
Code:
fbRTrig();
IF fbRTrig.Q OR bLogOn THEN
    (* Hier kommt der Code zum File öffnen *)
END_IF
und um den File-Write-Code (bei dir Schritt 3) kommt
Code:
fbFTrig();
IF NOT fbFTrig.Q THEN
    (* Hier kommt der Code zum File beschreiben *)
ELSE
    (* File schließen *)
    Step := 30;
END_IF

Den mittleren If-Zweig im Step 50 kannst du dir dann sparen.
 
Ich verstehe nicht so richtig wo ich nun was einfügen müsste,
gibt es denn kein "richtiges" switch-case Konstrukt bei dem man ein break nutzen kann?

Also was ich eigentlich machen will ist, dass er bei Knopfdruck einfach 6 Werte in eine datei schreibt. Am besten sollten die Werte untereinander stehen :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dann machs doch einfach so:
Code:
fbRTrig(CLK:=bLogOn);
 
sLogDaten := DINT_TO_STRING(BuffRead[0]);
sLogDaten := CONCAT(LogString, '$n');
sLogDaten := CONCAT(LogString, DINT_TO_STRING(BuffRead[1])); 
sLogDaten := CONCAT(LogString, '$n');
sLogDaten := CONCAT(LogString, DINT_TO_STRING(BuffRead[2])); 
sLogDaten := CONCAT(LogString, '$n');
sLogDaten := CONCAT(LogString, DINT_TO_STRING(BuffRead[3])); 
sLogDaten := CONCAT(LogString, '$n');
sLogDaten := CONCAT(LogString, DINT_TO_STRING(BuffRead[4])); 
sLogDaten := CONCAT(LogString, '$n');
sLogDaten := CONCAT(LogString, DINT_TO_STRING(BuffRead[5]));
 
CASE Step OF
    1:    (* File oeffnen *)
        fbRTrig();
        IF fbRTrig.Q THEN
            fbFileOpen(sNetId:= '',
                sPathName:= 'C:/Dokumente und Einstellungen/Cerberus/Desktop/test.txt,
                nMode:= FOPEN_MODEWRITE OR FOPEN_MODETEXT,
                ePath:= PATH_GENERIC,
                bExecute:= TRUE,
                tTimeout:= t#3s);
            Step := 2;
        END_IF
    2:
        fbFileOpen();
        IF NOT fbFileOpen.bBusy THEN
            IF fbFileOpen.bError THEN
                nErrId := fbFileOpen.nErrId;
                bError1 := TRUE;
                Step := 50;
            ELSE
                hFileDatei := fbFileOpen.hFile;
                Step := 3;
            END_IF
            fbFileOpen(bExecute:= FALSE);
        END_IF
    3:    (* File schreiben *)
        fbFileWrite(sNetId:= '',
            hFile:= hFileDatei,
            pWriteBuff:= ADR(sLogDaten),
            cbWriteLen:= LEN(sLogDaten),
            bExecute:= TRUE,
            tTimeout:= t#3s);
        Step := 4;
    4:
        fbFileWrite();
        IF NOT fbFileWrite.bBusy THEN
            IF fbFileWrite.bError THEN
                nErrID := fbFileWrite.nErrId;
                bError2 := TRUE;
                Step := 50;
            ELSE
                Step := 5;
            END_IF
            fbFileWrite(bExecute:= FALSE);
        END_IF
    5:    (* File schliessen *)
        fbFileClose(sNetId:= '',
            hFile:=hFileDatei,
            bExecute:= TRUE,
            tTimeout:= t#3s);
        Step := 6;
    6:
        fbFileClose();
        IF NOT fbFileClose.bBusy THEN
            IF fbFileClose.bError THEN
                nErrId := fbFileClose.nErrId;
                bError3 := TRUE;
                Step := 50;
            ELSE
                Step := 1;
            END_IF
            fbFileClose(bExecute:= FALSE);
        END_IF
END_CASE
 
Danke.
Dies entspricht, abgesehen von dem R_TRIG ja vom prinzip meinem Programm. Hier habe ich doch aber wieder das problem, dass wenn ich bspw dies als Function machen möchte und es aus meinem main Programm auffrufe, dann doch aber wieder ganze Zeit in dieser case anweisung gefangen bin oder wann würde er hier das case denn verlassen?
Wenn man bedenkt, dass case50 nun so aufgebaut ist
50:
(*Fehler beim öffnen oder schreiben aufgetreten, von vorne anfangen*)
IF (bError1=TRUE OR bError2=TRUE) THEN
bError1:=FALSE;
bError2:=FALSE;
Step := 1;
(*Fehler beim schließen der Datei aufgetreten, von vorne anfangen*)
ELSIF (bError3=TRUE) THEN
bError3:=FALSE;
Step:=1;


END_IF
 
Das RTrig srogt dafür, dass der Log-Prozess auf eine Variable reagiert. Diese kannst du dann im Knopfdruck setzen.

Das Problem an der Funktion bzw. FB ist, dass beide das CASE einmal durchlaufen, dann verlassen und auch den FB bzw. Funktion verlassen. Deshalb würd ich so ne File-Write-Geschichte auch immer im Programm laufen lassen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Problem an der Funktion bzw. FB ist, dass beide das CASE einmal durchlaufen, dann verlassen und auch den FB bzw. Funktion verlassen.

Um Missverständnissen vorzubeugen:
In deinem Fall würde in ner Funktion das CASE mit Step = 1 durchgeführt und danach wieder verlassen. Es würde also nur die Datei geöffnet, nichts geschrieben und so.
 
Ja genau! Aber gerade das soll ja nicht passieren :) daher wundert es mich ja so stark, dass es keinen switch befehl gibt! Dieser würde ja genau dieses verhalten verhindern.
In deinem Fall würde in ner Funktion das CASE mit Step = 1 durchgeführt und danach wieder verlassen. Es würde also nur die Datei geöffnet, nichts geschrieben und so.
d.h. mein Konstrukt mit dem case ist in diesem fall alles andere als sinnvoll, hast du eine Idee wie ich es ansonsten machen könnte? Wenn ich kein richtiges switch-case Konstrukt habe, dann kann ich doch nie wirklich auf meine Errors eingehen oder?

Ich könnte natürlich einfach fileopen-filewrite-fileclose hintereinander ausführen lassen und in meinem fall einfach case 50 komplett weglassen. Und wenn es dann halt mal einen Error gibt, dann funktioniert die Funktion halt einmal nicht :) oder ist eine SPS so schnell, das es egal ist wenn er beim ersten durchlaufen nur case1 macht und wenn dann das ganze SPS-Programm wieder von vorne läuft, dann würde er ja case2 bearbeiten...eine SPS arbeitet schon wie in so ner endlosschleife, arbeitet also immer wieder die MAIN ab oder?=)
 
Zuletzt bearbeitet:
daher wundert es mich ja so stark, dass es keinen switch befehl gibt! Dieser würde ja genau dieses verhalten verhindern.
d.h. mein Konstrukt mit dem case ist in diesem fall alles andere als sinnvoll, hast du eine Idee wie ich es ansonsten machen könnte? Wenn ich kein richtiges switch-case Konstrukt habe, dann kann ich doch nie wirklich auf meine Errors eingehen oder?

Das Case ist ein ganz normales switch-case!!


Ich könnte natürlich einfach fileopen-filewrite-fileclose hintereinander ausführen lassen und in meinem fall einfach case 50 komplett weglassen. Und wenn es dann halt mal einen Error gibt, dann funktioniert die Funktion halt einmal nicht :) oder ist eine SPS so schnell, das es egal ist wenn er beim ersten durchlaufen nur case1 macht und wenn dann das ganze SPS-Programm wieder von vorne läuft, dann würde er ja case2 bearbeiten...eine SPS arbeitet schon wie in so ner endlosschleife, arbeitet also immer wieder die MAIN ab oder?=)

Also wenn du das ganze in ner Funktion laufen lassen würdest, dann würde er bei jeder Durchführung immer nur den case 1 durchlaufen. Das liegt daran, dass bei jedem Aufruf der Funktion die internen Variablen Default-Werte erhalten.
Ob es in nem FB funzt, kann ich dir nicht sagen.

Was du natürlich machen könntest, ist, dass du deine Variable Step als In-Out-Variable im FB deklarierst. Dann würdest du den FB mit Step = 1 aufrufen und er würde dir nach der Bearbeitung Step = 2 zurückgeben. Im nächsten Schritt musst du dann halt den FB mit Step = 2 aufrufen.
 
Zurück
Oben