3fach-Blinker

clumsi

Level-2
Beiträge
142
Reaktionspunkte
0
Hallo,

da ich aus der C-basierten Steuerungsprogrammierung komme, habe ich noch sehr wenig Erfahrung mit der typischen SPS-Programmierung. Ein einfaches Blinksignal konnte ich jedoch schon mit zwei hintereinander geschalteten TOF-Funktionen realisieren. Auch die Funktionsweise ist mir davon klar.

Wo ich allerdings noch auf dem Schlauch stehe, ist bei der Erstellung eines einfachen 3fach-Blinklichtes: Ein Leuchtring bestehend aus drei LED-Kreisen soll "rotieren", d.h. Die Ausgänge 1, 2 und 3 sollen der Reihe nach mit einstellbaren Pausen- und Ein-Zeiten angesteuert werden.

Ich habe leider keine richtige Idee, wie man das macht. Habt ihr dafür ein Beispiel?

Grüße,
clumsi
 
Du könntest einen Zähler rotieren lassen. Dh. mit TON Addieren und bei Schalten des zugehörigen TON die Variable +1 hochzählen. Bei dem ersten setzt du sie dann wieder auf 1, naja ein Ringzähler eben. Die Ausgänge verknüpfst du einfach mit ==.
 
Nimm eine Schrittkette, wie schon von #3 empfohlen. Für "Hochsprachenprogrammierer" ist das "Zyklische" der SPS am Anfang das größte Problem. Eine Schrittkette kann das "entschärfen".
Legt sich aber :)
 
Hallo clumsi,
mir hatten damals auch echte Beispiele geholfen.
Ich habe da mal eins als Twincat2 angefügt.
Ist nur in ST geschrieben.
Viel Spaß beim verstehen.
Code:
PROGRAM Blinker3
VAR_INPUT
    EN                : BOOL;    (* Ein- / Ausschalten *)
END_VAR
VAR_OUTPUT
    Q1                : BOOL;        (* Ausgang 1 *)
    Q2                : BOOL;        (* Ausgang 2 *)
    Q3                : BOOL;        (* Ausgang 3 *)
END_VAR
VAR
    iSchritt        : INT;        (* Schrittkette *)
    Timer            : TON;        (* Unser Takt *)
END_VAR
VAR CONSTANT
    def_tArbeit1        : TIME    := t#3s;
    def_tPause1            : TIME    := t#2s;
    def_tArbeit2        : TIME    := t#3s;
    def_tPause2            : TIME    := t#2s;
    def_tArbeit3        : TIME    := t#3s;
    def_tPause3            : TIME    := t#2s;
END_VAR

Timer(); (* Wir brauchen ja ständig einen Zeitnehmer ! *)

(* Wenn Modul abgeschaltet wird, immer Init *)
iSchritt := iSchritt * BOOL_TO_INT(EN);


(* Unsere Schrittkette *)
CASE iSchritt OF
0:    (* Init *)
    Q1 := Q2 := Q3 := FALSE;        (* Alles Aus ! *)
    Timer.IN         := FALSE;        (* Timer ausschalten *)

    IF EN THEN                        (* Warten auf Modulaktiv *)
        iSchritt  := 10;            (* Auf gehts *)
    END_IF


10:    (* Q1 Arbeit *)
    Q1 := TRUE;                    (* Ausgang einschalten *)
    Timer.PT := def_tArbeit1;    (* Arbeitszeit vorgeben *)
    Timer.IN := TRUE;        (* Timer einschalten *)
    IF Timer.Q THEN            (* Zeit erreicht ? *)
        Timer.IN := FALSE;    (* Timer ausschalten *)
        iSchritt := 20;        (* Auf gehts *)
    END_IF

20:    (* Q1 Pause *)
    Q1 := FALSE;            (* Ausgang ausschalten *)
    Timer.PT := def_tPause1;    (* zeit vorgeben *)
    Timer.IN := TRUE;        (* Timer einschalten *)
    IF Timer.Q THEN            (* Zeit erreicht ? *)
        Timer.IN := FALSE;    (* Timer ausschalten *)
        iSchritt := 30;        (* Auf gehts *)
    END_IF

30:    (* Q2 Arbeit *)
    Q2 := TRUE;                    (* Ausgang einschalten *)
    Timer.PT := def_tArbeit2;    (* Arbeitszeit vorgeben *)
    Timer.IN := TRUE;        (* Timer einschalten *)
    IF Timer.Q THEN            (* Zeit erreicht ? *)
        Timer.IN := FALSE;    (* Timer ausschalten *)
        iSchritt := 40;        (* Auf gehts *)
    END_IF

40:    (* Q2 Pause *)
    Q2 := FALSE;            (* Ausgang 1 ausschalten *)
    Timer.PT := def_tPause2;    (* zeit vorgeben *)
    Timer.IN := TRUE;        (* Timer einschalten *)
    IF Timer.Q THEN            (* Zeit erreicht ? *)
        Timer.IN := FALSE;    (* Timer ausschalten *)
        iSchritt := 50;        (* Auf gehts *)
    END_IF

50:    (* Q3 Arbeit *)
    Q3 := TRUE;                    (* Ausgang einschalten *)
    Timer.PT := def_tArbeit3;    (* Arbeitszeit vorgeben *)
    Timer.IN := TRUE;        (* Timer einschalten *)
    IF Timer.Q THEN            (* Zeit erreicht ? *)
        Timer.IN := FALSE;    (* Timer ausschalten *)
        iSchritt := 60;        (* Auf gehts *)
    END_IF

60:    (* Q3 Pause *)
    Q3 := FALSE;            (* Ausgang 1 ausschalten *)
    Timer.PT := def_tPause3;    (* zeit vorgeben *)
    Timer.IN := TRUE;        (* Timer einschalten *)
    IF Timer.Q THEN            (* Zeit erreicht ? *)
        Timer.IN := FALSE;    (* Timer ausschalten *)
        iSchritt := 0;        (* Auf gehts / Anfang *)
    END_IF

END_CASE
 
Danke für Eure Antworten! Das Programm von shrimps sieht gut aus; werde ich mir ansehen und ausprobieren.

In der Zwischenzeit habe ich durch viel Probieren etwas hinbekommen, was auch erst mal funktioniert. In C hätte ich es sicherlich viel besser und einfacher hinbekommen, aber wie roman06 schon geschrieben hat, fällt mir das Umdenken von meinen eventbasierten C-Programmen in das Zyklische noch etwas schwer.

Deshalb sind meine SPS-Programme auch noch nicht sauber und schön programmiert, es geht bestimmt an vielen Stellen eleganter..... ;)

Was soll das Programm machen (funktioniert auch):
- Bei Not-Aus sollen alle drei LED-Kreise des Leuchtringes im gleichen Takt von T1 blinken.
- Wenn Zweihand betätigt sollen die drei LED-Kreise nach rechts rotieren (Lauflicht)
- Wenn Stoessel_auf sollen die LED nach links rotieren.
Dazu wird je nach Richtung hoch- oder runtergezählt.

Hier ist das Programm zu finden: https://drive.google.com/file/d/0B04URgYdVAnnNGY3N1dwbmtHSkE/view

Ich weiß, schön ist es nicht. Aber es funktioniert.
Die ST-Variante wäre mir später sicherlich lieber, aber für den Anfang würde ich dieses Programm gerne erst mal "in sauber" in KOP oder FUP aufbauen, um mich besser an das grafische zu gewöhnen.

Wenn ihr Tipps für das Programm habt, nehme ich sie gerne an.

VG,
clumsi
 
Zurück
Oben