Schrittkette und TON-Timer

Spoon

Level-1
Beiträge
27
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe folgendes Problem: Ich habe eine Schrittkette porgrammiert. Diese funktioniert auch eigentlich sehr gut und die einzelnen Schritte werden nacheinander abgearbeitet. Nur in einem Schritt wollte ich einen TON einfügen. Dieser wird aber einfach übersprungen und es geht mit dem Schritt 7 weiter.

CASE Step OF
.........
6: IF Sensor_1 AND NOT Timer_3.Q THEN
Timer_3.IN := TRUE;
Step := Step +1;
END_IF
7: IF Timer_3.Q THEN
Finish := FALSE;
Step := Step +1;
END_IF
8: Step := 0;
END_CASE

Timer_3 (PT:= T#5s, );
 
Hallo spoon,

versuche es vielleicht mit

7: IF Timer_3.Q THEN
Timer_3.IN := FALSE;
Finish := FALSE;
Step := Step +1;
END_IF

Gruß,
witkatz
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe es so geändert wie witkatz es beschrieben hat. Leider funktioniert es nicht. Der Timer wird einfach übersprungen und die Schrittkette springt wieder in Schritt 1.
Bleibt dort aber stehen, da der Merker Finsh erst zurück gesetzt werden muss.
 
Kannste mal deinen Schritt 5 und evtl auch Schritt 4 posten?

Du schreibst Schritt 6 wird übersprungen. Dann wird das Problem bestimmt voher zu suchen sein.
 
Hallo Spoon!

Also dein Ansatz ist soweit in Ordnung. Es fehlt aber noch an ein paar Kleinigkeiten.

1. Mit "Timer_3.IN := TRUE;" wird dein Timer nicht gestartet. Das liegt daran, dass der Timer-Baustein mit diesem Aufruf nicht aufgerufen wird. Besser ist "Timer_3(IN:= TRUE, PT:= T#5s);".

2. Um zu schauen, ob dein Timer abgelaufen ist, ist es richtig den Ausgang Q zu überprüfen. Das funktioniert auch mit "Timer_3.Q". Allerdings musst du vor deiner Abfrage den Timer aktualisieren, da er ansonsten nicht den aktuellen Wert übernimmt. Also einfach ein "Timer_3(IN:= TRUE);" vor der Abfrage einfügen.

3. Nachdem dein Timer abgelaufen ist, musst du ihn zurücksetzen, sonst kannst du ihn in deinem weiteren Programmablauf nicht mehr verwenden. Das hat auch schon witkatz angemerkt. Also einfach nach deiner Abfrage ein "Timer_3(IN:= FALSE);" einfügen.

Code:
6: IF Sensor_1 AND NOT Timer_3.Q THEN
Timer_3(IN := TRUE, PT := T#5s);         (* Timer starten *)
Step := Step +1;
END_IF
7: Timer_3(IN := TRUE);                  (* Timer aktualisieren *)
IF Timer_3.Q THEN                        (* Timer abgelaufen? *)
Timer_3(IN := FALSE);                    (* Timer zurücksetzen *)
Finish := FALSE;
Step := Step +1;
END_IF

Gruß Cerberus
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
@ Cerberus:
Spoon ruft den Timer am Ende der Schrittkette jeden Zyklus auf.
... hoffe zumindest, dass ich seinen Code korrekt interpretiere.

CASE Step OF
.........
6: IF Sensor_1 AND NOT Timer_3.Q THEN
Timer_3.IN := TRUE;
Step := Step +1;
END_IF
7: IF Timer_3.Q THEN
Finish := FALSE;
Step := Step +1;
END_IF
8: Step := 0;
END_CASE

Timer_3 (PT:= T#5s, );

Ich halte die Art des Aufrufs auch für die sauberste.
 
@ Cerberus:
Spoon ruft den Timer am Ende der Schrittkette jeden Zyklus auf.
... hoffe zumindest, dass ich seinen Code korrekt interpretiere.



Ich halte die Art des Aufrufs auch für die sauberste.

Sorry hab ich überlesen. In diesem Fall haben sich meine Punkte 1 und 2 erledigt. Trotzdem sollte der Timer wieder zurückgesetzt werden.
 
Hallo,
nach meiner Meinung wird das so mit dem Timer niemals was werden. Der Timer muß um sinnvoll funktionieren zu können, die steigende und auch die fallende Flanke am IN mitbekommen. Das klappt normalerweise in einem CASE oder auch in einer IF-THEN Anweisung nicht.
Ich würde den Timer außerhalb des CASE programmieren und zuweisen - dann von mit aus den Q etc. im CASE verwenden - das gibt dann keine Probleme ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
nach meiner Meinung wird das so mit dem Timer niemals was werden. Der Timer muß um sinnvoll funktionieren zu können, die steigende und auch die fallende Flanke am IN mitbekommen. Das klappt normalerweise in einem CASE oder auch in einer IF-THEN Anweisung nicht.
Ich würde den Timer außerhalb des CASE programmieren und zuweisen - dann von mit aus den Q etc. im CASE verwenden - das gibt dann keine Probleme ...

Gruß
LL

@ Larry

Ich verwende Timer regelmäßig in CASE-Schleifen. Wie im dem oben geposteten Code. Und es funktioniert einwandfrei.

Gruß Cerberus
 
Habe es so geändert wie witkatz es beschrieben hat. Leider funktioniert es nicht. Der Timer wird einfach übersprungen und die Schrittkette springt wieder in Schritt 1.

Code:
PROGRAM MAIN
VAR
    Step: INT;
    Timer_3: TON;
    Sensor_1: BOOL;
END_VAR
CASE Step OF
0:
    (*.........*)
    Timer_3.IN := FALSE;
    step:= 6;
6:
    IF Sensor_1 AND NOT Timer_3.Q THEN
        Timer_3.IN := TRUE;
        Step := Step +1;
    END_IF
7:
    IF Timer_3.Q THEN
        Timer_3.IN := FALSE;
        Step := Step +1;
    END_IF
8:
    Step := 0;
END_CASE

Timer_3 (PT:= T#5s, );
Die Schrittkette überspringt den Schritt 6 nicht. Der dauert nur einen Zyklus, man sieht das in der Online-Anzeige nicht. Dafür ist sie zu träge.
Um zu sehen ob der Schritt 6 bearbeitet wird, musst du einen Breakpoint oder eine Testvariable in dem Schritt setzen, oder den Schrittzähler Tracen.

Gruß,
witkatz
 
Wenn der Timer gestartet wurde und hochzählt wurde Schritt 6 erfolgreich ausgeführt. Eigentlich sollte er nach 5s in Schritt 8 springen und im nächsten Zyklus nach 0 zurück und der ganze Tanz geht von vorne los.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke erstmal für die vielen Antworten.

Hab das ganz nochmal ein bischen umgeschrieben:

Case Step OF
......
6: IF Reed_1 AND NOT Time_Go THEN
Go_Auto := FALSE;
Finish := TRUE;
TIME_Go := TRUE;
Step := Step +1;
END_IF
7: IF TIME_OK THEN
Time_Go := FALSE;
Finish := FALSE;
Step := Step +1;
END_IF
8: Step := 0;
END_CASE

Timer_3 (IN:=Time_Go, PT:= T#5s, Q=>, PT=>, );
IF Timer_3.Q THEN
TIME_OK:= TRUE;
ELSE
TIME_OK:= FALSE;
END_IF

Der Timer beginnt bei dem Aufruf des Schritt 6 zulaufen.
Es wird aber direkt in den Schritt 8 gesprungen und dann halt wieder in den Schritt 1. Als wäre die Zeit schon abgelaufen, obwohl sie ja noch läuft. So sehe ich das Online.
Ich will aber erst 5 Sekunden warten und dann wieder in den Schritt ein Springen. Vielleicht gibt es dafür noch eine andere Lösung.
 
Sicher dass du nicht noch irgendwo außerhalb der CASE ein Step := Step + 1 drin hast oder der Timer irgendwo nochmal aufgerufen wird?
Setz zur Sicherheit mal in den Schritte die Variable Step auf absolute Werte, also im Schritt 6: Step := 7, im Schritt 7: Step := 8 usw.

Lass den Timer zur Sicherheit mal allein laufen mit manuellem Setzen der .IN.
 
Zuletzt bearbeitet:
Hallo,
wo ist denn TIME_OK deklariert ? TEMP oder STAT ?
Du kannst in dem CASE-Konstrukt den Timer3.Q durchaus abfragen - wichtig ist das du den Timer selbst ausserhalb steuerst.

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Den Timer setzt man vor die Switch-Case-Anweisung. Daher

Code:
eier_timer(IN:=triggervar ... )

switch....
Setzt man den Timer über das Programm und nicht über IO-Eingänge muss der In-Eingang einen Low-High übergang machen.Entweder so:

Code:
Mann kann den Timer auch in die Switch-Case-Anweisung packen, aber dann wird es richtig unübersichtlich ergo hässlich. Ich halte diese Lösung für die sauberste, weil sie leicht wartbar ist. 

case schritt_100: 
   triggervar := FALSE;
   state := schritt_101;

case schritt_101:
   triggervar := TRUE;
   if eier_timer.out then
       state := schritt_xyz;
   end_if;
oder

Code:
case schritt_100:
   eier_timer(IN:=NOT eier_timer.out);
   if eier_timer.out then
       state := schritt_xyz;
   end_if;
Eine dritte Lösung ist ziemlich hässlich, wenn man die obige Struktur einsetzt:
Code:
case schritt_100:
   eier_timer(IN:=False);
   eier_timer(IN:=True);
   state := schritt_101;

case schritt_101:
   if eier_timer.out then
        state := schritt_xyz;
    end_if;
Wichtig ist in jedem Fall, dass der IN-Eingang einen Low-High-Übergang macht und bei jedem Wechsel des Eingangs der FB-Code ausgeführt wird, was nur dann geschieht, wenn der so dasteht:

Code:
eier_timer(....);
 
Zuletzt bearbeitet:
Zurück
Oben