Rampenfunktion schreiben

Majestic_1987

Level-1
Beiträge
270
Reaktionspunkte
22
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

ich möchte (ohne den Einsatz der oscat.lib) eine Rampenfunktion erstellen.

Diese soll einen Integer-Wert in einer bestimmten Zeit (Einstellbar, Typ TIME) von 0 bis auf einen definierten Endwert linear erhöhen.

Hat jemand nen Ansatz?
 
Hmmm sollte doch eigentlich die Funktion für eine Gerade ausreichen oder?

y=mx+n
y: dein Integer-Wert
x: die Zeit (z.B. in ms)
m: Anstieg (m=ymax/xmax)
n: ist der Offset

Die time variable kannst du mit time_to_dword in einen Zahlenwert für die Millisekunden konvertieren um damit zu rechnen. T#1m => 60000
 
Also ich habs jetz hinbekommen, das ich einmal die Rampe rauf und einmal die Rampe runter laufen lassen kann.

ABER danach springt der Ausgangswert mit Signalwechsel von 0 auf Maximalwert oder zurück.

Scheint daran zu liegen, dass der Ausgangswert der Timer (ET) auf seinem letzten Wert stehen bleibt. Wie kann ich den zurücksetzen?

Code:
(*Wenn Switch gesetzt inkrementiere Wert in Dimmerklemme über Zeitraum Dimm_Up_Time*)
                    IF Switch = TRUE THEN

                        Timer1(IN:=Switch,PT:=Dimm_Up_Time);                    (*Starte Timer*)

                        Slope := Max_Value_Periperal/TIME_TO_REAL(Dimm_Up_Time);                    (*Steigung der Rampe errechnen*)

                        In_Scenes[Scene_Nr].Q_Dimm := REAL_TO_INT(Slope * TIME_TO_DINT(Timer1.ET));    (*Geradengleichung für Rampe*)

                    (*Wenn Ausgang rückgesetzt dekrementiere Wert in Dimmerklemme über Zeitraum Dimm_Down_Time*)
                    ELSIF Switch = FALSE AND Timer1.Q THEN

                        Timer2(IN:=Timer1.Q,PT:=Dimm_Down_Time);                                        (*Starte Timer*)

                        Slope2 := (Max_Value_Periperal/TIME_TO_REAL(Dimm_Down_Time));                (*neg. Steigung der Rampe errechnen*)

                        In_Scenes[Scene_Nr].Q_Dimm := Max_Value_Periperal - REAL_TO_INT(Slope2 * TIME_TO_DINT(Timer2.ET));    (*Geradengleichung für Rampe*)

                    END_IF
 
Ich denke mal du musst die Timer wieder zurücksetzen wenn sie abgelaufen sind, also IN:=false dann sollten auch ET wieder auf 0 stehen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du rufst den 1. Timer nur auf, wenn Switch=True.
D.h. der In-Parameter Deines Timers ist immer True.

Beim 2. Timer genauso, nur dort ist der Eingangswert immer FALSE.

Beide Timer haben am Eingang also immer den gleichen Wert.

Es würde schon reichen, wenn Du beide Timer ausserhalb Deiner
IF-ELSE Anweisung setzen würdest.
 
Da müssen sie aber rein, denn in abhängigkeit verschiedener Zustände sollen diese Timer entweder funktionieren oder nicht. Geht quasi um verschiedene Betriebsmodi.

Bin der Lösung auf der Spur :)
 
Ich komme einfach nich auf nen Grünen zweig.

Ich möchte, wenn "Dimm" = TRUE ist
bei der positiven Flanke an "Start"
Timer1 Starten

Aus dessen Laufzeit errechnet sich mein Integer-Wert bis max 32767.

Wenn dann wieder eine positive Flanke an "Start" kommt soll
Timer2 Starten

Aus dessen Laufzeit wird die Rampe von 32767 auf 0 errechnet.

Kommt nun wieder eine positive Flanke an "Start" soll das ganze oben wieder los gehen.

Irgendwo hakts!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...
Ich möchte, wenn "Dimm" = TRUE ist
bei der positiven Flanke an "Start"
Timer1 Starten

Aus dessen Laufzeit errechnet sich mein Integer-Wert bis max 32767.

Wenn dann wieder eine positive Flanke an "Start" kommt soll
Timer2 Starten

Aus dessen Laufzeit wird die Rampe von 32767 auf 0 errechnet.

Kommt nun wieder eine positive Flanke an "Start" soll das ganze oben wieder los gehen.
...

Ich hab mich mal an diesen Ablauf gehalten. Bin mir aber nicht sicher ob Du das wirklich wolltest. In Deinem Code hast es anders Kommentiert.

Code:
FUNCTION_BLOCK FB_RAMP
VAR_INPUT
  DIMM  : BOOL;
  PT    : TIME;
  VALUE : INT;
END_VAR
VAR_OUTPUT
  OUT : INT;
END_VAR
VAR
  TON_UP   : TON;
  TON_DOWN : TON;
  DIMM_OLD : BOOL;
  UP       : BOOL;
  DOWN     : BOOL;
END_VAR
Code:
(* Geht es hoch oder runter? *)
IF DIMM AND NOT DIMM_OLD THEN
  UP := TRUE;
  IF TON_UP.Q THEN
    DOWN := TRUE;
  END_IF
END_IF

(* Timer *)
TON_UP(IN:=UP, PT:=PT);
TON_DOWN(IN:=DOWN, PT:=PT);

(* Berechnung des Ausgabewerts *)
OUT := REAL_TO_INT((TIME_TO_REAL(TON_UP.ET) - TIME_TO_REAL(TON_DOWN.ET)) / TIME_TO_REAL(PT) * INT_TO_REAL(VALUE));

IF TON_DOWN.Q THEN (* Rücksetzen der Werte *)
  UP   := FALSE;
  DOWN := FALSE;
  OUT  := 0;
END_IF

DIMM_OLD := DIMM; (* Information zur Flankenauswertung *)
 
Zurück
Oben