# Schalten von Relais verzögern (Lichtschalter mit Relais)



## Darkghost (15 September 2017)

Hallo zusammen,

was kann ich machen, damit wenn ich auf den SPS Taster (Licht Schalter) drücke (gehalten), das Releais nicht mehr als einmal angeschaltet wird?
Ich habe es mit einem Counter, einem R_TRIG und einem RS Baustein versucht aber leider allen Versuchen keine Lösung gefunden.
Programmiert hab ich es aktuell in CFC-.

Hat jemand eine Idee wie ich das einfach in CFC realisieren kann?

Grüße
Stefan


----------



## -J-E- (15 September 2017)

Hier musst du eine Flankenauswertung einsetzen -> Nur bei steigender Flanke wird der Relaisausgang betätigt


----------



## shrimps (15 September 2017)

Hi,
da du ja schon einen r_trig (Flankenauswertung) genutzt hast, wäre hier dein Codeschnipsel angesagt...

Dann sehen wir weiter !
Shrimps


----------



## Dr.MirakulixX (15 September 2017)

Sehe das auch so wie Shrimps. Merkwürdig ist auch das sich ein RS selber resetet.


----------



## oliver.tonn (16 September 2017)

Dr.MirakulixX schrieb:


> Merkwürdig ist auch das sich ein RS selber resetet.


Das Geheimniss kann vermutlich nur gelüftet werden, wenn der TE mal einen Screenshot von seinem Programm hier postet.
Ich schieße hier mal ins Blaue. Der TE möchte über einen Taster etwas ein- und wieder ausschalten (Stichwort: Stromstoßschalter), jedoch beim Drücken des Tasters geht der Ausgang immer fröhlich an und aus. Als er ein SR oder RS Flip-Flop genommen hatte, hat er vemutlich am S-Eingang auf nicht gesetzten Ausgang und betätigtem Taster und am R-Eingang auf gesetztem Ausgang und betätigtem Taster abgefragt und das sorgt dann für Geklapper, da ja abwechselnd in jedem Zyklus die eine und dann die andere Bedingung erfüllt ist und so der Ausgang ständig ein- und ausgeschaltet wird. Wie hier schon erwähnt wurde muss eine Flankenauswertung für den Taster eingesetzt werden, dann sollte es klappen.

Vielleicht hilft dieser Link dem TE weiter:

Stromstoßschalter


----------



## Darkghost (17 September 2017)

Hallo zusammen,

schon mal vielen Dank für die Rückmeldungen.
Als ich den Eintrag geschrieben hatte, hatte ich leider den Code nicht zur Verfügung und dachte evtl. ist das Problem bekannt.

Hier der Code
Im Main Programm steht:

IF boGwcLinksSchlater1 THEN
    IF boGwcDeckenlicht THEN
        boGwcDeckenlicht:=schalten(FALSE,boGwcDeckenlicht);
    ELSE
        boGwcDeckenlicht:=schalten(TRUE,boGwcDeckenlicht);    
    END_IF
END_IF

Schalten ist eine CFC Funktion.





Ich hab jetzt auch mal die Flankenerkennung eingebaut und im Kanal kommt auch nur eine steigende Flanke an, wenn ich den Taster gedrückt halte.
Jedoch schalten das Relais durchgehend bis ich den Taster nicht mehr drücke. (grgrgrgrgrgrgrgr)

Vermutlich liegt das an der IF Anweisung im Main aber wenn ich diese weg lasse dann leuchtet die Lampe nur, wenn ich auf den Taster drücke.

Im Main Programm:
    boGwcDeckenlicht:=schalten(boGwcLinksSchlater1,boGwcDeckenlicht);

Und in der Funktion




Woran kann das denn noch liegen? 

Grüße
Stefan


----------



## santacrews (18 September 2017)

Guten Morgen.

Womit programmierst Du denn?
Bedenke, dass eine Funktion keine Intelligenz hat und sich nicht an den Zustand des letzten Zyklus erinnern kann. Erst recht nicht, wenn Du ein und die selbe Funktion mehrfach aufrufst.
setLicht hat dann beim Aufruf erstmal keinen definierten Zustand!

Ich bin Freund von der XOR Variante. Das spart dir variablen, da Du kein RS mehr brauchst und der Ausgang des Lichts sozusagen dein Merker ist.
Versuchs mal damit.

Weiterhin gibt es mehr als genug standard Bausteine z.B. bei Oscat die fertig sind und noch weiteren Komfort bieten. z.B. einen Tast,Setz,Rücksetz Eingang. Wenns in richtung Lichtszenen geht ist das notwendig...


----------



## Ph3niX (18 September 2017)

santacrews schrieb:


> Ich bin Freund von der XOR Variante. Das spart dir variablen, da Du kein RS mehr brauchst und der Ausgang des Lichts sozusagen dein Merker ist.
> Versuchs mal damit.



Ich finde die XOR-Variante auch immer schön einfach, hier mal als Beispiel:
https://www.sps-forum.de/simatic/10313-funktion-taster-als-schalter-2.html#post69833


----------



## Darkghost (18 September 2017)

Leider bekomme ich das mit dem XOR nicht hin, obwohl ich eigentlich verstehe, wie es funktioniert.

Main:
boWzDeckenlicht:=schalten2(boWzSchlater1,boWzDeckenlicht);

CFC Programm: schalten2

FUNCTION schalten2 : BOOL
VAR_INPUT
	schalter : BOOL;
	beleuchtung : BOOL;
END_VAR
VAR
	setLicht: RS;
	trigSchalten: R_TRIG;
END_VAR



Wenn ich den Taster betätige dann passiert nichts.

Weiß einer warum das nicht klappt?

Grüße
Stefan


----------



## oliver.tonn (18 September 2017)

Hallo Stefan,
zunächst wäre es schön, wenn Du das was man Dir schon erklärt hatte auch umsetzt. In #7 hat santacrews Dir schon erklärt, dass Du keine Funktion sondern einen Funktionsbaustein nehmen musst, weil eine Funktion keine Werte über den Aufruf hinaus behält (Außer mit Klimmzügen) und außerdem lokale Variablen aufgrund dieses Umstandes vor dem Lesen erst beschrieben werden müssen. Aus diesem Grund wird auch die Flankenauswertung nicht funktionieren, weil sie einfach nicht weiß welcher Zustand beim vorherigen Aufruf am Eingang war und für sie jeder Aufruf quasi der Erste ist, sie aber erst nach dem zweiten Aufruf funktioniert. Setz das was in #7 steht erstmal um, teste es und dann sehen wir weiter. Ansonsten sieht das was Du gemacht hast nämlich korrekt aus.

Von irgendwas mit Internetzugang gesendet


----------



## PN/DP (18 September 2017)

Damit mit einem XOR ein Bit invertiert werden kann muß ein XOR-Eingang gleich dem XOR-Ausgang sein. Der andere XOR-Eingang bestimmt, ob der erste Eingang invertiert (bei 1) oder nicht invertiert (bei 0) zum Ausgang übernommen wird.

Ein Stromstoßschalter mit XOR sieht in CFC so aus:

```
+------------+
           |   R_TRIG   |
Taster-----|CLK        Q|---+   +-------+
           +------------+   |   |  XOR  |
                            +---|       |------Lampe
Lampe---------------------------|       |
                                +-------+
```

Harald


----------



## Darkghost (22 September 2017)

Vielen Dank für die Erklärung und die Zeichnung.
Habs denke ich jetzt verstanden aber leder muss ich noch einen Fehler in der Programmierung haben, da R_Trig nicht reagiert.
Vermutlich ist es ganz einfach aber ich steh da irgendwie auf dem Schlauch...

Ich hab jetzt einen Funktion Block genommen. Code:
FUNCTION_BLOCK lichtSchalten
VAR_INPUT
	schalter:BOOL;
	beleuchtung : BOOL;
END_VAR
VAR_OUTPUT
	lampe : BOOL;
END_VAR
VAR
	trig_schalter: R_TRIG;
END_VAR




Nur wie rufe ich den jetzt im Main auf?

So geht es zumindest nicht... 

IF boWzSchalterLi THEN
	lichtSchaltenWz.schalter:=boWzSchalterLi;
	lichtSchaltenWz.beleuchtung:=boWzDeckenlicht;
	boWzDeckenlicht:=lichtSchaltenWz.lampe;
END_IF


Grüße
Stefan


----------



## PN/DP (26 September 2017)

Dein R_TRIG funktioniert nicht richtig, weil Du die FB-Instanz nur aufrufst wenn der Lichtschalter gedrückt ist (IF boWzSchalterLi THEN...). Der R_TRIG kann so keine Flanke erkennen. R_TRIG muß auch (mindestens einmal) aufgerufen werden, wenn der Eingang FALSE ist, damit das nachfolgende TRUE als steigende Flanke erkannt wird.


Nochmal: damit der Stromstossschalter invertierend funktioniert muß der Eingang und der Ausgang die selbe Variable sein (oder umständlicher Dein Eingang "beleuchtung" und Dein Ausgang "lampe" beim FB-Aufruf mit der selben Variable beschaltet werden). Wenn ein FB-Parameter Eingang und Ausgang sein soll, dann muß er als VAR_IN_OUT deklariert werden:

```
FUNCTION_BLOCK lichtSchalten
VAR_INPUT
  Taster : BOOL;
END_VAR
VAR_IN_OUT
  Lampe : BOOL;
END_VAR
VAR
  trig_schalter : R_TRIG;
END_VAR
```

Ich kenne Codesys nicht gut, doch vermutlich mußt Du in Deinem Main (oder als globale Variable?) eine Instanz Deines FB "lichtSchalten" deklarieren. Und dann aufrufen und beschalten (etwa so, nicht getestet):

```
VAR_GLOBAL
  lichtSchaltenWz : lichtSchalten;
END_VAR

lichtSchaltenWz(Taster:=boWzSchalterLi, Lampe:=boWzDeckenlicht);
```

Harald


----------



## oliver.tonn (26 September 2017)

Oh Mann, da war ich mal wieder betriebsblind, danke Harald. Das er den FB nur aufruft wenn der Taster gedrückt ist hatte ich ganz ignoriert. Soviel zu dem Thema "Das was er macht sieht ansonsten richtig aus".


----------



## PN/DP (26 September 2017)

oliver.tonn schrieb:


> Oh Mann, da war ich mal wieder betriebsblind


Das ist aber auch schwer zu erkennen, besonders wenn man nicht genau weiß, welcher Code denn nun gerade verwendet wird:
- in #6 ruft er die Function zuerst nur auf wenn der Taster gedrückt ist, in der zweiten Variante immer aufrufen ohne das IF funktioniert aber auch nicht richtig
- in #9 ruft er die Function immer auf
- in #12 ruft er die FB-Instanz gar nicht auf (*), sondern kopiert nur Ein- und Ausgänge, aber nur wenn der Taster gedrückt ist

(*) was ich auch zuerst nicht so genau gesehen habe, so daß meine Erklärung eigentlich falsch ist

Harald


----------



## Darkghost (8 Oktober 2017)

Danke für Eure Rückmeldungen habe jetzt erst mal den "Code" auf die oberste Ebene gelegt, so wird jetzt R_TRIG immer ausgeführt. Werde in den nächsten Tagen dann mal schauen, dass in einen FB zu packen.


----------

