Flanke SCL

nutellahase

Level-2
Beiträge
180
Reaktionspunkte
28
Zuviel Werbung?
-> Hier kostenlos registrieren
Hatte letztens eine hitzige Debatte mit einem Kollegen wegen einer Flankenauswertung in SCL. Ich versteh auch nicht ganz wieso das eigentlich funktioniert. Hier erstmal der Code:

Code:
Trigger := False;
Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];

IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;
IndexAnf := IndexAnf + 1;


IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
END_IF;
Der Index wird jeden SPS-Zyklus um eins erhöht. Anforderung_alt ist ein Array of Bool und eine Stat-Variable. Anforderung ist ebenfalls ein Array of Bool und eine Eingangsvariable.
Das Signal Trigger setzt er mit einer pos. Flanke. Ich versteh allerdings nicht wie die Flanke überhaupt zustande kommen kann. Angenommen der Index ist jetzt 1 und das Signal Anforderung an der Indexstelle ist ebenfalls log 1. Dann wird doch am Anfang des Programms folgendes gemacht:
Anforderung_alt[1]:= True; (weil ja Anforderung[1] ebenfalls True ist)

Wie kann jetzt die Flanke erfolgen?

If Anforderung[1] = True and not Anforderung_alt[1] = False weil sie ja davor mit dem Wert True überschrieben wird!?!

Verstehen würde ich es wenn er das nur einmalig machen will! Dann würde ich es allerdings so schreiben:

Code:
Trigger := False;

IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;
IndexAnf := IndexAnf + 1;


IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
END_IF;
So würde Trigger nur einmal an der jeweiligen Indexstelle gesetzt werden, wenn das Signal Anforderung True ist.

Wenn er es bei jeder pos. Flanke machen will würde ich es so schreiben:

Code:
Trigger := False;

IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;
IndexAnf := IndexAnf + 1;


IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
END_IF; 
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
Dennoch funktioniert aber seine Variante auch... Wieso?? Ich denk bei SCL nämlich immer gerne Zeile für Zeile... Sprich was ganz oben steht wird auch als erstes durchgeführt...

Vielleicht denk ich aber auch nur falsch / zu kompliziert ?!?
 
Hatte letztens eine hitzige Debatte mit einem Kollegen wegen einer Flankenauswertung in SCL. Ich versteh auch nicht ganz wieso das eigentlich funktioniert. Hier erstmal der Code:

Code:
Trigger := False;
Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];

IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;
IndexAnf := IndexAnf + 1;


IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
END_IF;
Der Index wird jeden SPS-Zyklus um eins erhöht. Anforderung_alt ist ein Array of Bool und eine Stat-Variable. Anforderung ist ebenfalls ein Array of Bool und eine Eingangsvariable.
Das Signal Trigger setzt er mit einer pos. Flanke. Ich versteh allerdings nicht wie die Flanke überhaupt zustande kommen kann. Angenommen der Index ist jetzt 1 und das Signal Anforderung an der Indexstelle ist ebenfalls log 1. Dann wird doch am Anfang des Programms folgendes gemacht:
Anforderung_alt[1]:= True; (weil ja Anforderung[1] ebenfalls True ist)

Wie kann jetzt die Flanke erfolgen?

If Anforderung[1] = True and not Anforderung_alt[1] = False weil sie ja davor mit dem Wert True überschrieben wird!?!

Verstehen würde ich es wenn er das nur einmalig machen will! Dann würde ich es allerdings so schreiben:

Code:
Trigger := False;

IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;
IndexAnf := IndexAnf + 1;


IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
END_IF;
So würde Trigger nur einmal an der jeweiligen Indexstelle gesetzt werden, wenn das Signal Anforderung True ist.

Wenn er es bei jeder pos. Flanke machen will würde ich es so schreiben:

Code:
Trigger := False;

IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;
IndexAnf := IndexAnf + 1;


IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
END_IF; 
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
Dennoch funktioniert aber seine Variante auch... Wieso?? Ich denk bei SCL nämlich immer gerne Zeile für Zeile... Sprich was ganz oben steht wird auch als erstes durchgeführt...

Vielleicht denk ich aber auch nur falsch / zu kompliziert ?!?


Hallo!

Könntest du noch etwas mehr ausholen?Wie wird die Eingansvariable Anforderung beschrieben?Bzw. in welchem zusammenhang wird dieser Baustein verwendet?

Mfg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Index wird jeden SPS-Zyklus um eins erhöht.
Das sehe ich auch so, denn die zweite IF Anweisung wird doch wohl gar nie durchlaufen:
Code:
Trigger := False;
Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
 
[COLOR=green]IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;[/COLOR]
[COLOR=green]IndexAnf := IndexAnf + 1;[/COLOR]
 
[COLOR=red]// Diese Anweisung wird nie bearbeitet da Anforderung_alt immer gleich Anforderung ist.[/COLOR] 
IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
END_IF;
Das einzige was an dem Code relevant ist, sind die grün markierten Zeilen.
Den Rest kann dein Kollege weglassen und du hast Recht, das hat nichts mit einer Flankenauswertung zu tun.
 
Wenn der Baustein das erste mal aufgerufen wird macht er sehrwohl die Flanken aber nur solange bis der Index einmal komplett durchlaufen wurde!Wenn am eingang Anforderung[IndexAnf] wieder 0 anliegt denn dann werden die Statisch gespeicherten Nforderung_alt[IndexAnf] Werte wieder mit False überschrieben!Wird das auch einen ganzen Indexdurchlauf gemacht kann wieder mit der Flankenausauswertung begonnen werden!

Mfg
 
Hallo,

1. Aussage vom TE es funktioniert.

2. es liegt wohl daran, das z.B. am Anfang des Codes, also vor dem grünen.

IndexAnf, z.B. 17 ist und dann auf 18 geändert wird.

Gruß, Voxe
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hatte letztens eine hitzige Debatte mit einem Kollegen wegen einer Flankenauswertung in SCL. Ich versteh auch nicht ganz wieso das eigentlich funktioniert. Hier erstmal der Code:

Code:
Trigger := False;
Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];

IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;
IndexAnf := IndexAnf + 1;


IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
END_IF;
Vielleicht denk ich aber auch nur falsch / zu kompliziert ?!?

Du denkst wohl zu kompliziert! :ROFLMAO:

Ich versuch das mal zu erklären

1. Trigger := False; //hier wird der Trigger immer False gesetzt
2. Anforderung_alt[IndexAnf] := Anforderung[IndexAnf]; //hier wird die Anforderung X immer gleich gesetzt!!!!!!!!!!!!!!!!!

3. IF IndexAnf > 99 THEN
4. IndexAnf := 0;
5. END_IF; //Kontrolle, ober der Index überläuft, wenn ja zurücksetzen auf 0, Paule, du hast hier das END_IF überlesen, das ist so korrekt
6. IndexAnf := IndexAnf + 1; //hier wird der Index immer um 1 erhöht X := X+1


7. IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN //Anforderung (X+1 in Bezug auf Zeile 2!!!) True und Anforderung _alt (X+1 in Bezug auf Zeile 2!!!) noch False!!!, dann
8. Trigger := True; //Trigger auf True
9. Anforderung_alt[IndexAnf] := Anforderung[IndexAnf]; //Anforderung_alt auf gleichen Wert wie Anforderung setzen
10. END_IF; [/CODE]

Zeile 2 setzt die Anforderung_alt(X) auf den Wert von Anforderung(X)
Zeile 6 erhöht den Index Anforderung auf X+1
Zeile 7 Anforderung X+1 auf True mit Anforderung_alt X auf False und
Zeile 8 setzt den Trigger
Zeile 9 setzt Anforderung_alt X+1 auf den Wert von Anforderung X+1, damit ist Anforderung alt auch auf True,

Es ergibt sich: Wenn Anforderung auf True geht und Anforderung_alt noch False ist kommt eine Flanke zustande, anschließend sind Anforderung und Anforderung_alt gleichgesetzt!!!
In nächsten Durchlauf (Zyklus) wird Anforderung_alt und Anforderung gleichgesetzt, dann muß Anforderung also wieder False sein, sonst funtkioniert der Code nicht!!!!!!!

Der Code bringt Flanken bei Kommen des Ereignisses, also wenn Anforderung (Index) True, aber nur jedes 2. Mal oder aber, Anforderung ist selbst schon eine Flanke!

Warum? Der Code bekommt nicht mit, dass Anforderung auf False geht, es sei denn, Anforderung ist selbst eine Flanke, also im nächstfolgenden Zyklus schon wieder False.
Wenn Anforderung zu einem beliebigen Zeitpunkt False wird, dann wird beim nächsten Durchlauf (Z+1) des Index keine Flanke erkannt, denn Anforderung_alt ist noch True, Anforderung_Alt wird aber immerhin wieder False gesetzt und so wird dann beim Durchlauf Z+2 die Flanke erkannt, so Anforderung dann immer noch auf True steht!!!
 
Zuletzt bearbeitet:
Wie auch immer ...
Ich würde auch die Variante favourisieren, die der TE selbst auch für besser hält (also die Flanke nach der Überprüfung bilden). Es ist so auf Anhieb ersichtlich.

Gruß
Larry
 
Wie auch immer ...
Ich würde auch die Variante favourisieren, die der TE selbst auch für besser hält (also die Flanke nach der Überprüfung bilden). Es ist so auf Anhieb ersichtlich.

Gruß
Larry

Das grundsätzliche Problem an dem Code ist, dass erst beim nächsten Indexzähldurchgang wieder alles zurückgestellt werden kann! In den restlichen 99 Zyklen, kann die Variable Anforderung, deren Index gerade nicht an der Reihe ist, machen, was sie will, es passiert nichts. Angenommen, man hat 10ms Zykluszeit, dann sind das 1 Sekunde und da kann viel passieren, zumindest wird dann nur alle 2 Sekunden überhaupt eine Flanke erkennbar sein, denn nach 1 Sekunde muß ja erstmal zurückgestellt werden. Kann sein, dass das für die Aufgabe ausreichend ist, mir würde das so nicht gefallen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du denkst wohl zu kompliziert! :ROFLMAO:

Ich versuch das mal zu erklären
[...]

Danke ... na klar ... das mit x und x+1 wäre mir jetzt so nie in den Sinn gekommen :ROFLMAO: . Habe das immer mit den gleichen Index verglichen und dabei völlig vergessen, dass die Zeile ja davor steht.

So würde es dann aber nie funktionieren oder bzw. wäre es völlig sinnlos?:

Code:
Trigger := False;

IF IndexAnf > 99 THEN IndexAnf := 0; END_IF;
IndexAnf := IndexAnf + 1;

[COLOR=Red]Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];[/COLOR]

IF Anforderung [IndexAnf] AND NOT Anforderung_alt[IndexAnf] THEN 
    Trigger := True;
    Anforderung_alt[IndexAnf] := Anforderung[IndexAnf];
END_IF;
Ich bleibe dennoch bei meiner Variante, weil wie man sieht verwirrt es einen anfangs scheinbar doch sehr.

Zum Thema Zyklen:
Wir haben das auch schon mit einer Schleife probiert, das Problem dabei ist dass dann die Zykluszeit enorm ansteigt (was auch logisch bei einer Schleife ist). Für unsere Anwendung reicht die zyklische Abarbeitung vollkommen aus. Das Signal Anforderung ist im Grunde ein digitaler Eingang von einer Klappe. Dieser Eingang liegt solange an bis Material nachgefüllt wurde. Nachdem wir 100 Dinger davon haben eben ein Array von 100 Einträgen.

Von daher versteh ich auch seine Auswertung nicht warum er das so macht. Da werte ich doch gleich die Flanke im gleichen Index aus (Variante 3 im ersten Beitrag). Sollte das Signal beim nächsten Durchlauf immer noch anliegen wird die Variable Trigger sowieso nicht mehr gesetzt.
Die Art und Weise wie er manchmal die If-Blöcke schreibt (in einer Wurst) habe ich auch schon mal kritisiert. Das ist teilweise auch sehr unübersichtlich und man überliest dann schon manchmal ein End_if!
Aber ich bin ja nur Instandhalter und er der Programmierer also kann ich schon verstehen das man es vl. irgendwann nur mehr so runterschreibt und nichts mehr kommentiert. :cool:

Aber man lernt halt nie aus! Daher ein Danke an Euch für eure Hilfe.
 
Ja, der Code in deinem letzten Post würde nicht funktionieren!
Für die beschriebene Anwendung funktioniert der Ausgangscode, es dauert wohl einen Durchlauf länger, bis die neue Klappenstellung erkannt wird, das sollte nichts ausmachen, Material nachfüllen dauert sicher länger.
 
Zurück
Oben