Umsetzung Szenenbaustein in ST

Beiträge
432
Reaktionspunkte
18
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich versuche gerade meine Beleuchtungssteuerung etwas zu optimieren, dazu habe ich einen FB Stromstoß etwas geändern.

Folgende Funktion soll erfüllt werden:

Zentral AUS
Zentral EIN
Taster EIN/AUS
Szene EIN (Dauerhaft True)
Szene AUS (Dauerhaft True)

Ich möchte unabhängig ob die Lampe an oder aus ist, auf die Szene umschalten können, wird die Szene wieder deaktiviert, soll der Letzte Zustand davor angenommen werden, Ausser Licht AUS.

Den letzten Zustand annehmen bereitet mir Schwierigkeiten, ich habe versucht das mit einer Statusvariable zu lösen.

Das ist der CODE sowie die Bausteinschnittstelle:

Code:
VAR_INPUT
    xTaster:                BOOL;
    xModbus:                BOOL;
    xZent_Aus:            BOOL;
    xZent_Ein:                BOOL;
    xSzene_Ein:            BOOL;
    xSzene_Aus:            BOOL;

END_VAR
VAR_OUTPUT
    xQ:                        BOOL;
    iStatus:                INT;
END_VAR
VAR
    p_Flanke:              R_TRIG;
    iStatusmerker:        INT;

END_VAR

Code:
p_Flanke(CLK:=xTaster OR xModbus );

IF  p_Flanke.Q  AND NOT xQ THEN
    iStatus:= 100;
ELSIF
    p_Flanke.Q AND xQ THEN
    iStatus:= 101;
END_IF

IF xZent_Aus THEN
    iStatus:= 102;
ELSIF  xZent_Ein THEN
    iStatus:= 103;
END_IF

IF xSzene_Ein THEN
    iStatus:= 104;
    iStatusmerker:= iStatus;
ELSIF  NOT xSzene_Ein THEN
    iStatus:= iStatusmerker;
END_IF

IF xSzene_Aus THEN
    iStatus:= 105;
    iStatusmerker:= iStatus;
ELSIF  NOT xSzene_Aus THEN
    iStatus:= iStatusmerker;
END_IF



CASE iStatus OF

     0:     xQ:= FALSE;
    100: xQ:= TRUE;
    101: xQ:= FALSE;
    102: xQ:= FALSE;
    103: xQ:= TRUE;
    104: xQ:= TRUE;
    105: xQ:= FALSE;

END_CASE

Mir Überschreibt es hier den Statusmerker, soviel ist klar. Ich brauche bitte einen Denkanstoß in die richtige Richtung.
Der Baustein soll einfach Bitorientiert gesteuert werden und soll wie ich es will beliebige Zustände annehmen.

Ich wäre um einen Tipp dankbar.
 
Zentral AUS
Zentral EIN
Taster EIN/AUS
Szene EIN (Dauerhaft True)
Szene AUS (Dauerhaft True)
Zentral: "override" von 1 Stelle aus
Taster: viele individuelle "vor Ort"?, die jeweils 1 Lampe(-nGruppe) schalten?
Szene: wird wo/wie definiert/abgespeichert? Ist wo abrufbar? Hat Einfluss auf wieviele/welche/alle Lampen?
Der Baustein soll einfach Bitorientiert gesteuert werden und soll wie ich es will beliebige Zustände annehmen.
Aus "Zentral" und "Szene" schliesse ich, dass es um etliche Lampen(-Gruppen) geht. Was heisst "bitorientiert" steuern? Willst Du für jede Lampe(-nGruppe) einen FB-Aufruf spendieren?
Um wieviele Lampen(-Gruppen) geht es?
Aus wievielen (verschiedenen) Szenen soll ausgewählt werden?
Wäre es evtl. sinnvoller z.B. "Zentral AUS" als Szene 0, "Zentral EIN" als Szene 1, "Zustand vor Szene EIN" als Szene 2, Szene A als Szene 3, Szene B als Szene 4, u.s.w. zu benandeln?
Z.B. in einem Array von DoppelWorten für bis zu 31 Lampen(-Gruppen)?
Wäre schon interessant zu wissen, welche "Manipulationen" nach "Zentral AUS" bzw. "Zentral EIN" bzw. Anwahl einer "Szene" zulässig sind und in wieweit sie den "Zustand vor Anwahl von Szene" beeinflussen dürfen.

Gruss, Heinileini
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi, danke für deine Mühe.

Also dieser FB soll eigentlich über DO an der SPS die Leuchte über Taster oder Visu bei Bedarf schalten. Zusätzlich soll Zentral ein und Aus alles überschreiben falls benötigt.
Wenn ich jetzt z.B eine Szene z.B. ALLES AN über einen vorher definierten Merker auf True setze dann soll am Eingang xSzene_Ein 1 Signal anstehen.
Bei einer anderen Szene könnte dann z.B ein 0 Signal anstehen, je nachdem welche Leuchte in eine Szene aufnehmen möchte.

Die Szenenbefehle kommen von extern. Jede Leuchte bekommt bei mir einen FB (Erweiteter Stromstoßschalter). Ich weiß man könnte das alles in einem Schubs in nem Struct, oder Array varINOUT usw. erledigen, wäre viel eleganter, aber das verstehe ich dann nach 3 Wochen nicht mehr, falls ich das Programm erweitern möchte.

Was heisst "bitorientiert" steuern?
Das die VarIN des Fb,s über Tastereingänge oder Bit von Visu oder Bit von Szenebaustein gesteuert werden.

Am elegantesten wäre es meiner Meiner Meinung nach einen VarInOut zu definieren und hier von Tastern oder Szene Baustein einen Status als Byte zu übergeben.

Ich weiß einfach nicht wie ich den aktuellen Status speichere, ich möchte das wenn ich die Szene wieder deaktiviere das der letzte Status der vor der Szene aktiv war wieder aufgerufen wird. Der einzige Status der nach der Szene nicht aufgerufen werden darf ist (Zentral Aus). Aber war z.B. das das Wohnzimmerlicht vor der Szene aktiv soll es nach der Szene wieder aktiv sein, sonst stehe ich ja im dunkeln da.

Ich hoffe ich konnte es dir etwas besser verdeutlichen.
 
Zuletzt bearbeitet:
Vor und nach Szene verstehe ich wohl. Aber woher weiss der "StromStossFB", welchen Zustand er bei aktiver Szene herbeiführen soll?
Soll der Zustand während (und trotz) aktiver Szene z.B. durch Taster EIN/AUS verändert werden können?
Mir fehlt irgendwie der Überblick, was Vorrang worüber haben soll u.s.w. …

Gruss, Heinileini
 
Also wenn eine Szene aktiv ist, sollte nur zentral Ein und Aus die Szene überschreiben. Der Taster soll nix machen. Wenn die Szene deaktiviert wird, soll der FB wieder in den vorherigen Zustand zurückfallen, jetzt sollen auch wieder Tastersignale aktiv sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
If xSzeneEIN& And Not xSzeneEINold& Then ' Start von SzeneEIN: aktuellen Status retten
    xRett& = xStatusLampe&
ElseIf Not xSzeneEIN& And xSzeneEINold& Then ' Ende von SzeneEIN: geretteten Status wieder herstellen
    xStatusLampe& = xRett&
ElseIf xSzeneEIN& Then ' Szene aktiv: aktuellen Status entsprechend Vorgabe für Szene
    xStatusLampe& = xStatusSzene&
    End If
xSzeneEINold& = xSzeneEIN&

' xSzeneEINold& wird als FlankenMerker benutzt.
' xRett& wird benutzt, um den Status der Lampe vor "Szeme aktiv" zu retten.
' Beide o.g. Bits müssen also im jeweils nächsten Zyklus unverändert verfügbar sein.
' xSzeneEIN&: nur 1 Bit für SzeneEIN und SzeneAUS! D.h. eigenes Bit für SzeneAUS finde ich überflüssig bis störend.
' Aber ein zusätzliches Bit "xStatusSzene&" wird benötigt, um dem FB zu sagen, welchen Zustand die Lampe bei "Szene aktiv" haben soll!!
Habe mal versucht, es in einer mir geläufigen Schreibweise zu formulieren. Hoffe, es ist (trotzdem) verständlich!?

Gruss, Heinileini
 
Zuletzt bearbeitet:
Ich glaub dass könnte funktionieren, soweit ich das nachvollziehen kann. Ich muss halt das xRett und den xStatus noch auf meine integervariable schreiben.
Ich werde es bei nächster Gelegenheit testen. Danke.
 
Also der Baustein funktioniert soweit.

Hier der Dekl- Teil
Code:
FUNCTION_BLOCK _FB_Stromstoss_3
VAR_INPUT
    xTaster:                BOOL;
    xModbus:                BOOL;
    xZent_Aus:            BOOL;
    xZent_Ein:                BOOL;
    xSzene_EIN:            BOOL;
END_VAR
VAR_OUTPUT
    xQ:                        BOOL;
    iStatus:                INT;
END_VAR
VAR
    p_Flanke:              R_TRIG;
    xTrSzene_EINold:        R_TRIG;
    iRett_Status:             INT;
    xSzene_EINold:         BOOL;
END_VAR


und der Code falls jemand mal sowas braucht.
Code:
p_Flanke(CLK:=xTaster OR xModbus );

IF  p_Flanke.Q  AND NOT xQ THEN
    iStatus:= 100;                                                        (*xQ mit Taster Einschalten*)
ELSIF
    p_Flanke.Q AND xQ THEN
    iStatus:= 101;                                                        (*xQ mit Taster Ausschalten*)
END_IF

IF xZent_Aus THEN
    iStatus:= 102;                                                        (*xQ mit Zentral Aus  Ausschalten*)
ELSIF  xZent_Ein THEN
    iStatus:= 103;                                                        (*xQ mit Zentral Ein  Einschalten*)
END_IF



IF xSzene_EIN AND NOT xTrSzene_EINold.M THEN                 (* Start von SzeneEIN: aktuellen Status retten*)
    iRett_Status := iStatus;
ELSIF NOT xSzene_EIN AND xTrSzene_EINold.M THEN             (* Ende von SzeneEIN: geretteten Status wieder herstellen*)
    iStatus:= iRett_Status;
ELSIF xSzene_EIN THEN                                                 (*Szene aktiv: aktuellen Status entsprechend Vorgabe für Szene*)
   iStatus:= 106;
END_IF

xSzene_EINold := xSzene_EIN;
xTrSzene_EINold(CLK:=xSzene_EINold , Q=> );


CASE iStatus OF
     0:     xQ:= FALSE;
    100: xQ:= TRUE;
    101: xQ:= FALSE;
    102: xQ:= FALSE;
    103: xQ:= TRUE;
    104: xQ:= FALSE; (*Reserve*)
    105: xQ:= TRUE;  (*Reserve*)
    106: xQ:= TRUE;
END_CASE

Das einzige was ich noch austüfftel muss ist. Das der Status bei Szene deaktivieren nicht mehr in Zentral Aus oder Zentral Ein zurückspringt.
Falls jemand am Code was auszusetzen hat, kann er gerne machen, ich bin für jede Verbesserung offen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Also der Baustein funktioniert soweit. …
Das Licht am Ende des Tunnels ist also schon in Sicht!
… Das einzige was ich noch austüfftel muss ist. Das der Status bei Szene deaktivieren nicht mehr in Zentral Aus oder Zentral Ein zurückspringt. …
… auch dann nicht, wenn der letzte Zustand vor SzeneEIN ZentralAUS bzw. ZentralEIN war?
Du könntest doch wahrscheinlich verhindern, dass bei aktivem Zustand ZentralAUS bzw. ZentralEIN der Zustand SzeneEIN angewählt werden kann, dann wäre Dein Problem damit erledigt.

In #3 hast Du einen "SzeneBaustein" erwähnt. Hast Du schon Ideen/Vorstellungen, was der tun und wie der seine Informationen an die zig FB-Aufrufe weitergeben soll?
Ich vermute, das könnte die eigentliche "Baustelle" sein, die Dir noch bevorsteht.

Gruss, Heinileini

PS:
Die vielen Zustände, die Du in der Case-Selektion aufdrieselst, bringen mich zu folgenden Vorschlag.
Den Begriff Zustand würde ich in Zusammenhang mit ZentalAUS, ZentralEIN und SzeneEIN durch den Begriff "BetriebsArt" ersetzen und dann noch die BetriebsArt "Normal" hinzufügen.
Von diesen 4 BetriebsArten ist immer genau 1 aktiv. Ich denke, dass das die Betrachtungsweise vielleicht etwas vereinfacht?
 
auch dann nicht, wenn der letzte Zustand vor SzeneEIN ZentralAUS bzw. ZentralEIN war?
Du könntest doch wahrscheinlich verhindern, dass bei aktivem Zustand ZentralAUS bzw. ZentralEIN der Zustand SzeneEIN angewählt werden kann, dann wäre Dein Problem damit erledigt.
Ich wollte eigentlich nicht zuerst in einen anderen Zustand schalten um die Szene aktivieren zu können, ausser man lässt es im Hintergrund ablaufen.

In #3 hast Du einen "SzeneBaustein" erwähnt. Hast Du schon Ideen/Vorstellungen, was der tun und wie der seine Informationen an die zig FB-Aufrufe weitergeben soll?
Ich vermute, das könnte die eigentliche "Baustelle" sein, die Dir noch bevorsteht.

An dem SzenenEingang kommt ein Oder Glied das z.B. Szene 1 OR Szene 2 OR Szene 3 weiterleitet. Die Bits kommen dann vom Szenen FB.
Der FB ist für über Relais geschaltetene Wandlampen, Steckdosen (Stehlampe) usw. gedacht.
Für Dimmbare Leuchten habe ich für Dali richtige Szenebausteine.

PS:
Die vielen Zustände, die Du in der Case-Selektion aufdrieselst, bringen mich zu folgenden Vorschlag.
Den Begriff Zustand würde ich in Zusammenhang mit ZentalAUS, ZentralEIN und SzeneEIN durch den Begriff "BetriebsArt" ersetzen und dann noch die BetriebsArt "Normal" hinzufügen.
Von diesen 4 BetriebsArten ist immer genau 1 aktiv. Ich denke, dass das die Betrachtungsweise vielleicht etwas vereinfacht?

Ich weiß worauf du hinauswillst, ähnlich wie in der Indsutrie Hand, Auto, Halbauto, Rüstbetrieb. Muss ich mal überlagen wie ich sowas umsetzen kann.
 
Zurück
Oben