Timer/Delay zwischen Funktionen

Kilianxnw

Level-1
Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
meine Aufgabenstellung ist es, ein Lauflicht zu programmieren in "structured text", bekomme aber keine Timer, oder Delay-artige Verzögerung hin. Weder mit FOR, noch WHILE. (Frequenz und Duty Cycle einstellbar, aber unrelevant in meiner Frage hier.
SOFTWARE: Automation Studio V4.10
Lerne erst die Sprache, würde mich sehr über Hilfe freuen, das habe ich bis jetzt, vllt kann man mein Problem verstehen.
Liebe Grüße, Kilian

PROGRAM _CYCLIC
// ~~~~~~~~~~~~~~~~~~~~ Start des Programms ~~~~~~~~~~~~~~~~~~~~~~~~~~

IF DI1 THEN // Schalter DI1
DO1 := TRUE; // Lampe DO2 ON
// ~~~~~~~~~~~~~~~~~~~~ Auswahl der Frequenz ~~~~~~~~~~~~~~~~~~~~~~~~~

IF DI2 THEN

f := (10000-490*AI1); // Frequenz veränderung mittels P1
ELSE
f := 500; // f -> fix
END_IF

// ~~~~~~~~~~~~~~~~~~ Einstellung des Duty Cycle ~~~~~~~~~~~~~~~~~~~~~~
Duty_Cycle := AI2*2; // Für den wait (derzeit unbenutzt)

// ~~~~~~~~~~~~~~~~~~~~~~~ Funktion_1 blinken ~~~~~~~~~~~~~~~~~~~~~~~~~

// init
Zaehler := 10000;
TON_01(IN:=NOT DO3ge, PT:=INT_TO_TIME(f)); // DI3 ON mit Zeitverzögerung
DO3ge:=TON_01.Q;
TOF_01(IN:=DO3ge, PT:=INT_TO_TIME(f)); // DI3 OFF mit Zeitverzögerung
DO3ge:=TOF_01.Q;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WAIT_1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Var1 := 1;
WHILE Var1 < Zaehler DO
Var1 := Var1 + 1;

END_WHILE

// ~~~~~~~~~~~~~~~~~~~~~~~ Funktion_2 blinken ~~~~~~~~~~~~~~~~~~~~~~~~~

TON_01(IN:=NOT DO4ge, PT:=INT_TO_TIME(f)); // DI4 ON mit Zeitverzögerung
DO4ge:=TON_01.Q;
TOF_01(IN:=DO4ge, PT:=INT_TO_TIME(f)); // DI4 OFF mit Zeitverzögerung
DO4ge:=TOF_01.Q;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WAIT_2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Var2 := 1;
WHILE Var1 < Zaehler DO
Var2 := Var2 + 1;

END_WHILE

// ~~~~~~~~~~~~~~~~~~~~~~~ Funktion_3 blinken ~~~~~~~~~~~~~~~~~~~~~~~~~

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WAIT_3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ELSE
DO1 := FALSE; // Lampe DO1 OFF
DO2 := FALSE;
DO3ge := FALSE; // Lampe DO3 OFF
DO4ge := FALSE; // Lampe DO4 OFF


END_IF
AO7 := 1111; // Anzeige P1

END_PROGRAM
 
Bei einer SPS wird das Programm schon in einer "äußeren Schleife" zyklisch abgearbeitet. Man kann nicht in einer Schleife warten daß Zeit vergeht. Man muß lediglich einen Timer aufrufen und bei jedem Programmdurchlauf schauen, ob die gewünschte Zeit abgelaufen ist.

Harald
 
... Zaehler := 10000;
TON_01(IN:=NOT DO3ge, PT:=INT_TO_TIME(f)); // DI3 ON mit Zeitverzögerung
DO3ge:=TON_01.Q;
TOF_01(IN:=DO3ge, PT:=INT_TO_TIME(f)); // DI3 OFF mit Zeitverzögerung
DO3ge:=TOF_01.Q;

... TON_01(IN:=NOT DO4ge, PT:=INT_TO_TIME(f)); // DI4 ON mit Zeitverzögerung
DO4ge:=TON_01.Q;
TOF_01(IN:=DO4ge, PT:=INT_TO_TIME(f)); // DI4 OFF mit Zeitverzögerung
DO4ge:=TOF_01.Q;

...
Mehrfache Zuweisungen auf den gleichen Ausgang im gleichen Zyklus sind in einem SPS-Programm sinnlos.
Es "gewinnt" dann der letzte im Zyklus.
Du musst das Progamm so schreiben, dass es zyklisch aufgerufen werden kann, keine Warteschleifen.
Gruß
Erich
 
Zuviel Werbung?
-> Hier kostenlos registrieren
UPDATE:
Die erste und die zweite LED leuchten jetzt so wie es soll, sprich nacheinander.
Kopiere ich jetzt die Funktion und Delay nach unten, um auf meine 3 (Am Ende sollen es insg. 4 werden) LED'S zu kommen und ändere die LED von DO4ge auf DO5ge, bleibt die dritte LED aber permanent ausgeschaltet - als hätte ich keine LED hinzugefügt leuchten die 1. und 2. fröhlich vor sich hin.
Code:

PROGRAM _CYCLIC
// ~~~~~~~~~~~~~~~~~~~~ Start des Programms ~~~~~~~~~~~~~~~~~~~~~~~~~~

IF DI1 THEN // Schalter DI1
DO1 := TRUE; // Lampe DO2 ON

// ~~~~~~~~~~~~~~~~~~~~ Auswahl der Frequenz ~~~~~~~~~~~~~~~~~~~~~~~~~

IF DI2 THEN

f := (10000-490*AI1); // Frequenz veränderung mittels P1
ELSE
f := 500; // f -> fix
END_IF

// ~~~~~~~~~~~~~~~~~~ Einstellung des Duty Cycle ~~~~~~~~~~~~~~~~~~~~~~
Duty_Cycle := AI2*2; // Für den wait
// ~~~~~~~~~~~~~~~~~~~~~~~ Funktion_1 blinken ~~~~~~~~~~~~~~~~~~~~~~~~~

TON_01(IN:=NOT DO3ge, PT:=INT_TO_TIME(f)); // DI3 ON mit Zeitverzögerung
DO3ge:=TON_01.Q;
TOF_01(IN:=DO3ge, PT:=INT_TO_TIME(f)); // DI3 OFF mit Zeitverzögerung
DO3ge:=TOF_01.Q;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WAIT_1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Count := 0;
Delay(IN:=TRUE, PT:=T#0.5S);
IF NOT(Delay.Q) THEN
RETURN;
END_IF
Delay(IN:=FALSE);
// ~~~~~~~~~~~~~~~~~~~~~~~ Funktion_2 blinken ~~~~~~~~~~~~~~~~~~~~~~~~~
TON_01(IN:=NOT DO4ge, PT:=INT_TO_TIME(f)); // DI4 ON mit Zeitverzögerung
DO4ge:=TON_01.Q;
TOF_01(IN:=DO4ge, PT:=INT_TO_TIME(f)); // DI4 OFF mit Zeitverzögerung
DO4ge:=TOF_01.Q;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WAIT_2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Count := 0;
Delay(IN:=TRUE, PT:=T#0.5S);
IF NOT(Delay.Q) THEN
RETURN;
END_IF
Delay(IN:=FALSE);
// ~~~~~~~~~~~~~~~~~~~~~~~ Funktion_3 blinken ~~~~~~~~~~~~~~~~~~~~~~~~~

TON_01(IN:=NOT DO5ge, PT:=INT_TO_TIME(f)); // DI4 ON mit Zeitverzögerung
DO5ge:=TON_01.Q;
TOF_01(IN:=DO5ge, PT:=INT_TO_TIME(f)); // DI4 OFF mit Zeitverzögerung

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WAIT_3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Count := 0;
Delay(IN:=TRUE, PT:=T#0.5S);
IF NOT(Delay.Q) THEN
RETURN;
END_IF
Delay(IN:=FALSE);

ELSE
DO1 := FALSE; // Lampe DO1 OFF
DO2 := FALSE;
DO3ge := FALSE; // Lampe DO3 OFF
DO4ge := FALSE; // Lampe DO4 OFF
DO5ge := FALSE; // Lampe DO5 OFF


END_IF
AO7 := 1111; // Anzeige P1

END_PROGRAM
 
Siehe LargoD in #5 zum Thema Mehrfachzuweisungen.
Jeden Timer nur einmal verwenden.
Sollte auch für Delay gelten.
 
Mehrfache Zuweisungen auf den gleichen Ausgang im gleichen Zyklus sind in einem SPS-Programm sinnlos.
Es "gewinnt" dann der letzte im Zyklus.
Du musst das Progamm so schreiben, dass es zyklisch aufgerufen werden kann, keine Warteschleifen.
Gruß
Erich
Wie genau implementiert man eine zyklischen Aufruf?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dein Programm wird vom Betriebssystem der SPS zyklisch aufgerufen.
Timer werden nicht benutzt, das Programm zu verzögern, sondern nur die gewünschten Schaltvorgänge.
Du musst Dein Programm so aufbauen, dass jeder Ausgang nur einmal pro Zyklus geschrieben wird.
Gruß
Erich
 
Ich würde es auch wärmstens empfehlen deine Variablen einheitlich zu benennen und die Software nach IF oder WHILE Kontrollstrukturen um einen Tab einzurücken. Das erhöht die Lesbarkeit um einiges. Als kleine Anregung für dein Programm würde ich noch mitgeben, dass du mit einem TON einen Counter von 1-x hochzählst und damit deine LED schaltest. Somit hast du einen Counter, einen Timer und kannst deine Anzahl an LED flexibel anpassen. Wenn du nun noch die LED in einem Array organisierst hast du deine Zuweisung in einer einzigen Anweisung erledigt. Egal wie viele LED du verwendest.
 
Zurück
Oben