Codesys CAA File bitte Hilfe

Niko194

Level-1
Beiträge
19
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo erstmal und Danke das du mir helfen möchtest.
Ich möchte über die CAA file Lib eine Csv/txt datei erstellen wo diese 4 Sensorwerte hinterlegt werden.
Ich probiere es schon eine gefühlte Ewigkeit aus.

Das Programm möchte einfach nicht mir diese Datei im Laufwerk F erstellen, bzw. auch nicht überschreiben und verwenden. Ich check das Problem einfach nicht. Hab das Gefühl die Lib wird in der Bib einfach nicht mehr unterstützt.

Das Programm hat sehr Ähnlichkeit mit einem Beispiel snippet aus dem Netz.

Bin außerdem neu was Codesys anbelangt.


PROGRAM POU
VAR
Flussmenge:STRING;
Licht:STRING;
Temp1:STRING;
Temp2:STRING;

bWriteData:BOOL:=FALSE; //trigger to write log-data
uiStpDataLogger:UDINT:=0; //sequencer

//Dateiname und Pfad
sFileName: CAA.FILENAME:= 'F:/TestFile.csv'; // Dateiname
hFile: CAA.HANDLE;

measuredData: ARRAY [1..4] OF logData := [(index:='Flussmenge',data:='Flussmenge'),(index:='Lichtmenge',data:='Licht'),(index:='Temperatur 1',data:='Temp1'),(index:='Temperatur 2',data:='Temp2')];
sStringToWrite: STRING:='no data';
writeIndex:UINT:=1;

CRLF:STRING(2):= '$R$N';
LF:STRING(1):= '$N';

fopen : FILE.Open;
fwrite : file.Write;
fclose : file.Close;


END_VAR
Flussmenge := REAL_TO_STRING(Gvl.rAI0Fluss);
Licht := REAL_TO_STRING(Gvl.rAI1Licht);
Temp1 := REAL_TO_STRING(Gvl.rAI2Temp);
Temp2 := REAL_TO_STRING(Gvl.rAI3Temp);


CASE uiStpDataLogger OF

//TRIGGER fürs Daten schreiben

(*wait for trigger*)
0: IF bWriteData THEN
bWriteData:=FALSE;
uiStpDataLogger:=10;
END_IF

10: (* Datei Öffnung*)
fopen.sFileName:=sFileName;
fopen.eFileMode:=File.MODE.MRDWR;
fopen.xExclusive:=TRUE;
fopen( xExecute:=TRUE);
IF fopen.xDone THEN
hFile:=fopen.hFile;
sStringToWrite:='';
writeIndex:=1;
uiStpDataLogger:=20;
END_IF

20: (*Daten zusammenführen*)
sStringToWrite:=CONCAT(measuredData[writeIndex].index,',');
sStringToWrite:=CONCAT(sStringToWrite,measuredData[writeIndex].data);
sStringToWrite:=CONCAT(sStringToWrite,CRLF);
//sStringToWrite:=CONCAT(sStringToWrite,LF);
uiStpDataLogger:=30;

30: (* Schreiben in die Datei *)
fwrite.hFile:=hFile;
fwrite.pBuffer:=ADR(sStringToWrite);
fwrite.szSize:=LEN(sStringToWrite);
fwrite.udiTimeOut:=100000; //Timeout
fwrite( xExecute:=TRUE);
IF fwrite.xDone THEN
fwrite( xExecute:=FALSE);
writeIndex:=writeIndex+1;
IF writeIndex <= 4 THEN
uiStpDataLogger:=20;
sStringToWrite:='';
ELSE
uiStpDataLogger:=40;
END_IF
END_IF
IF fwrite.xError THEN
//Error
uiStpDataLogger:=16#DEADBEEF;
END_IF

40: (* Datei Schließen *)
fclose.hFile:=hFile;
fclose( xExecute:=TRUE);
IF fclose.xDone THEN
fopen( xExecute:=FALSE);
fwrite( xExecute:=FALSE);
fclose( xExecute:=FALSE);
uiStpDataLogger:=0;
END_IF
IF fclose.xError THEN
//Error
uiStpDataLogger:=16#DEaaaaaa;
END_IF

16#DEADBEEF:
//ErrorHandling
;
END_CASE
 
Benutze doch bitte die CODE TAGS, so ist das eine Katastrophe zum lesen.

Und es fehlen auch Infos.
Was für eine Codesys Version, was für eine Windows Version, worauf läuft das Ganze,
sind die entsprechenden Laufwerksfreigaben vorhanden usw....
 
Zuviel Werbung?
-> Hier kostenlos registrieren
sFileName: CAA.FILENAME:= 'F:/TestFile.csv'; // Dateiname

Abgesehen von den fehlenden Informationen, einfach mal ins Blaue gefragt: Sicher daß hier ein Slash und kein Backslash hin gehört?
Was bekommst Du denn für einen Fehlercode zurückgeliefert? fopen, fwrite, fclose sollten Dir eigentlich Stati zurückgeben, so daß Du weißt, was passiert (oder eben nicht).
 
Codesys V3.5 SP15 Patch1
Win 10

Hab es mit den Slash und Backflash probiert, dass klappt leider nicht.
Fehlercodes standen keine drin im Baustein. Das einzige was er mir gibt was fraglich ist das nach dem durchlauf im hfile irgend eine lange zahl steht 19830..... irgendwie so.
 
Danke

ich möchte nur testweise erstmal das er mir die Datei auf den Rechner packt. Oder wie ist es da verzwickt ?
 
also ich hab mir das angeschaut...
keine ahnung ob ich da zu unerfahren bin aber das sind lediglich andere konfigurationsnamen für mein sfilename

ausser die sps aktualisieren. Bekomme auch komische fehlermeldungen von wegen systimertc in der bib...
 
Bekomme auch komische fehlermeldungen von wegen systimertc in der bib...
Wenn du da Hilfe brauchst, solltest du diese vielleicht hier nennen.

Du verwendest in deinem Skript:
Was ja sicherlich schon mal falsch ist, dies müsste zumindest so lauten:

Bezüglich dem LinuxKonvention, das ist auch nicht so mein Fachgebiet aber dem Link nach sollte es wohl
in folgender Form angegeben sein:
/home/pi/deinOrdner/TestFile.csv
Wie gesagt, ohne Gewähr. Ich mache nichts mit Linux
 
Zuviel Werbung?
-> Hier kostenlos registrieren
das mit dem backslach und normalen hab ich alles getestet gehabt. auch wenn ich die beispielprogramme rüber kopiere etc. erstellt er mir nicht einmal eine datei, selbst wenn ich eine vorhandene datei nur rein schreiben möchte klappt das alles nicht. Die einzelnen Bausteine geben keine Fehlermeldungen raus.
Deswegen wende ich mich an das Forum hier da mein Latein begrenzt ist mittlerweile :/

das mit dem /home/pi... teste ich aus danke .
 
Codesys V3.5 SP15 Patch1
Win 10

Hab es mit den Slash und Backflash probiert, dass klappt leider nicht.
Fehlercodes standen keine drin im Baustein. Das einzige was er mir gibt was fraglich ist das nach dem durchlauf im hfile irgend eine lange zahl steht 19830..... irgendwie so.
Wenn alle Deine Versuche ins Leere laufen und angeblich auch keine Stati ausgegeben werden: Wird der Code ausgeführt?
Daß in hFile eine Zahl drin steht: Das ist der Datei-Handler, unter dem im System jetzt die geöffnete Datei registriert ist.

Es könnte an Deinem Write liegen:
Code:
30: (* Schreiben in die Datei *)
    fwrite.hFile:=hFile;
    fwrite.pBuffer:=ADR(sStringToWrite);
    fwrite.szSize:=LEN(sStringToWrite);
    fwrite.udiTimeOut:=100000; //Timeout
    fwrite( xExecute:=TRUE);
    IF fwrite.xDone THEN
        fwrite( xExecute:=FALSE);
        writeIndex:=writeIndex+1;
        IF writeIndex <= 4 THEN
            uiStpDataLogger:=20;
            sStringToWrite:='';
        ELSE
            uiStpDataLogger:=40;
        END_IF
    END_IF
    IF fwrite.xError THEN
        //Error
        uiStpDataLogger:=16#DEADBEEF;
    END_IF

Den solltest Du mal wie folgt ändern und dann testen:

Code:
30: (* Schreiben in die Datei *)
    fwrite.hFile:=hFile;
    fwrite.pBuffer:=ADR(sStringToWrite);
    fwrite.szSize:=LEN(sStringToWrite);
    fwrite.udiTimeOut:=100000; //Timeout
    fwrite( xExecute:=TRUE);
    uiStpDataLogger := 31;
    
31:
    fwrite( xExecute:=FALSE);
    IF fwrite.xDone THEN
        writeIndex:=writeIndex+1;
        IF writeIndex <= 4 THEN
            uiStpDataLogger:=20;
            sStringToWrite:='';
        ELSE
            uiStpDataLogger:=40;
        END_IF
    END_IF
    IF fwrite.xError THEN
    //Error
        uiStpDataLogger:=16#DEADBEEF;
    END_IF

Meistens dürfen die Funktionen keinen Dauer-True haben, weil sie sonst immer wieder neu anfangen. Also nur mit Execute = True anstoßen und danach nur noch mit FALSE aufrufen, bis sie fertig sind.
Das Gleiche würde ich auch mal beim Öffnen und Schließen machen.

Und bei Deinem Error-Handling: Ich würde grundsätzlich immer über fClose gehen, selbst bei Fehler. Ist nicht schön, wenn da offene Dateien im System rumhängen.

Und irgendeinen Status solltest Du eigentlich rausbekommen... Wenn Du eine offene Datei hast (hFile <> 0), dann solltest Du die auch sehen können. Selbst als offene und leere Datei.
 
Hab das wie folgt geändert damit er nicht beim der 31 immer hängen bleibt.
30: (* Schreiben in die Datei *) fwrite.hFile:=hFile; fwrite.pBuffer:=ADR(sStringToWrite); fwrite.szSize:=LEN(sStringToWrite); fwrite.udiTimeOut:=100000; //Timeout fwrite( xExecute:=TRUE); uiStpDataLogger := 31; 31: fwrite( xExecute:=TRUE); IF fwrite.xDone THEN writeIndex:=writeIndex+1; IF writeIndex <= 4 THEN uiStpDataLogger:=20; sStringToWrite:=''; fwrite( xExecute:=FALSE); ELSE uiStpDataLogger:=40; END_IF END_IF IF fwrite.xError THEN //Error uiStpDataLogger:=16#DEADBEEF; END_IF

Trotz dessen passiert echt nichts im Ordner temp. Auch wenn ich über den Pfad /home/pi/C:/temp/TestFile.csv gehe.
Mich wundert einfach das beim User Wollvieh das Programm läuft, aber ich komm einfach nicht drauf warum bei mir nicht...
Hab selbst das aktuellste codesys geladen und es ausgeführt und es passiert nichts.

Könntest du mich aufklären was zb hfile[0] oder hfile[xxxxx] bedeutet ? würde gern wissen was es mit aufsich hat falls das eine beliebig große Zahl drin steht oder null.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hab das wie folgt geändert damit er nicht beim der 31 immer hängen bleibt.
30: (* Schreiben in die Datei *) fwrite.hFile:=hFile; fwrite.pBuffer:=ADR(sStringToWrite); fwrite.szSize:=LEN(sStringToWrite); fwrite.udiTimeOut:=100000; //Timeout fwrite( xExecute:=TRUE); uiStpDataLogger := 31; 31: [B] [/B][COLOR=rgb(226, 80, 65)][B]fwrite( xExecute:=TRUE);[/B][/COLOR] IF fwrite.xDone THEN writeIndex:=writeIndex+1; IF writeIndex <= 4 THEN uiStpDataLogger:=20; sStringToWrite:=''; fwrite( xExecute:=FALSE); ELSE uiStpDataLogger:=40; END_IF END_IF IF fwrite.xError THEN //Error uiStpDataLogger:=16#DEADBEEF; END_IF
Jetzt rufst Du ja fWrite doch immer wieder mit True auf. Ausschließlich in Schritt 30... und dann sofort auf 31 wechseln und nur noch mit False aufrufen!

Trotz dessen passiert echt nichts im Ordner temp. Auch wenn ich über den Pfad /home/pi/C:/temp/TestFile.csv gehe.
Was soll das denn für ein Ordner sein? Entweder sind wir auf Linux, dann bist Du im Home-Ordner oder wir sind auf Windows, dann bist Du auf C:

Könntest du mich aufklären was zb hfile[0] oder hfile[xxxxx] bedeutet ? würde gern wissen was es mit aufsich hat falls das eine beliebig große Zahl drin steht oder null.
Das Betriebssystem (nicht CoDeSys) verwaltet die Dateizugriffe.
FOpen fordert das Öffnen einer Datei an. Das macht jetzt das Betriebssystem und gibt einen Datei-Handle zurück. Den merkt sich fOpen und übergibt ihn Dir, damit Du damit dann weiterarbeiten kannst. Jede Funktion, die jetzt was mit der Datei machen möchte, benötigt diesen Handle. Und das ist die "beliebig große Zahl". Einfach nur eine ID, damit das Betriebssystem weiß, um welche Datei es geht.
 
Das mit dem fwrite ist abgeändert, ich probieren da einfach aus damit er mir hauptsache diese Datei erstellt.
Fürs Verständnis ist es ja recht egal was er im fwrite macht, die Datei wird einfach nicht erstellt, dass geschieht ja nur im fopen Sektor und das mit dem Pfad hab ich jegliches ausprobiert egal ob /home/pi/temp/Testfile.csv oder C:/temp/Testfile.csv oder das im vorherigen
Post. Er macht rein gar nichts, dass ist ja mein größtes Problem, er erzeugt einfach keine Datei egal wie ich es mache. Er erzeugt selbst keine Datei wenn ich ein Beispielprogramm ausführe. Egal was ich ausprobiere ich verzweifle da langsam dran.
 
Dann überspring doch das Schreiben mal. Nur Öffnen (da bekommst Du ja ein Handle) und Schließen.
Und gucken, ob die Schrittkette fehlerfrei durchläuft. Kannst Du auch Debuggen.

Gibt es bei fOpen einen Modus "Write" oder "Append"? Manchmal gibt es einen Modus, der öffnet nur vorhandene Dateien, ein anderer erstellt sie neu. Ich sehe sowas bei Dir nicht.

Wie ist der Datentyp CAA aufgebaut? Ich habe schon Strukturen gesehen, da übergibt man den Pfad und den Dateinamen einzeln, z.B.:
Code:
sFileName.FILENAME  := 'Test.txt';
sFileName.PATH        := 'C:\';
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier mal ein File Zugriff vom Raspi :

Bausteinkopf _
Code:
PROGRAM Read_Write_plc_data
VAR
  bReadAtSystemStart  : BOOL;
  bWrite              : BOOL;
  bRead               : BOOL;
  handleFile          : DWORD;
  handleFileInternal  : DWORD;
  FilePathAndName     : STRING    :=        '/home/pi/Downloads/SystemData.dat';
  fopen               : FILE.Open;
  fwrite              : file.Write;
  fread               : file.Read;
  fclose              : file.Close;
  readwritestep       : INT;
  WriteFlag           : R_TRIG;
  ReadFlag            : R_TRIG;
  ReadAtSysStartFlag  : R_TRIG; 
  FileModeInternal    : INT;
  berror              : BOOL;
  bok                 : BOOL;
  tstart , tend, tdur : TIME;
END_VAR

Anweisungen dazu :
Code:
// read at Systemstart
IF NOT bReadAtSystemStart
THEN
  bReadAtSystemStart := TRUE;
END_IF



 // Dynamisierung 
WriteFlag(CLK:= bWrite , Q=> ); 
ReadFlag (CLK:= bRead  , Q=> ); 
ReadAtSysStartFlag(CLK:= bReadAtSystemStart , Q=> );

// fb for fileopen
 fopen(
   xExecute:=,
   xDone=> ,
   xBusy=> ,
   xError=> ,
   sFileName:= FilePathAndName,
   eFileMode:= FileModeInternal,
   xExclusive:= ,
   eError=> ,
   hFile=> handleFile);
// fb for filewrite
fwrite(
   xExecute:= ,
   xAbort:= ,
   udiTimeOut:= ,
   xDone=> ,
   xBusy=> ,
   xError=> ,
   xAborted=> ,
   hFile:= handleFileInternal,
   pBuffer:= ADR(SystemData),
   szSize:=   SIZEOF(SystemData) ,
   eError=> );
// fb for fileread
fread(
    xExecute:= ,
    xAbort:= ,
    udiTimeOut:= ,
    xDone=> ,
    xBusy=> ,
    xError=> ,
    xAborted=> ,
    hFile:= handleFileInternal,
    pBuffer:=  ADR(SystemData),
    szBuffer:= SIZEOF(SystemData) ,
    eError=> ,
    szSize=> );
// fb for fileclose
fclose(
   xExecute:= ,
   xDone=> ,
   xBusy=> ,
   xError=> ,
   hFile:= handleFileInternal,
   eError=> );
  


// Sequence for write / read / file

 
CASE readwritestep OF
  0 : IF WriteFlag.Q THEN readwritestep := 10;  FileModeInternal := FILE.MODE.MWRITE; tstart := TIME();  END_IF
      IF ReadFlag.Q  OR ReadAtSysStartFlag.Q THEN readwritestep := 50;  FileModeInternal :=  FILE.MODE.MREAD; tstart := TIME(); END_IF
       fopen.xExecute  := FALSE;
       fwrite.xExecute := FALSE;
       fclose.xExecute := FALSE;
       tdur := tend-tstart;
      
 10 : bok    := FALSE;
      berror := FALSE;
      fopen.xExecute := TRUE;
      readwritestep      := 11;
      
 11 : IF fopen.xDone = FALSE THEN readwritestep      := 12;     END_IF
 
 12 : IF fopen.xDone = TRUE AND fopen.xError = FALSE THEN  handleFileInternal:= handleFile ;  readwritestep := 13;  END_IF
      IF fopen.xError = TRUE THEN  readwritestep := 110;  END_IF
      
 13 : fopen.xExecute := FALSE;
      IF fopen.xDone = FALSE THEN readwritestep      := 20;     END_IF
 

 
 20:   fwrite.xExecute := TRUE;
      
      IF fwrite.xDone = TRUE AND fwrite.xError = FALSE THEN  readwritestep := 30;  END_IF
      IF fwrite.xError = TRUE THEN  readwritestep := 120;  END_IF
      
 30 : fwrite.xExecute := FALSE;
      fclose.xExecute := TRUE;
        
      IF fclose.xDone = TRUE AND fclose.xError = FALSE THEN  readwritestep := 0; bWrite:= FALSE;  bok    := TRUE;  tend := TIME(); END_IF
      IF fclose.xError = TRUE THEN  readwritestep := 130;  END_IF

      
    
 50 : bok    := FALSE;
      berror := FALSE;
      fopen.xExecute := TRUE;
      readwritestep      := 51;
      
 51 : IF fopen.xDone = FALSE THEN readwritestep      := 52;     END_IF
 
 52 : IF fopen.xDone = TRUE AND fopen.xError = FALSE THEN  handleFileInternal:= handleFile ;  readwritestep := 53;  END_IF
      IF fopen.xError = TRUE THEN  readwritestep := 110;  END_IF
      
 53 : fopen.xExecute := FALSE;
      IF fopen.xDone = FALSE THEN readwritestep      := 60;     END_IF
 
 
 60:   fread.xExecute := TRUE;
      
      IF fread.xDone = TRUE AND fread.xError = FALSE THEN  readwritestep := 61;  END_IF
      IF fread.xError = TRUE THEN  readwritestep := 120;  END_IF
      
 61 : fread.xExecute := FALSE;
      fclose.xExecute := TRUE;
        
      IF fclose.xDone = TRUE AND fclose.xError = FALSE THEN  readwritestep := 0; bRead:= FALSE;   bok    := TRUE;  tend := TIME();   END_IF
      IF fclose.xError = TRUE THEN  readwritestep := 130;  END_IF

 
      
      
      
      
100,110,120 : // some error occured
      berror         := TRUE;
      fopen.xExecute := FALSE;
      fwrite.xExecute := FALSE;
      fread.xExecute := FALSE;
      fclose.xExecute := FALSE;
      IF State.In.Quit     
      THEN
        readwritestep := 0;
         berror       := FALSE;
      END_IF
END_CASE;


Beispielstruct dazu :

Code:
TYPE SystemDataStruct :
STRUCT
    valueReal   : REAL;
    valueDint   : DINT;
    valueString : STRING;
    bool1       : BOOL;
    bool2       : BOOL;
END_STRUCT
END_TYPE

GVL dazu :
Code:
VAR_GLOBAL
    SystemData : SystemDataStruct;
END_VAR

Viel Spaß bei Studieren und schönes Wochenende !
 
Das mit dem sFileName.Path gibt es glaub ich nicht, so wie es aussieht geht es nur über sFileName:CAA.FILENAME:='xxx';
ich fang den Spaß mal von vorne nach hinten an heute Abend.
Das muss ja irgendwie funktionieren das er mir einfach eine Datei erzeugt ohne dort etwas hinein zu schreiben erstmal.
 
Du scheinst beratungsresistent. Der gepostete Code läuft seit Monaten auf 2 Raspis ohne Probleme.
Gruß vom Wollvieh.
 
Zurück
Oben