TIA Signalflanke erkennen und inkrementieren: Programm läuft in einem anderen Projekt nicht.

Beiträge
110
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe ein Problem zum folgenden Code:
Code:
#Counter := 0; // Zähler auf 0 setzen

IF "S4" = FALSE AND #Schritt = 5 THEN
    // Positionier Einstellung setzen und Bewegung ausführen solange die Bedingungen erfüllt sind
    IF #Counter < 10 THEN
        // Anfahrpositionen
        "Motor_DB".Position := INT_TO_DWORD(#Counter * 100 + 200);
        // Starten
        #Start_3 := FALSE;
        "IEC_Timer_0_DB".TP(IN := "sensor",
                            PT := T#500ms,
                            Q => #Start);
        // Positive Signalflanke erkennen
        "R_TRIG_DB_1"(CLK:="sensor",
                      Q=>#pos_trig_1);
        // Zähler inkrementieren
        IF #pos_trig_1 = TRUE THEN
            #Counter += 1;
        END_IF;
    END_IF;
ELSE
    #Counter := 0;
    #Start := FALSE;
END_IF;
  • Die Bedingungen "S4" ist FALSE.
  • Wenn diese Bedingung erfüllt ist, wird Folgendes ausgeführt:
    • Überprüfung, ob der Wert von #Counte kleiner als 10 ist.
    • Setzen der Anfahrposition "Motor_DB".Position basierend auf dem Zählerwert.
    • Setzen des Startbefehls #Start für die Bewegung mit einem Impuls von 500ms.
    • Erkennen der positiven Signalflanke "pos_trig_1" basierend auf "sensor".
    • Inkrementieren des Zählers #Counter, wenn die positive Signalflanke erkannt wird.
Ich habe dieses SCL-Programm entwickelt, das ursprünglich einwandfrei funktioniert hat. Jedoch habe ich festgestellt, dass es nach dem Kopieren in ein anderes Projekt nicht mehr wie erwartet läuft. Insbesondere wird der Zähler nicht mehr inkrementiert. Es scheint ein Problem mit der Flankenerkennung zu geben, aber woran genau könnte das liegen? Ich bitte um Tipps. Bitte bescheid geben wenn mehre Informationen benötigt werden. Danke
 
Für welche SPS-CPU war das original-Programm, für welche CPU das kopierte Programm? Getestet auf echter CPU oder PLCSIM?
Welche TIA Version?

Wenn "sensor" schon True ist, bevor der Code ausgeführt wird, dann kann und wird es Probleme mit dem Timer TP und der Flanken Erkennung geben. Ganz schlechte Logik! Wenn das Programm "ohne Probleme" lief, dann hast Du einfach nur Glück gehabt. Merke: Timer und Flanken-Erkennung nicht bedingt (in If-Zweigen) ausführen, sondern immer (in jedem Zyklus).

Bool-Ausdrücke braucht man nicht mit TRUE oder FALSE vergleichen, der Ausdruck ist ja schon Bool und kann direkt bei z.B. IF verwendet werden.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe dieses SCL-Programm entwickelt
Warum hast Du es in SCL entwickelt? Wenn Du das Logik-lastige Programm in für Logik-Probleme besonders geeigneten Programmiersprachen wie KOP oder FUP entwickelt hättest, dann würde das Programm ziemlich sicher besser funktionieren. KOP/FUP Programme machen viele Dinge richtig, wo der Programmierer noch nicht mal ahnt, daß er eigentlich nicht genug Ahnung hat...

Harald
 
Motor ist so cool in Kyrillisch...
:cool: 😁


Dies:

dagegen weniger. 🙄


Sorry für den OT. 🤷‍♂️
Wie sollte ich das denn am besten ausdrücken?
Für welche SPS-CPU war das original-Programm, für welche CPU das kopierte Programm? Getestet auf echter CPU oder PLCSIM?
Welche TIA Version?

Wenn "sensor" schon True ist, bevor der Code ausgeführt wird, dann kann und wird es Probleme mit dem Timer TP und der Flanken Erkennung geben. Ganz schlechte Logik! Wenn das Programm "ohne Probleme" lief, dann hast Du einfach nur Glück gehabt. Merke: Timer und Flanken-Erkennung nicht bedingt (in If-Zweigen) ausführen, sondern immer (in jedem Zyklus).

Bool-Ausdrücke braucht man nicht mit TRUE oder FALSE vergleichen, der Ausdruck ist ja schon Bool und kann direkt bei z.B. IF verwendet werden.

Harald
Beide Projekte wurden auf derselben CPU getestet. Nun habe ich ein neues Projekt erstellt, in dem ich nur einen bestimmten Teil der Maschine testen möchte. Da ich noch ein Anfänger im SPS Programmieren bin, fehlt es mir an Erfahrung, um das Problem besser zu lösen. Für geeignete Beispiele wäre ich dankbar.
Mehrfach verwendet im Projekt?
Tatsächlich hatte ich das mehrfach verwendet. Aber auch nach dieser Anpassung, gab es keine Verbesserung.
Warum hast Du es in SCL entwickelt? Wenn Du das Logik-lastige Programm in für Logik-Probleme besonders geeigneten Programmiersprachen wie KOP oder FUP entwickelt hättest, dann würde das Programm ziemlich sicher besser funktionieren. KOP/FUP Programme machen viele Dinge richtig, wo der Programmierer noch nicht mal ahnt, daß er eigentlich nicht genug Ahnung hat...

Harald
SCL erscheint mir deutlich einfacher als KOP oder FUP und ganz besonders wenn man auch nur eine Rechnung hat. Ich finde auch, dass es übersichtlicher aussieht. Bei FUP sieht es immer ungeschickt aus, wenn man mehrere Ausgänge in einem Netzwerk hat. Bei SCL kommt mir das unproblematisch vor. Deshalb habe ich mich an SCL gewöhnt. Aber wenn du sagst, dass es mit FUP funktionieren wird, werde ich es umändern. Teilen die anderen diese Meinung übrigens auch?

Danke für die Tipps bisher.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Deshalb habe ich mich an SCL gewöhnt. Aber wenn du sagst, dass es mit FUP funktionieren wird, werde ich es umändern. Teilen die anderen diese Meinung übrigens auch?
Für Suppe die Gabel, weil man sich dran gewöhnt hat?
Für Fleisch 'nen Löffel, weil man den Umgang damit als erstes gelernt hat?

Für jede Aufgabe das (vorhandene) Werkzeug verwenden, das dafür am besten geeignet ist!
;)


PS:
Neue Siemens-CPUen lassen mittlerweile auch einen Mix aus SCL und FUP/KOP in einem Baustein zu.
:cool:
 
Gibt es noch mehr Sachen, die mehrfach verwendet wurden? Der RTRIG_DB z.b.?

Die Hinweise aus Beitrag #4 gelesen?
Ich habe extra "R_TRIG_DB_1" neu erstellt und alles andere wurde auch nur einmal verwendet. Ich habe auch Beitrag #4 gelesen, aber ich bin mir nicht sicher, wie ich mein Programm entsprechend anpassen kann. Insbesondere verstehe ich nicht, wie er das hier beschrieben hat und wie man das machen soll: "Timer und Flankenerkennung nicht bedingt (in If-Zweigen) ausführen, sondern immer (in jedem Zyklus)."
 
Warum gibts eigentlich das IF #Counter < 10 THEN ... in Deinem Code, wenn doch #Counter direkt davor in jedem Zyklus immer wieder bedingungslos auf 0 gesetzt wird?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Flanken, also Änderungen des Zustands eines Signals zu erkennen, ist im Prinzip sehr simpel. Man muss lediglich den aktuellen Zustand mit dem "vorherigen" Zustand vergleichen.

Ändert sich der Zustand von FALSE auf TRUE (alias von LOW auf HIGH oder 0 auf 1), spricht man von einer positiven Flanke.
Code:
posFlanke := NOT vorherigerZustand AND aktuellerZustand ;
Ändert sich der Zustand von TRUE auf FALSE (alias von HIGH auf LOW oder 1 auf 0), spricht man von einer negativen Flanke.
Code:
negFlanke := vorherigerZustand AND NOT aktuellerZustand ;
Manchmal will man jede Flanke erhaschen und muss dabei nicht unterscheiden, ob es gerade eine positive oder eine negative Flanke ist.
Dann kann man einfacher ...
Code:
jedeFlanke := vorherigerZustand XOR aktuellerZustand ;
... schreiben.
Sooo, zum Abschluss müssen wir noch dafür sorgen, dass eine Kopie des jetzt noch aktuellen SignalZustands abgespeichert wird, damit sie beim nächsten Durchlaufen unserer FlankenErkennung betreffend dasselbe Signal als 'vorherigerZustand' zum Vergleich mit dem dann evtl. veränderten aktuellen Zustand zur Verfügung steht.
Code:
vorherigerZustand := aktuellerZustand ;
Diese Variable 'vorherigerZustand' wird häufig und durchaus zu Recht als 'FlankenMerker' bezeichnet. Denn 'Merker' heisst hier lediglich, dass das Programm sich darin eine Information merken muss und es darf selbstverständlich ein Bit aus einem DB sein.
Der FlankenMerker ist NICHT das Ergebnis der FlankenErkennung, sondern nur ein "im Untergrund" wirkendes HilfsMittel zur FlankenErkennung.
Erst der Vergleich zwischen dem aktuellen und dem vorherigen, im FlankenMerker gespeicherten Zustand, liefert das Ergebnis, nämlich einen "impulsartigen" TRUE-Zustand, der genau 1 Zyklus lang bestehen bleibt. Der Satz "Nach einem 1 Zyklus langen Impuls folgt immer eine mindestens 1 Zyklus lange ImpulsPause." gilt aber nur bei der Erkennung positiver oder negativer Flanken!
Sollen beliebige Flanken - egal, ob positiv oder negativ - also alle Flanken erkannt werden, so kann das Ergebnis in direkt aufeinander folgenden Zyklen den Zustand TRUE beibehalten, vorausgesetzt, das Signal wechselt wirklich in jedem Zyklus seinen Zustand!

Gaaanz wichtig:
Der Vergleich zwischen dem 'aktuellenZustand' und dem 'vorherigenZustand' kann nur dann sinnvolle Ergebnisse liefern, wenn der 'vorherigeZustand'
- erstens überhaupt 1 Zklus lang erhalten bleibt UND
- zweitens der dort gespeicherte Wert von keiner anderen ProgrammStelle überschrieben/verfälscht wird - auch nicht von derselben ProgrammStelle, die in einer anderen Instanz aktiv ist! Doppel- oder MehrfachBelegungen von Bits dürfen nicht vorkommen. Jede Instanz benötigt ein eigenes Bit.

Die als FlankenMerker benutzten Variablen dürfen NICHT temporär sein, sondern müssen statisch oder global sein, um lange genug ihren Inhalt behalten zu können. VAR_IN_OUT sind auch möglich, sofern diese auf statische oder DB-Bits zugreifen.

Warum sagt Harald ...
Merke: Timer und Flanken-Erkennung nicht bedingt (in If-Zweigen) ausführen, sondern immer (in jedem Zyklus).
Ganz einfach: die FlankenErkennung kann Flanken schlichtweg "übersehen", wenn sie nicht oft genug aufgerufen/durchlaufen wird.
Darum ruft man die FlankenErkennung grundsätzlich in jedem Zyklus auf und nicht nur gelegentlich, bei vermeintlich bestehendem Bedarf.
Wurde z.B. eine positive Flanke erkannt, so kann die nächste positive Flanke nicht erkannt werden, wenn das Lesen der dazwischenliegenden negative Flanke aus GesundSchrumpfungsEinsparGründen wegrationalisiert wird.
Natürlich kann man sich Gedanken darüber machen, ob wirklich immer in jedem Zyklus durchlaufen werden muss. Aber die zu investierende Gewissenhaftigkeit steht m.E. in keinem vernünftigen Verhältnis zum erwartbaren EinsparPotenzial. Und jeder, der später über solche Stellen im Programm stolpert, wird hier wieder viel Zeit verbraten, um entweder einen tatsächlichen Fehler endlich zu entlarven oder zum x-ten Male zu klären, dass die Bedenken wegen eines möglichen Fehlers gegenstandslos sind.

Oben habe ich nur selbstgemachte FlankenErkennungen gezeigt.
Es gibt (leider) auch die vorgefertigten FlankenErkennungen in diversen ProgrammierSprachen.
Das mag etwas für "Runaways" (= Fortgeschrittene) sein.
Anfänger müssen jedenfalls die Do-It-Yourself-FlankenErkennungen benutzen. Solange, bis sie ihre WirkungsWeise wirklich verstanden haben! 😇
Ob man dann wirklich noch einen Vorteil darin sieht, sich mit einer manchmal verwirrenden Vielfalt verschiedener, vorgefertigter FlankenErkennungen herumzuplagen ... na ja, lesen sollte man sie notfalls können. ;)

Ich habe dieses SCL-Programm entwickelt, das ursprünglich einwandfrei funktioniert hat. Jedoch habe ich festgestellt, dass es nach dem Kopieren in ein anderes Projekt nicht mehr wie erwartet läuft.
Das spricht wohl dafür, dass eine DoppelBelegung durch das Kopieren entlarvt wurde oder hinzugekommen ist, evtl. durch hinzugekommene Instanzen?
Vielleicht unterscheiden sich "Original und Fälschung" in einer oder mehreren VariablenDeklarationen?
 
Insbesondere verstehe ich nicht, wie er das hier beschrieben hat und wie man das machen soll: "Timer und Flankenerkennung nicht bedingt (in If-Zweigen) ausführen, sondern immer (in jedem Zyklus)."
Das Problem ist, dass die Beiden jeweils den Signalwechsel mitbekommen müssen. Dies ist meißt (und ganz sicher in deinem Fall) nicht so.
Wenn das Ding in einem IF-Konstrukt eingebaut ist und dieses dann irgendwann bearbeitet wird dann ist der Eingang wahrscheinlich statisch - aslo kein Wechsel - also keine Funktion ...
 
Das Problem ist, dass die Beiden jeweils den Signalwechsel mitbekommen müssen.
Den SignalWechsel? Wenn die Mimik z.B. nur die positiven Flanken detektieren soll, dann muss sie auch die negativen Pegel bzw. die negativen Flanken zwischen den eigentlich interessierenden positiven Flanken sehen dürfen und können.
Alle SignalWechsel müssen von der Mimik gesehen werden können, wenn sichergestellt werden soll, dass keine interessierende Flanke übersehen wird.
Ich stelle mir das immer als Stroboskop(-Effekt) vor, wenn es darum geht, die Umwelt mit den "Augen" einer PLC zu sehen.
Wie leicht kann es da zu FehlSchlüssen (sozusagen zu "optischen Täuschungen") kommen, wenn der Takt des Beobachtens einfach nicht zum Takt der zu beobachtenden Ereignisse passen will ... ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Warum gibts eigentlich das IF #Counter < 10 THEN ... in Deinem Code, wenn doch #Counter direkt davor in jedem Zyklus immer wieder bedingungslos auf 0 gesetzt wird?
Das Konstrukt ist in einem Else Zweig und somit sollte es auf Null gesetzt werden, wenn die erste If Bedingung nicht mehr erfüllt ist. So habe ich mir das jedenfalls gedacht. Nichts was ich ausprobiert hatte, hat funktioniert, außer das ändern des Programmes zu Fup. Aber ich schau mir das später nochmal genauer an und melde mich. danke
 
Das Konstrukt ist in einem Else Zweig und somit sollte es auf Null gesetzt werden, wenn die erste If Bedingung nicht mehr erfüllt ist. So habe ich mir das jedenfalls gedacht.
Code:
#Counter := 0; // Zähler auf 0 setzen   <= #Counter wird hier immer auf 0 gesetzt!

IF "S4" = FALSE AND #Schritt = 5 THEN
    // Positionier Einstellung setzen und Bewegung ausführen solange die Bedingungen erfüllt sind
    IF #Counter < 10 THEN     <= Wie sollte #Counter hier jemals einen anderen Wert als 0 haben können?
...
Dieses (2.) IF ist daher (zumindest momentan) so überflüssig wie ein Kropf.
Es wird eh' immer erfüllt.
;)


PS:
Aber vermutlich ist eher die 1. Zeile ungewollt, oder?
 
Zuletzt bearbeitet:
Ich weiß nicht ob es hier etwas hilft - in der Vergangenheit habe ich jedoch die Erfahrung gemacht, dass es bei derartigen Verknüpfungen schon mal zu Interpretations-Varianzen von Seiten Fa. Siemens kommt. Klammern setzen hilft hier (auch wenn augenscheinlich nicht notwendig) :
Code:
IF ("S4" = FALSE) AND (#Schritt = 5) THEN
oder besser noch :
Code:
IF not "S4" AND (#Schritt = 5) THEN
 
Zuletzt bearbeitet:
Zurück
Oben