Timer in FB bzw. FB über mehrere Zyklen

Bytebeisser

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

Ich möchte zwei Impulse mit bestimmter Wartezeit dazwischen erzeugen. Mein erster Gedanke war, dies mit einem FB zu machen nach dem Motto "Fire and Forget".
Das klappt anscheinend nicht, weil der FB in den folgenden Zyklen nur dann arbeitet, wenn er dort aufgerufen wird. Die Funktionslogik in FUP habe ich als Bildchen angehängt. Dabei habe ich aber den CFC-Editor nur als Zeichentool missbraucht um das Bildchen zu erhalten. Interessant ist zunächst der rot eingekreiste Bereich. Programmieren möchte ich das Ganze in ST.

Da habe ich auch was.

Hauptprogramm:
Code:
    PRG_timertest();
    IF gvl.taster3 THEN
        timer1(set:=gvl.taster3,reset:=gvl.taster4,
                aktiv=>gvl.LED_13, 
                imp_1=>gvl.LED_14, 
                interv=>gvl.LED_15, 
                imp_2=>gvl.LED_16
        );
    END_IF;

PRG_timertest
Code:
PROGRAM PRG_timertest
VAR
    impuls_1,impuls_2: tp;
    intervall: ton;
    
    Timer_aktiv: SR;
END_VAR

impuls_1(in:=Timer_aktiv.Q1, pt:=T#500MS, q=>gvl.led_10);
intervall(in:=timer_aktiv.Q1, pt:=T#3S, q=>gvl.LED_11);
impuls_2(in:=intervall.Q, pt:=T#500MS,q=>gvl.LED_12);

timer_aktiv(set1:=gvl.taster1,reset:=(gvl.taster2 OR intervall.Q),q1=>gvl.LED_9);

Dieses Programm wird zyklisch aufgerufen und tut zunächst, was es soll. LED_14 leuchtet kurz und nach ein paar Sekunden leuchtet auch LED_16 kurz auf.

FB_timertest
Code:
FUNCTION_BLOCK FB_timertest
VAR_INPUT
    set,reset:BOOL;
END_VAR
VAR_OUTPUT
    imp_1,imp_2,interv,aktiv:BOOL;
END_VAR
VAR
    impuls_1,impuls_2: tp;
    intervall: ton;
    
    SR_Timer_aktiv: SR;
    RS_Timer_aktiv: RS;

END_VAR

// RS
impuls_1(in:=RS_Timer_aktiv.Q1, pt:=T#500MS, q=>imp_1);
intervall(in:=RS_timer_aktiv.Q1, pt:=T#3S, q=>interv);

impuls_2(in:=intervall.Q, pt:=T#500MS,q=>imp_2);


RS_timer_aktiv(set:=set, reset1:=reset,q1=>aktiv);

Dieser FB arbeitet nur, wenn taster3 permanent gehalten wird, anscheinend, weil der FB in den Folgezyklen nur aufgerufen, wenn die Bedinung (taster3) gegeben ist.
Das ist soweit OK. Ich müsste mir überlegen, wie dich die Bedingung im Hauptprogramm setze. Ich könnte evtl. dort das SR (oder RS) Flipflop unterbringen.


Aber was ist grundsätzlich von meinem Ansatz zu halten? Macht man das so?
FBs wollte ich verwenden, weil ich viele Instanzen benötige. Es geht um eine Sonnenschutzsteuerung mittels Rolläden und es soll jeder Rolläden indviduell behandelt werden. Da erschien mir ein FB mit Gedächtnis sinnvoll.

Grundsätzlich scheinen FBs ja durchaus geeignet zu sein, um zyklenübergreifend zu arbeiten, wei Ton, Tof und Tp zeigen. Aber wie müsste ich mein Programm ändern, damit das funktioniert und möglichst viel "Intelligenz" (wie z.B. das FlipFlop) im FB enthalten ist?
 

Anhänge

  • Rolladentimer_CFC.png
    Rolladentimer_CFC.png
    24,1 KB · Aufrufe: 15
Manchmal hilft es schon, wenn man das Problem mal ausformuliert und einen Blick auf bewährten Code wirft.
Und man muss sich die Eigenheiten von ST verinnerlichen.

Nun geht es. Ich habe diese Zeile im Hauptprogramm untergebracht
Code:
        timer1(set:=gvl.taster3,reset:=gvl.taster4,
                aktiv=>gvl.LED_13,
                imp_1=>gvl.LED_14,
                interv=>gvl.LED_15,
                imp_2=>gvl.LED_16
        );
und die If-Abfrage rausgeschmissen. Die benötige ich in meinem Testaufbau garnicht.

Warscheinlich wäre auch dies gegangen:
Code:
timer1();
ins Hauptprogramm (bzw. in das aufrufende Programm) und in die IF-Abfrage dann so was:

Code:
if Bedingung then
    timer1.set=gvl.taster2, reset:=gvl.taster4,
    ....
aber eigentlich ist das unnötig.

Ich glaube nun auch den Rat zu verstehen, dass man z.B. die Initialiserung von Timern nicht in Bedingungen stecken sollte.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Dieser FB arbeitet nur, wenn taster3 permanent gehalten wird, anscheinend, weil der FB in den Folgezyklen nur aufgerufen, wenn die Bedinung (taster3) gegeben ist.
Das ist soweit OK. Ich müsste mir überlegen, wie dich die Bedingung im Hauptprogramm setze. Ich könnte evtl. dort das SR (oder RS) Flipflop unterbringen.

Aber was ist grundsätzlich von meinem Ansatz zu halten? Macht man das so?
Ich würde das "Pferd von hinten aufzäumen" und alle drei Timer (TOF!) mit derselben (negativen) Flanke triggern.
Leuchte := TOF1.Q OR NOT TOF2.Q AND TOF3.Q ;
Die Zeiten wären
TOF1 = LeuchtDauer des ersten Aufleuchtens
TOF2 = PausenDauer + LeuchtDauer des ersten Aufleuchtens
TOF3 = LeuchtDauer des zweiten Aufleuchtens + PausenDauer + LeuchtDauer des ersten Aufleuchtens.
 
deine Beschreibung (Wortwahl) ist eine Schrittkette.
Da gibs x-mögliche Lösungen wie z.b. Timer / counter oben und unten ein case auf eine enum , eventuell oben auch eine Pause für aktuellen schritt oder Komplettabruch zu Startschritt... oder setzen von Bitvariablen welche den aktuellen schritt setzen und die dann timer für schrittwechsel Laufen lassen ... etcetc.
Aber deine Beschreibung entspricht nicht einem formlosen, gleichzeitigen Ausführung.
Natürlich, "so einfach wie möglich, so komplex wie nötig", aber diese Schrittkette ist doch einfach und so leicht mit debugvariablen versehbar, die Wechselkondition so komfortabel mit timern oder Sekundencountern (pausierbar) bestückbar => das entspricht doch einem einfachen und übersichtlichem Lösungsansatz.

PS: was passiert z.b. mit einer formlosen Lösung wenn kurz der Strom fällt ? Mit Schrittkette auf Retain wird richtig abgeschlossen sobald es geht
 
Ich würde das "Pferd von hinten aufzäumen" und alle drei Timer (TOF!) mit derselben (negativen) Flanke triggern.
Leuchte := TOF1.Q OR NOT TOF2.Q AND TOF3.Q ;
Die Zeiten wären
TOF1 = LeuchtDauer des ersten Aufleuchtens
TOF2 = PausenDauer + LeuchtDauer des ersten Aufleuchtens
TOF3 = LeuchtDauer des zweiten Aufleuchtens + PausenDauer + LeuchtDauer des ersten Aufleuchtens.
Was wäre denn der Vorteil deines Vorschlags?
Die beiden Impulse sind immer gleichlang (halt so lang, dass der RolladenSTG diese sicher erkennt), wogegen die Pause von der Grösse des Rolladens und der Laufrichtung abhängt. Da fände ich es angenehm, wenn ich nur diese Zeit ändern müsste.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
deine Beschreibung (Wortwahl) ist eine Schrittkette.
Da gibs x-mögliche Lösungen wie z.b. Timer / counter oben und unten ein case auf eine enum , eventuell oben auch eine Pause für aktuellen schritt oder Komplettabruch zu Startschritt... oder setzen von Bitvariablen welche den aktuellen schritt setzen und die dann timer für schrittwechsel Laufen lassen ... etcetc.
Aber deine Beschreibung entspricht nicht einem formlosen, gleichzeitigen Ausführung.
Natürlich, "so einfach wie möglich, so komplex wie nötig", aber diese Schrittkette ist doch einfach und so leicht mit debugvariablen versehbar, die Wechselkondition so komfortabel mit timern oder Sekundencountern (pausierbar) bestückbar => das entspricht doch einem einfachen und übersichtlichem Lösungsansatz.

PS: was passiert z.b. mit einer formlosen Lösung wenn kurz der Strom fällt ? Mit Schrittkette auf Retain wird richtig abgeschlossen sobald es geht
Du schlägst also AS vor?
Abgesehen davon ist das Thema Stromausfall m.E. hier vernachlässigbar. Fällt der Strom aus, ist eh alles weg und bei Spannungsrückkehr werden die Rolläden irgendwann wieder automatisch richtig stehen, sofern nicht die Bewohner vorher schon manuell eingegriffen haben.
 
Nein, nur dass du es von dem Standpunkt aufziehst wie es deine Wortwahl anzeigt, also eine Schrittkette, in der Sprache die dir dabei am bequemsten vorkommt. Ob dann wirklich nur die Zeiten bearbeitet werden oder auch Abbrüche/pausen ist nicht wirklich relevant.
 
Was wäre denn der Vorteil deines Vorschlags?
Anscheinend habe ich das Stichwort "Rollladen" überlesen und nur die Vorgaben ...
... zwei Impulse mit bestimmter Wartezeit dazwischen erzeugen ...
... sowie die gezeigte Ansteuerung diverser LEDs und ...
.... Motto "Fire and Forget" ...
... gelesen, sowie, dass Dich das Festhalten des Tasters stört und Du deshalb möglichst viel Intelligenz in Form eines FlipFlops einbauen wolltest:
Dieser FB arbeitet nur, wenn taster3 permanent gehalten wird ...
Bei meinem Vorschlag wird die Sequenz beim Loslassen des Tasters gestartet und läuft ab dann komplett bis zum bitteren Ende durch. Voll im Sinne von "fire and forget".
Dass dabei Summen aus den ImpulsDauern und der Pausenzeit zu berücksichtigen sind, ist für Deine Anwendung nicht wirklich hilfreich, wäre aber zumindest "beherrschbar".
Wenn die Anforderungen an die Schaltung erst so nach und nach offengelegt werden, kann es natürlich zu Missverständnissen und zu weniger nützlichen Vorschlägen kommen. Ich bitte vielstmals um Entschuldigung ... ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
[...]
Wenn die Anforderungen an die Schaltung erst so nach und nach offengelegt werden, kann es natürlich zu Missverständnissen und zu weniger nützlichen Vorschlägen kommen. Ich bitte vielstmals um Entschuldigung ... ;)
Kritik angekommen und aufgenommen. Allerdings wollte ich auch nicht zu viel "Palaver" veranstalten und mich zunächst auf die Problematik fixiert, wie man die Timer überhaupt gescheit absetzt.
Mit "Fire and Forget" meinte ich, dass, nach Aufruf durch das Programm, der FB den Rest erledigt. Das klappt jetzt anscheinend aber meine Formulierung war Kappes.

Gerne schildere ich auch ein wenig mehr vom Projekt:
Das eigentliche Fahren der Rollläden wird von Steuergeräten organisiert. Es gibt zwei Taster, Hoch und Runter. Kurzer Druck auf einen der beiden lässt den Rolladen soange fahren, bis entweder die Endlage erreicht ist, oder erneut einen Taste betätigt wird. Wird dieselbe Richtungstaste nochmal betätigt, hält er an, wird die Gegenrichtungstaste betätigt, fährt er in die andere Richtung.

Die SPS soll nun parallel zu diesen Tastern wirken. Konkret geht es dabei um Sonnenschutz, d.h. auf der Ostseite sollen die Rolläden morgens nur ein wenig angehoben werden, wogegen an der südlich und westlich ausgerichteten Seiten die Rolläden nachmittags ein gehöriges Stück (aber nicht ganz) runtergefahren werden sollen.
Gesteuert wird ganz primitiv über die Uhrzeit. "Sommer" wird über einen Schalter gesetzt, evtl. gibt es später auch die Möglichkeit, einen Wetterdienst anzuzapfen, so dass die SPS weiss, obs sonnig (und warm) ist.

Falls Interesse besteht, kann ich den bisherigen Code auch gerne posten.
 
Zurück
Oben