Verständnisfrage Timer Ton in ST

Bytebeisser

Level-2
Beiträge
13
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

mittlerweile funktioniert mein Programm aber ich verstehe nicht, warum es vorher nicht ging. Deswegen bitte ich um Erleuchtung.
Zum Problem:
Ein Unterprogramm sollte alle X Sekunden vom Hauptprogramm aus aufgerufen werden.
Statt lang drumrum zu reden, hier die beiden Programmieransätze (Anmerkung: Aus dem Gedächtnis aufgeschrieben, mittlerweile habe ich alles nochmal geändert, z.B. ist der Timer nicht mehr global sondern Bestandteil des Hauptprogramms)

Timerdeklaration
Code:
VAR_GLOBAL
    timer:ton;
    intervallzeit : time:=T#5s;
END_VAR

Hauptprogramm
Code:
schreib_timer(in:=TRUE,pt:=intervallzeit);
IF schreib_timer.Q = TRUE THEN
    UNTERPROGRAMM();
END_IF;

Unterprogramm - funktionierend
Code:
PROGRAMM Unterprogramm
VAR
END_VAR
// irgendwelche Anweisungen
schreib_timer(in := FALSE);

Unterprogramm - NICHT funktionierend
Code:
PROGRAMM Unterprogramm
VAR
END_VAR
//irgendwelche Anweisungen
schreib_timer.Q := FALSE;  // diese Anweisung funktioniert offensichtlich nicht so, wie erwartet

Der einzige Unterschied liegt in der Art, wie ich im Unterprogramm den Timer inaktiv gesetzt habe (bzw. glaubte, in so zu setzen).
Tatsächlich konnte ich nämlich sehen, dass der Timer immer Aktiv war.
Warum ist das so?

Ich hätte vermutlich noch ein paar mehr Verständnisfragen zu ST und der "Gleichzeitigeit" darin. Aber eins nach dem anderen.
 
schreib_timer.Q := FALSE; // diese Anweisung funktioniert offensichtlich nicht so, wie erwartet

Doch, sie funktioniert genau so wie erwartet, wenn auch nicht von dir erwartet. Du kannst auf einem Ausgang eines beliebigen Funktionsbausteins herumschreiben (und der Timer ist genau genommen auch ein Funktionsbaustein), das juckt den Baustein keineswegs. Er wird das nächste Mal aufgerufen, schaut auf seine Eingänge und seine internen Variablen und steuert seine Ausgänge an. Egal was du vorher mit diesn angestellt hast, werden diese überbügelt. Selbst wenn du im Baustein den Zustand der Ausgänge abfrägst, wird der zuletzt im Baustein gesetzte Zustand verwendet und nicht "die Kopie", die du außerhalb beschrieben hast. Ein-/Ausgänge von Bausteinen werden "byVal" übergeben, also als Kopie, im Gegensatz zu In/Out, diese werden üblicherweise "byRef" übergeben, also als Pointer. Ausnahme bei In/Out gibt es bei TIA wenn zwischen optimierten und nicht optimierten Bausteinen übergeben wird, dann wird da auch per Kopie übergeben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Unterprogramm - NICHT funktionierend
Code:
...
schreib_timer.Q := FALSE;  // diese Anweisung funktioniert offensichtlich nicht so, wie erwartet
Hier versuchst Du, den Ausgang Q des Timers zu überschreiben. Das dürfte den Timer bzw. seine Wirkungsweise nicht "interessieren".
Der einzige Unterschied liegt in der Art, wie ich im Unterprogramm den Timer inaktiv gesetzt habe (bzw. glaubte, in so zu setzen).
Tatsächlich konnte ich nämlich sehen, dass der Timer immer Aktiv war.
Warum ist das so?
Um den Timer zu beeinflussen, gibt es den Eingang IN.
Der Zustand des Ausgangs Q folgt dem Zustand des Eingangs IN.
Und zwar unverzüglich, wenn IN seinen Zustand von True auf False ändert und um die vorgegebene Zeit verzögert, wenn IN von False auf True wechselt.
Was Du nun genau mit Timer aktiv bzw. inaktiv meinst, weiss ich nicht. Unter aktiv würde ich die Phase verstehen, in der die programmierte Zeit abläuft und der Eingang IN weiterhin den Zustand True hat.
Ganz "untätig" ist der TON aber auch nach Ablaufen der Zeit nicht. Er nimmt seinen Ausgang Q auf False zurück, sobald sein Eingang IN auf False wechselt.
 
Danke für Eure Antworten. Jetzt bin ich wieder im Zweifel, denn eigentlich hätte ich bereits wissen sollen, dass Schreiben meinerseits auf "Q" nichts bringt, weil es ja ein Ausgang ist.

Ich frage mich nun, ob ich in der Tat die ganze Zeit diesen saublöden Fehler gemacht habe oder ob ich mich nur beim Posten vertan habe (ich muss mal gucken, ob ich das alte Programm noch habe und was da genau drin steht).

Was wäre denn gewesen, wenn ich versucht hätte, den Timer so
Code:
schreib_timer.IN := FALSE;
zurückzusetzen?

Eigentlich wollte ich genau das posten, weil ich meinte, das so auch -erfolglos- im Programm versucht zu haben.

Zu deiner Frage Heinileini: Mit "aktiv" meine ich, dass der Timereingang "in" TRUE ist (demnach Inaktiv => FALSE).

Ehe ich mich nochmal verposte, frage ich mal ganz konkret:
Gibt es einen Unterschied zwischen diesen beiden Anweisungen:
Code:
schreib_timer.IN := FALSE;
und
Code:
schreib_timer(IN := FALSE);
?
 
Zuletzt bearbeitet:
Gibt es einen Unterschied zwischen diesen beiden Anweisungen:
Code:
schreib_timer.IN := FALSE;
und
Code:
schreib_timer(IN := FALSE);
?
Bei der ersten Zeile wird lediglich der Eingang IN des Timers auf False gesetzt. Das hat noch keinen Einfluss auf seinen Ausgang Q. Erst wenn der Timer danach aufgerufen wird, werden auch seine Ausgänge aktualisiert (entsprechend dem Zustand des Eingangs IN, den der Timer dann hat. Dem kann zwischendurch noch mehrmals etwas zugewiesen werden).

Bei der zweiten Zeile wird der Timer aufgerufen, nachdem sein Eingang IN auf False gesetzt wird, so daß er auch seine Ausgänge aktualisiert. --> Der Timer wird sofort gestoppt, sein Ausgang Q ist sofort nach der Anweisung False.

Harald
 
Herzlichen Dank.
StructuredTrash, du nimmst mir die Buchstaben von der Tastatur, den genau das haette ich sonst nochmal gefragt.:)

Da wollte ich besonders schlau sein und dachte, ich haette werweisswie elegant programmiert aber in Wirklichkeit habe ich mir erstmal ein Ei gelegt. Ich hoffe, dass ich es jetzt verstanden habe.

Das ist vermutlich einer der Vorteile der "graphischen" Sprachen, wie FUP oder KOP. Da wird dem Anfaenger eher klar, was er macht. ST dagegen ist maechtiger und effizienter aber man muss auch gewaltig aufpassen.
 
Zurück
Oben