Zahl wird aufaddiert obwohl IF Bedingung nicht aktiv ist

micha1983
2010-02-27
2010-02-28
  • micha1983 - 2010-02-27

    Hallo liebes Forum,

    ich mach gerade meine ersten Gerversuche mit ST in Codesys.

    ich bin dabei ein Array of Byte mit auf asci Zeichen zu durchsuchen

    dafür habe ich folgenden Code erstellt

    FOR I:=0 TO size DO
       IF PT^[I]=13 OR PT^[I] = 10 THEN
           zahl:=zahl +1;
       END_IF
       IF zahl = 52 THEN
          anfang:= PT^[I-1];
          feld_anfang:=I;
          zahl_anfang:=zahl;
       END_IF
       IF zahl = 53 THEN
          ende:= PT^[I-1];
          feld_ende:=I;
          zahl_ende:=zahl;
       END_IF
    END_FOR
    

    Jetzt habe ich nur ein Problem:

    Die For-Schleife wird ordnungsgemäß durchlaufen, allerding wird obwohl die For-schleife schon fertig ist der Int "zahl" zwischen der If Abfrage

    IF PT^[I]=13 OR PT^[I] = 10 THEN
           zahl:=zahl +1;
       END_IF
    

    weiterhin aufaddiert und fängt deswegen natürlich nach einem Überlauf wieder von Vorne an.

    Kann mir jemand helfen, warum "zahl" weiterhin aufaddiert wird?

    Vielen Dank.

    Ich sehr hier nämlich keinen Fehler!

    Gruß Michael

     
  • Oberchefe - 2010-02-28

    I kann doch nicht gleichzeitig Dein Pointer und Dein Schleifenzähler sein. Wenn das Array vorher schon festgelegt ist sollte das eher so aussehen:

    FOR I:=0 TO size DO
       IF MeinArray[I]=13 OR MeinArray[I] = 10 THEN
           zahl:=zahl +1;
       END_IF
       IF zahl = 52 THEN
          anfang:= MeinArray[I-1];
          feld_anfang:=I;
          zahl_anfang:=zahl;
       END_IF
       IF zahl = 53 THEN
          ende:= MeinArray[I-1];
          feld_ende:=I;
          zahl_ende:=zahl;
       END_IF
    END_FOR 
    
     
  • micha1983 - 2010-02-28

    Hallo danke.

    Aber I ist doch nicht mein Pointer sondern PT und I ist mein Schleifenzähler.

    Oder stehe uch auf der Leitung?

    Danke

    Gruß Michael

     
  • Pitsch - 2010-02-28

    Hallo

    Leider ist aus Deinem Posting nicht ersichtlich, wie Dein Array definiert ist (ich nehme mal an, es ist ein Pointer-Array), was size ist und was Du da eigentlich genau überprüfst.

    Ausserdem wird eine Schleife pro Zyklus vollständig durchlaufen. So wie es aussieht, stimmt eben der Vergleich in jedem Zyklus, um den IF -> End_If Rumpf zu verarbeiten.

    Wenn während des Zykluses der wert in dem durch den Pointer referenzierten Speicherbereich nicht ändert, dereferenziert eben jeder Zyklus, immer wieder den gleichen Feld-Inhalt. Somit wird die Zahl auch weiter hochgezählt, bis eben ein anderer Wert dereferenziert wird. dieser Wert ändert sich sehr wahrscheinlich nicht.

    Du müsstest eher definieren(auch mit einen If-Anweisung), ob die Schleife durchlaufen werden soll oder nicht. Eventuell mit einer Flanken-Triggerung oder dergleichen.

    Mit freundlichen Grüssen! Pitsch

     
  • micha1983 - 2010-02-28

    Hallo vielen Dank.

    Das mit der Flankentriggerung habe ich auch schon überlegt.

    ich poste mal den kompletten FB, damit man sich einen überblick verschaffen kann.

    FUNCTION_BLOCK string_auslesen
    VAR_INPUT
       PT: POINTER TO ARRAY [0..   MAX_RECEIVE_TCP_CLIENT] OF BYTE;
       size: INT;
    END_VAR
    VAR_OUTPUT
       anfang: BYTE;
       ende: BYTE;
       feld_anfang:INT;
       feld_ende:INT;
       zahl_anfang:INT;
       zahl_ende:INT;
    END_VAR
    VAR
       I:INT:=0;
       zahl: WORD:=0;
    END_VAR
    
    FOR I:=0 TO size DO
       IF PT^[I]=13 OR PT^[I] = 10 THEN
           zahl:=zahl +1;
       END_IF
       IF zahl = 52 THEN
          anfang:= PT^[I-1];
          feld_anfang:=I;
          zahl_anfang:=zahl;
       END_IF
       IF zahl = 53 THEN
          ende:= PT^[I-1];
          feld_ende:=I;
          zahl_ende:=zahl;
       END_IF
    END_FOR
    

    Der Baustein bekommt bei "PT" die Adresse eines Arrays of Byte. Dieses Array ist 4000 Byte lang, allerdings nur bis zum Feld "size" gefüllt.

    Jedes Byte beinhaltet den ASCI Code eines Zeichnes einer Datei.

    Ich will jetzt das Array auf Zeilenumbrüche durchsuchen und mit einige Zeilen später dann ausgeben.

    => Deswegen der Zähler "zahl" dieser soll mir die gefundenen Zeilenumbrüche herausfiltern und das Startfeld und Endefeld der z.B. 54. zeile ausgeben.

    Damit ich nicht das Array durchsuchen muss, wollte ich eben die Suche auf die gefüllten Zellen des Arrays begrenzen indem ich nur bis "size" durchsuche.

    Ich versuche es jetzt mal mit einer Triggerflanke, allerdings wollte ich später dann nur immer "I" auf 0 zurücksetzen damit es wieder durchlaufen wird.

    Mich wundert halt nur, das die Forschleife weiter durchlaufen wird obwohl bereits "I" = "size" ist.

    Vielen dank für eure Unterstützung.

    Gruß Michael

     
  • Pitsch - 2010-02-28

    Hallo

    I ist im nächsten Zyklus, da die Schleife wieder von vorne beginnt, natürlich wieder null! Dein Problem, ist wirklich nur, Du vergisst, dass ein SPS-Programm Zyklisch abgearbeitet wird. Das kannst Du nicht mit einem Komputerprogramm z.B. VB oder VBA vergleichen.

    Vielleicht hilft es ja, wenn Du im Codeteil, in der ersten Zeile die Variable Zahl auf null setzst.

    Zahl := 0;
    FOR I:=0 TO size DO
    (*etc.*)
    

    Mit freundlichen Grüssen! Pitsch

     
  • micha1983 - 2010-02-28

    Stimmt ich bin die ganze zit davon ausgegangen, dass I erst wieder auf 0 gesetzt wird wenn ic es auf 0 setze.

    Vielen dank für die Erklärung.

    Gruß Michael

     

Log in to post a comment.