codesys v3 csv Datei einlesen und verarbeiten

cobra123

Level-1
Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen, ich bin dabei mich in die Programmiersprache strukturierter Text einzuarbeiten und habe dabei folgendes Problem.

Ich möchte mit Codesys V3 eine CSV Datei einlesen und verarbeiten. Die Datei soll aus drei Spalten bestehen (Index, Zeit, Spannung) die jeweils durch ein Trennzeichen getrennt werden. Mit Hilfe des Trennzeichen möchte ich erkennen zu welchen dieser drei Kategorien die Zeichen gehören.
Beim einlesen möchte ich die Zeichen einzeln einlesen und anschließend in einem weiteren String wieder zusammen fügen. Das einlesen klappt soweit, allerdings funktioniert das zusammensetzen mit dem Befehl "CONCAT(x ,y)" der beiden STRINGs nicht. Mein Problem hierbei ist das ich online sehe dass die einzelnen Zeichen eingelesen werden allerdings werden diese nicht wie gewünscht zusammen gesetzt.

Mein Programm sieht wie folgt aus:

PROGRAM PLC_PRG
VAR
myTON : TON;
SysFileOpenNum : DWORD;
FileName : STRING := 'C:\CoDeSysCSV.csv';
ReadBuffer : STRING;
Buffer : STRING;
pResult : WORD;
pResult_1 : WORD;
DwWritten : DWORD;
myCount : INT;
END_VAR



myTON(IN:=NOT myTON.Q, PT:=T#1S); (* Sekunden oszi *)
IF myTON.Q THEN

CASE myCount OF
0: SysFileOpenNum := SysFileOpen(FileName, am:= ACCESS_MODE.AM_READ, pResult:= pResult);

1..20: ReadBuffer := ' ';
Buffer := CONCAT(Buffer ,ReadBuffer); // In ReadBuffer sind die einzelnen Zeichen zu sehen aber im Buffer wird nichts geschrieben
DwWritten := SysFileRead(SysFileOpenNum, ADR(ReadBuffer), LEN(ReadBuffer), pResult:= pResult_1);

21: SysFileClose(SysFileOpenNum);

END_CASE

IF myCount < 22 THEN
myCount := myCount + 1;
END_IF;
END_IF
 
Hi,
am besten nimmst du für den ReadBuffer ein array of Byte dann kannst du mit einer Schleife das array durchlaufen und auf die Trennzeichen reagieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo lord2k3,

Vielen Dank für die schnelle Antwort.

Das ist leider nicht ganz das was ich wissen wollte, aber danke für den Tipp (Die Auswertung der Trennzeichen habe ich noch nicht versucht).

Ich kann die Zeichen aus der Datei lesen diese werden im "ReadBuffer" nacheinander angezeigt allerdings werden diese nicht in "Buffer" übernommen woran kann dies liegen?

anbei ein Bild im Online Modus ich hoffe das verdeutlicht mein Problem.

Datei lesen.jpg
 
Hallo,
du musst das Zusammensetzen nach dem Lesen ausführen.
Bei deinem aktuellen Code ist der ReadBuffer beim Zusammensetzen leer initialisiert.

Versuchs mal so:

ReadBuffer := ' ';
DwWritten := SysFileRead(SysFileOpenNum, ADR(ReadBuffer), LEN(ReadBuffer), pResult:= pResult_1);
Buffer := CONCAT(Buffer ,ReadBuffer);


Gruß
 
ich vermute du bekommst in der Onlineansicht "Der Wert des Ausdrucks kann nicht gelesen werden" angezeigt. Korrekt? Oder hat "????"

Das ist ein Problem wenn der keine Termininierung am Ende findet. Ist mir neulich auch passiert.

Hier ein Beispiel (noch nicht fertig) wie ich CSV einlese:

ACHTUNG: Die Abbruchbedingung ist noch nicht gut mit dem "bNewLineFound", es besteht noch ein Risiko einer Endlosschleife. Es handelte sich hierbei nur um eine schnelle Lösung was zu testen, vielleicht hilft dir das so schon mal weiter.
Es funktioniert auch nur wenn deine Zeilen immer <255 Zeichen sind sonst gibt's ein Problem und $R wird nicht gefunden.

Code:
PROGRAM PRG_CSVREAD
VAR
 strParameterFile : STRING(80) := 'EPCO.csv';
 iStep : INT := 0;
  
 rtsHandle : CmpErrors.RTS_IEC_HANDLE;
 rtsResult : CmpErrors.RTS_IEC_RESULT;
 iBytesRead : UDINT := 0;
 
 strLineBuffer : STRING(255) := '';
 strPNU : STRING(20) := '';
 strSubindex : STRING(20) := '';
 strDataType : STRING(20) := '';
 strValue : STRING(30);
 iNewLinePosition : INT := 0;
 iReadStartPosition : INT := 0;
 iReadEndPosition : INT := 0;
 iReadPosInFile : DINT := 0;
 bNewLineFound : BOOL := FALSE;
// byLineBuffer : ARRAY [0..200] OF BYTE;


 
END_VAR





rtsHandle := file.SysFileOpen(
    szFile := strParameterFile,
    am := file.AM_READ,
    pResult := ADR(rtsResult)
   );


bNewLineFound := TRUE;
WHILE bNewLineFound DO
  
 // Datei einlesen   
 iBytesRead := file.SysFileRead(
      hFile := rtsHandle, 
      pbyBuffer := ADR(strLineBuffer), 
      ulSize := SIZEOF(strLineBuffer),
      pResult := ADR(rtsResult)
     ); 
 iNewLinePosition := FIND(strLineBuffer, '$R'); 
 IF iNewLinePosition = 0 THEN
  bNewLineFound := FALSE;
  EXIT;
 END_IF;
  
 IF iNewLinePosition > 0 THEN
  strLineBuffer := MID(strLineBuffer, iNewLinePosition,1);
  
  iReadStartPosition := 1;
  iReadEndPosition := FIND(strLineBuffer,',');
  strPNU := MID(strLineBuffer, iReadEndPosition - iReadStartPosition, iReadStartPosition);
  strLineBuffer := MID(strLineBuffer,LEN(strLineBuffer),iReadEndPosition+1 );
  
  iReadStartPosition := 1;
  iReadEndPosition := FIND(strLineBuffer,',');
  strSubindex := MID(strLineBuffer, iReadEndPosition - iReadStartPosition, iReadStartPosition);
  strLineBuffer := MID(strLineBuffer,LEN(strLineBuffer),iReadEndPosition+1 );
  
  iReadStartPosition := 1;
  iReadEndPosition := FIND(strLineBuffer,',');
  strDataType := MID(strLineBuffer, iReadEndPosition - iReadStartPosition, iReadStartPosition);
  strLineBuffer := MID(strLineBuffer,LEN(strLineBuffer),iReadEndPosition+1); 
  
  iReadStartPosition := 1;
  iReadEndPosition := FIND(strLineBuffer,'$R');
  strValue := MID(strLineBuffer, iReadEndPosition - iReadStartPosition, iReadStartPosition);
  strLineBuffer := MID(strLineBuffer,LEN(strLineBuffer),iReadEndPosition+1 );
  
  
     
 END_IF;
 iReadPosInFile := iReadPosInFile + iNewLinePosition+1;
 // Leseposition auf Anfang setzen
 file.SysFileSetPos(
  hFile := rtsHandle,
  ulOffset := iReadPosInFile
 );
END_WHILE
    
file.SysFileClose(rtsHandle);
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@ghosty wenn ich das Zusammensetzen verschiebe funktioniert es.

@excelite es wird leider keine Meldung angezeigt.

Den angefügten Programmcode kann ich leider nicht ausführen da folgende Fehlermeldung angezeigt wird: "Bezeichner 'file' nicht definiert" . Meine Versuche file zu deklarieren sind leider gescheitert. Wie muss 'file' definiert werden?
 
Das ist ein Namespace, kein Bezeichner. Musst im Blibiotheksmanager schauen wie deine Syslibfile Lib eingebunden ist. Da steht dann der Namespace dran.
 
Hallo cobra,
freut mich wenn es funktioniert.
Vielleicht noch eine kurze Anmerkung. Ich würde bei der Programmierung von SPS-Steuerungen versuchen, möglichst auf While-Schleifen zu verzichten.
Du hast hier einen Task mit festem Zeitraster. In diesem Zeitraster muss dein Programm abgearbeitet werden. Ansonsten wirst du Probleme mit Zykluszeitüberschreitungen bekommen.
Bei While-Schleifen kannst du nie wissen wie lange diese zur Abarbeitung brauchen. Im schlechtesten Fall wird deine Schleife nie beendet.
 
Zurück
Oben