SUBroutine

S7-kub

Level-1
Beiträge
29
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich verwende nach Auswertung der Funktionstasten F1 - F5 eines Displays die "sub .... end_sub" in Abhängigkeit der betätigten F-Taste.
ganz Easy, 5 Unterprogramme.
Reicht aber nicht, also wird zu Beginn jeder SubRoutine su_F1_0 bis su_F5_0 weiter verzweigt zu su_F1_1 ..... su_F1_5 / su_F2_1 .... su_F2_5 / ...... / su_F5_1 .... su_F5_5. Ergibt, ganz easy, 25 verschiedene Möglichkeiten.

So, nun zum Optimieren:
"Aufenthalt" in su_F1_0 ==> Led in F1 ist ON. Easy.

bei "Aufenthalt" in su_F1_1 oder su_F1_2 oder su_F1_x soll die LED --blinken--.

Klar, eine su_Blinken muss her. Das Dumme ist nun: mit

Sub Blinken;

LED := not LED;
delay(t#1000mS);

End_Sub;

bleibe ich 1 Sekunde im su_Blinken "hängen". Eingaben am Display sollen aber direkt und unabhängig vom LED-Blinken weiterhin in der su_Fx_y sofort möglich sein. Klar, es gibt die Möglichkeit, in jeder der 25 SUBs das Blinken unabhängig zu programmieren. Aber das wäre ja pervers ....

Also meine Frage an die Profis:

Gibt es überhaupt den Weg über eine universelle/taskunabhängige "Blinken-Routine" (evtl mit Übergabe -aktueller individueller TimerWert aus su_yx -??-) und es muss individuell in jeder Sub programmiert werden?

In einer konventionellen SPS ist das kein Thema, da würde ich einfach einen Systemtimer abfragen und der Code kommt ja immer alle 20mS "da vorbei" und aktualisiert den LED-Zustand

BSP
SLC500: XIC S4/6 (1 Sek-Timer) OTE [LED_F1] // LED_F1 hat immer/gleichzeitig den Zustand von Bit S4/6
S7:
U Timer(1Sek)
= LED_F1

Ich weiß, ein simples Problem aber "blöd" zu beschreiben. Sorry.

@Jetter: LED_F1 := flash[flashTime] ==> LED_F1 := flash(t#500mS)
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielleicht sagst du welches Display du hast, dann kann man dir vielleicht helfen...


Grüße

Marcel

sorry, dachte das wäre nicht relevant für das Blinken:

Das LCD34, 2 Zeilen a 25 Zeichen; 5 Funktionstasten.

http://www.jetter.de/industrieautomation/produkte/bediengeraete-deutsch/alphanumerisch/lcd-34.html

Code_im_Projekt:

// Display LCD34
// Merker für Tasten LCD34
Taste_0 : Bool at %mx 2160;
Taste_1 : Bool at %mx 2161;
Taste_2 : Bool at %mx 2162;
Taste_3 : Bool at %mx 2163;
Taste_4 : Bool at %mx 2164;
Taste_5 : Bool at %mx 2165;
Taste_6 : Bool at %mx 2166;
Taste_7 : Bool at %mx 2167;
Taste_8 : Bool at %mx 2168;
Taste_9 : Bool at %mx 2169;
Taste_F1 : Bool at %mx 2201;
Taste_F2 : Bool at %mx 2202;
Taste_F3 : Bool at %mx 2203;
Taste_F4 : Bool at %mx 2204;
Taste_F5 : Bool at %mx 2205;
Taste_R : Bool at %mx 2215;
Taste_C : Bool at %mx 2218;
Taste_Minus : Bool at %mx 2220;
Taste_Punkt : Bool at %mx 2222;
Taste_Enter : Bool at %mx 2219;

// Merker für LED
Led_F1 : Bool at %mx 2224;
Led_F2 : Bool at %mx 2225;
Led_F3 : Bool at %mx 2226;
Led_F4 : Bool at %mx 2227;
Led_F5 : Bool at %mx 2228;

Ende Code_im_Projekt
 
Zuletzt bearbeitet:
Hallo S7-kub,

ich würde für jede LED einen zusätzlichen Merker anlegen und diesen dann in der jeweiligen Subroutine setzen, anstelle des Merkers des LCDs.
Dann einen separaten Task anlegen, der diese zusätzlichen Merker auswertet und den zugehörigen Merker Led_Fx zyklisch ein- und ausschaltet.

Drain
 
Zuletzt bearbeitet:
@Drain

das Sitchwort "separater Task" war der zu lösende Knoten. Keine SUB, ein t_Task_LEDflash. Manchmal ist das Leben sooo einfach.


sub xy
LedAdresse := 2228;
taskrestart t_Blink;
//code sub yx
taskbreak t_Blink;
end_sub;

// ****************************************************************************

// Auswertung indirekte Adressierung einer Variablen "Register LED-Nr."
// der Task wird aus der Subroutine gestartet (taskrestart)
// und nach Rückkehr wieder gestoppt (taskbreak)
// LedAdresse enthält die Registernummer der Led im LCD34 von 2224 (Taste F1) - 2228 (Taste F5)
task t_Blink
loop
flags[LedAdresse] := b_ms_Timer.9; // b_ms_Timer : int at %vl 201000
end_loop;
end_task;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Kub,

ich habe an deiner Ausführung was zu bemängeln.
Das mag funktionieren, sieht aber eher nach S7-Logik aus
Code:
task t_Blink
  loop
    flags[LedAdresse] := b_ms_Timer.9; // b_ms_Timer : int at %vl 201000
  end_loop;
end_task;
Der Task läuft solange durch die loop-Schleife, bis die zugewiesene Taskzeit rum ist und setzt den Merker dabei zigfach neu.

Besser wäre es etwa so
Code:
task t_Blink
  loop
    flags[LedAdresse] := not flags[LedAdresse]; //LED invertieren
    delay(t#500ms);
  end_loop;
end_task;
Wenn der Task durch den Time-Scheduler aufgerufen wird und die Delay-Zeit noch nicht abgelaufen ist, dann wird sofort mit dem nächten Task weitergemacht.

Ist bei kleinen Projekten wohl nicht relevant, wenn aber viel Performance verlangt wird und jede Menge Tasks vorhanden sind kann sich dies schon bemerkbar machen.
Welche Programmiersprache verwendest du, ST oder STX? Mit welcher Hardware?

Grüße Drain
 
Hi Drain,

da hast Du natürlich Recht. Jemand gab mir den Tipp mit dem Blinkmerker und schon war wieder KOP im Kopp. Hat mich von Deiner Version abgehalten. Und ja, ich tendiere immer wieder zur zyklichen (SLC500) Welt, 28 Jahre gebräuchliche Gewohnheiten wird man(n) nicht so schnell los.

Ich nutze JetSym STX 5V0.1 mit der 1.0.0.4er Motion API. 340er CPU / 32DI / 32DO / 2 JetMove 203 / LCD34. So um die 20-25 Tasks.

Ist (erst) mein zweites Projekt. Man wächst ja bekanntlich mit seinen Aufgaben :cool:

Grüße vom Rhein

der Kub
 
Zurück
Oben