Anfängerfrage: Analogausgang Wert mehrmals im Programm Wert zuweisen????

KingHelmer

Level-1
Beiträge
1.076
Reaktionspunkte
139
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo liebe Leute, ich bins mal wieder.

Ich habe wieder ein problem im Programm, wobei ich sagen muss, dass bisher alles rund geklappt hat.

Ich habe ein Programm geschrieben zum Dimmen und Szenen einstellen bei LED-Leuchten. Es handelt sich um RGB-LEDS und ich steuere ein PWM-Modul mit 0-10V an.

Erklären wäre sehr schwierig, ich glaube ein Code hilft hier mehr:

Funktionsblock für das Dimmen:

Code:
Instanz1_GEN_PULSE(ENQ:=DIM_Hoch , PTH:= (Zeitintervall_Puls/2), PTL:=(Zeitintervall_Puls/2) , Q=> );   
Instanz2_GEN_PULSE(ENQ:=DIM_Runter , PTH:= (Zeitintervall_Puls/2), PTL:=(Zeitintervall_Puls/2) , Q=> );
Instanz1_Fb_Stromstoss(
    xTaster:=Licht_Einschalten ,
    xZenAUS:=FALSE ,
    xZenEIN:=FALSE ,
    bResetModus:=,
    xAktor=>Merker_EIN );
IF Merker_EIN = TRUE
THEN Rueckmeldung_AN := TRUE;
ELSE Rueckmeldung_AN:= FALSE;
END_IF;
Instanz1_CTUD(
    CU:= (Instanz1_GEN_PULSE.Q AND NOT Zaehler_Obergrenze),
    CD:= Instanz2_GEN_PULSE.Q,
    PV:= REAL_TO_INT(((TIME_TO_REAL(Dimmdauer)/TIME_TO_REAL(Zeitintervall_Puls))/100)*Einschalthelligkeit_Prozent),
    QU=> ,
    QD=> ,
    CV=> );
Instanz1_R_TRIG(CLK:=Merker_EIN , Q=>Instanz1_CTUD.LOAD );
Instanz1_F_TRIG(CLK:=Merker_EIN , Q=>Instanz1_CTUD.RESET );
Zaehlerwert:=LIMIT(0,Instanz1_CTUD.CV*((32761*TIME_TO_INT(Zeitintervall_Puls))/TIME_TO_INT(Dimmdauer)), 32761);
Ausgabe_Analogausgang:=Zaehlerwert;
IF Zaehlerwert >= 32761 THEN
Zaehler_Obergrenze:=TRUE;
ELSE Zaehler_Obergrenze:=FALSE;
END_IF;

Hier wird ein Zählerwert gesetzt, der mittels einem Impulsgeber (GEN_PULSE) erhöhr und erniedrigt werden kann in Stufen, die von einer eingegebenen Dimmdauer abhängig sind.
Das funktioniert ALLEINE wunderbar. Jedoch habe ich nun auch einen Block für das Einstellen von Lichtszenen erstellt, siehe hier:

Code:
Instanz1_F_TRIG(                    CLK:=Szene1_ON_OFF , Q=>MTRIG1 );
Instanz2_F_TRIG(                    CLK:=Szene2_ON_OFF , Q=>MTRIG2 );
Instanz3_F_TRIG(                    CLK:=Szene3_ON_OFF , Q=>MTRIG3 );
Instanz4_F_TRIG(                    CLK:=Szene4_ON_OFF , Q=>MTRIG4 );

IF MTRIG1 THEN
Analogausgang_ROT             := REAL_TO_INT((INT_TO_REAL(RotwertProzentS1)/100.0)*32761.0);
Analogausgang_BLAU            := REAL_TO_INT((INT_TO_REAL(BlauwertProzentS1)/100.0)*32761.0);
Analogausgang_GRUEN            := REAL_TO_INT((INT_TO_REAL(GruenwertProzentS1)/100.0)*32761.0);
ELSIF MTRIG2 THEN
Analogausgang_ROT             := REAL_TO_INT((INT_TO_REAL(RotwertProzentS2)/100.0)*32761.0);
Analogausgang_BLAU            := REAL_TO_INT((INT_TO_REAL(BlauwertProzentS2)/100.0)*32761.0);
Analogausgang_GRUEN            := REAL_TO_INT((INT_TO_REAL(GruenwertProzentS2)/100.0)*32761.0);
ELSIF MTRIG3 THEN
Analogausgang_ROT             := REAL_TO_INT((INT_TO_REAL(RotwertProzentS3)/100.0)*32761.0);
Analogausgang_BLAU            := REAL_TO_INT((INT_TO_REAL(BlauwertProzentS3)/100.0)*32761.0);
Analogausgang_GRUEN            := REAL_TO_INT((INT_TO_REAL(GruenwertProzentS3)/100.0)*32761.0);
ELSIF MTRIG4 THEN
Analogausgang_ROT             := REAL_TO_INT((INT_TO_REAL(RotwertProzentS4)/100.0)*32761.0);
Analogausgang_BLAU            := REAL_TO_INT((INT_TO_REAL(BlauwertProzentS4)/100.0)*32761.0);
Analogausgang_GRUEN            := REAL_TO_INT((INT_TO_REAL(GruenwertProzentS4)/100.0)*32761.0);
END_IF;

Das ist ein Auszug aus dem FB.

Man sieht hier nun, dass der gleiche Analogausgang, z.B. Analogausgang_ROT 2 x gesetzt wird. Einmal kann man ihn dimmen und einmal kann man einen Wert darauf schrieben mit einer Taste "Szene1_ON_OFF".
Allerdings kan ich in der Visu nur das setzen von Szenen benutzen, die Dimmfunktion bleibt funktionslos, obwohl in der Instanz im Online-modus ein Wert korrekt gesetzt wird.

Nun die eigentliche Frage:

Kann ich eine Variable an zwei Ausgängen von FBs zuweisen?
Ich meine, wenn der eine FB der Variablen keinen Wert zuweisst, weisst er ihr dann den Wert 0 zu?

Vieleicht hat jemand interesse , mal mein Programm anzusehen. ich könnte es per Email versenden, hier hochladen funktioniert anscheinend nicht.
Es wäre auch eine Visu dabei, mit der die Funktionsweise klar wird!

Mein Gott, das ist so schwer zu beschreiben......

Grüße,

Florian
 
Hallo,
so eine kleine Anregung hätte ich (ohne jetzt tiefer in der gezeigten Code eingestiegen zu sein) :
Du könntest bei den Variablen der Farbwerte mit Array's arbeiten. Dann könnte die Zuweisung auf die Schnittstelle dann so aussehen :
Code:
Auswahl := 1 ;  // Default-Einstellung
IF MTRIG1 THEN
   Auswahl := 1 ;
ELSIF MTRIG2 THEN
   Auswahl := 2 ;
ELSIF MTRIG3 THEN
   Auswahl := 3 ;
ELSIF MTRIG4 THEN
   Auswahl := 4 ;
END_IF;

Analogausgang_ROT      := REAL_TO_INT((INT_TO_REAL(RotwertProzent[Auswahl])/100.0)*32761.0);
Analogausgang_BLAU              := REAL_TO_INT((INT_TO_REAL(BlauwertProzent[Auswahl])/100.0)*32761.0);
Analogausgang_GRUEN := REAL_TO_INT((INT_TO_REAL(GruenwertProzent[Auswahl]S4)/100.0)*32761.0);
... das spart auf jeden Fall schon mal Programmcode (und ist vielleicht auch ein bißchen übersichtlicher ;))
Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Larry Laffer,

Ich habe noch nie arrays benutzt.
Eine "Auswahl" würde dann ja aber aus vier verschiedenen Werten bestehen. Wie kann ich das
mit einbringen?
Ich will ja für jede Szene die Prozentwerte der Helligkeit, also des Integer-Wertes für den jeweiligen AO angeben können.
Außerdem würde mit einer Default einstellung ja immer der Wert von Einstellung 1 gesetzt werden. Es soll aber auch gedimmt werden können.
Das hieße, es soll kein wert gesetzt werden, wenn keine Taste gedrückt wird.

Nur bei positiver Flanke soll ein Wert gesetzt werden.

Mit Arrays konnte ich mich leider noch überhaupt nicht beschäftigen. trifft man allerdings häufig an!

Danke dir trotzdem!!!
 
... also als erstes würde ich vorschlagen : mach das mal mit den Array's (also beschäftige dich damit).
Die Umsetzung, die du siehst, bezieht sich auf dein Code-Beispiel. Das kann natürlich auch noch ganz anders werden, so dass du ggf. mehrere 1000 Lichtszenen verwalten kannst - das ist mehr eine Frage deiner Fantasie ...
Das mit der Default-Auswahl habe ich so gemacht, weil es mir erstmal nicht besser eingefallen ist - aber was spricht (bei keiner Anwahl) dagegen ?
Die Werte bekommst du in dein Array so wie du sie jetzt in die Einzel-Elemente bekommst.

Gruß
Larry
 
Dein Hauptproblem ist wohl, dass du zuerst dimmst und danach schreibst du dann den Szenenwert auf deine Variable. Am Zyklusende wenn das PAW rausgeschrieben wird, sind da dann die Szenenwerte drin.

Ein Lösungsansatz wäre, das entsprechende NW nur dann ausführen, wenn eine neue Eingabe erfolgte, sonst das NW überspringen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
mach das mal mit den Array's (also beschäftige dich damit).

Ich denke, da hast du recht. Ich habe in den letzten Tagen so viel neues gelernt, es ist unglaublich.
Ich muss mich natürlich auch da rantasten, ich werde mir auch ein Buch zu ST bestellen und zuhause üben und lernen. Ich meine, was gibt es interessanteres?

Dein Hauptproblem ist wohl, dass du zuerst dimmst und danach schreibst du dann den Szenenwert auf deine Variable. Am Zyklusende wenn das PAW rausgeschrieben wird, sind da dann die Szenenwerte drin.
Ein Lösungsansatz wäre, das entsprechende NW nur dann ausführen, wenn eine neue Eingabe erfolgte, sonst das NW überspringen.

Ich hatte es schon vermutet. Ich muss mir also etwas einfallen lassen, wie ich diesen FB praktisch "ausblende" bis eine Eingabe an den Szenentastern erfolgt.
Eventuell über eine "Enable" Variable im PLC_PRG, welches den Aufruf des Szenen-FBs ein-/ausschaltet.
Wenn ich mit dem gleich trigger, also der positiven Flanke von einem der Taster für Szenen den Enable-Befehl trigger, wird die positive Flanke dann auch im gleichen Zyklus noch im FB_Aufruf verarbeitet?

Danke euch für die Beiträge!

Grüße, Florian
 
Ich hatte es schon vermutet. Ich muss mir also etwas einfallen lassen, wie ich diesen FB praktisch "ausblende" bis eine Eingabe an den Szenentastern erfolgt.
Eventuell über eine "Enable" Variable im PLC_PRG, welches den Aufruf des Szenen-FBs ein-/ausschaltet.
Wenn ich mit dem gleich trigger, also der positiven Flanke von einem der Taster für Szenen den Enable-Befehl trigger, wird die positive Flanke dann auch im gleichen Zyklus noch im FB_Aufruf verarbeitet?
Das lässt sich sicher irgendwie hintricksen. Aber wenn Du noch eine weitere Möglichkeit zur Steuerung der RGB-Ausgänge einbauen willst, stehst Du wieder vor dem gleichen Problem.
Ich würde es lieber so machen, dass der Dimm-FB einen Real-Wert von 0.0 bis 1.0 für den Gesamt-Dimmgrad ausgibt und der Szenen-FB drei Reals für die RGB-Stellgrade und damit nur an einer Stelle im Hauptprogramm auf die Ausgänge schreiben, z. B.
Analogausgang_Rot:=Real_to_Word(Dimm-Stellgrad*Rot-Stellgrad*32767);
Wenn keine Szene angewählt ist, muss der Szenen-FB dann für RGB jeweils 1.0 ausgeben, damit nur der Dimmer aktiv ist.
 
Hi Structered Trash,

ich war in den letzten Tagen nicht da, sonst hätte ich deine (gar nicht mal so schlechte) Idee versucht, umzusetzen.

mittlerweile habe ich das hier geschrieben, allerdings setzt das Anschalten keinen Analogwert.
Ich habe keine Ahnung wora es liegen könnte....

Code:
FUNCTION_BLOCK NEUNEUNEUNEUNEU
VAR_INPUT
    Einschalthelligkeit: INT;
    Szene1_Prozent: INT;
    Szene2_Prozent: INT;
    Szene3_Prozent: INT;
    Szene4_Prozent: INT;
    Licht_EIN_AUS: BOOL;
    Szene1_EIN: BOOL;
    Szene2_EIN: BOOL;
    Szene3_EIN: BOOL;
    Szene4_EIN: BOOL;
END_VAR
VAR_OUTPUT
    Analogwert_Ausgabe: INT;
END_VAR
VAR
    Analogwert: INT;
    Instanz1_R_TRIG: R_TRIG;
    Instanz2_R_TRIG: R_TRIG;
    Instanz3_R_TRIG: R_TRIG;
    Instanz4_R_TRIG: R_TRIG;
    Instanz5_R_TRIG: R_TRIG;
END_VAR

(*Ende der Deklaration*)

Instanz1_R_TRIG(CLK:=Licht_EIN_AUS);
Instanz2_R_TRIG(CLK:=Szene1_EIN);
Instanz3_R_TRIG(CLK:=Szene2_EIN);
Instanz4_R_TRIG(CLK:=Szene3_EIN);
Instanz5_R_TRIG(CLK:=Szene4_EIN);

IF Analogwert = 0 AND Instanz1_R_TRIG.Q = TRUE THEN
Analogwert := (Einschalthelligkeit/100) * 32761;
ELSIF Analogwert > 0 AND Instanz1_R_TRIG.Q = TRUE THEN
Analogwert := 0;
ELSIF Instanz2_R_TRIG.Q = TRUE THEN
Analogwert := Szene1_Prozent;
ELSIF Instanz3_R_TRIG.Q = TRUE THEN
Analogwert := Szene2_Prozent;
ELSIF Instanz4_R_TRIG.Q = TRUE THEN
Analogwert := Szene3_Prozent;
ELSIF Instanz5_R_TRIG.Q = TRUE THEN
Analogwert := Szene4_Prozent;
END_IF;

Analogwert_Ausgabe:=Analogwert;

Wie gesagt, ich ahbe keine Ahnung, warum mir bei eingegegebener "Einschalthelligkeit" von 80 (prozent) kein Analogwert gesetzt wird.
Der Wert bleibt auf 0. Szenen setzen hingegen funktioniert! Auch das Ausschalten funktioniert!

Unerklärlich für mich ....
 
Zuviel Werbung?
-> Hier kostenlos registrieren
"Einschalthelligkeit" ist ein INT, und das Ergebnis einer INT-Division ist ebenfalls ein INT. 80/100 ist dann 0 Rest 80, und der Rest fällt weg.
Du musst "Einschalthelligkeit" als REAL anlegen und dann schreiben:
Analogwert:=REAL_TO_INT((Einschalthelligkeit/100.0)*32761.0);
Möglicherweise reicht auch schon die "100.0" in der Division, denn die wird dann als REAL-Konstante interpretiert. Das Ergebnis müsste dann eigentlich auch REAL sein. Probier es einfach mal aus.
 
Zuletzt bearbeitet:
Oh man bin ich blöd :D

Danke für die Antwort, hätte ich mir denken können!
Hast dein Danke redlich verdient :D

Jetzt kann ich weitermachen :)

Grüße!
 
Zurück
Oben