TIA Steilheitsbegrenzer mit Rundung

pasnos

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

ich bin ein Einsteiger mit TIA und wollte einen Steilheitsbegrenzer mit Rundung programmieren. Mein Ziel ist es, einen Steilheitsbegrenzer mit Rundung für Antriebssollwert zu programmieren (Sinamics hat es auch im Sollwertkanal drin, ich weiß, aber ich will auch in SPS so eine Funktion haben). Es ist auf SCL geschrieben. Das ist meine erste Annäherung aufs Thema und ich möchte auch gerne eure Meinung dazu haben, inwiefern meine Annäherung richtig/falsch ist und wie weit von einer Realisierung in einer Applikation wäre. Ins Programm werden nur Werte von 0..100 angezeigt, es gibt noch keine richtige Verriegelung usw., also nutzt ihr bitte nur Werte innerhalb dieses Bereiches. Ich danke euch im Voraus!

pm
 

Anhänge

  • TIA_test_Project1_171215.rar
    2,2 MB · Aufrufe: 27
Hallo pasnos,
wäre hier nicht die SMC (Standard Motion Control) Funktionalität besser? Hier kannst du alles einstellen Beschleunigung, Verzögerung, Ruckbegrenzung für Antriebe.
Dazu musst du unter Technologie Objekte z.B. eine analoge Drehzahlachse anlegen und den Adressbereich von deinem Sollwert des Antriebsauswählen und dann die gewünschten Parameter einstellen. Danach kannst du dasTechnologie Objekt mit den Motion Control Befehlen verfahren.
Gr Michitronik
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Michitronik,

danke fuer deine Antwort! Du hast Recht, ich verstehe, dass eine standadisierte Bibliothek viel besser ist. Aber es geht darum, dass ich meine eigene Funktion fuer Steilheitsbegrenzer mit Rundung programmieren moechte. Da aber alle diese Standardbausteine immer Know-How Schutz haben und alles geschuetzt ist, wollte ich "rausfinden" was da drin programmiert sein koennte! Deswegen wollte auch eure Meinung dazu haben, wie weit von der Realitaet so ein Baustein waere :p

MfG
pm
 
Hallo,
wie wäre es, wenn du den Code deines Berechnungs-Bausteins mal als Text hier einstellst.
Ich habe z.B. gar kein TIA um mir dein Projekt ansehen zu können ...

Gruß
Larry
 
Hallo,

gerne mach ich. Hier ist die von TIA erzeugte SCL Quelle. Die soll auch in version5.5 eingesetzt werden koennen.

Code:
FUNCTION_BLOCK "FB_RFG_W_RND1"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      i_x : Int;   // setpoint
      i_high : Real;
      i_low : Real;
      i_rampTime : Real;   // ramp time
      i_RndTime : Real;   // rounding time
      i_Clock : Bool;
      i_reset : Bool;
   END_VAR

   VAR_OUTPUT 
      o_Y : Real;
   END_VAR

   VAR 
      error : Real;
      deadband : Real;
      timer1 : Int;
      Imp_Clock : Bool;
      YB : Real;
      YA_new : Real;
      YA_old : Real;
      Y_new : Real;
      Y_old : Real;
      ph1_started_up : Bool;   // phase 1 ramp up started
      ph2_started_up : Bool;   // phase 2 ramp up started
      ph3_started_up : Bool;   // phase 3 ramp up started
      ph1_started_dn : Bool;   // phase 1 ramp down started
      ph2_started_dn : Bool;   // phase 2 ramp down started
      ph3_started_dn : Bool;   // phase 3 ramp down started
   END_VAR

   VAR_TEMP 
      YAmax : Real;
      TU : Real;   // ramp-up time
      TRU : Real;   // rounding ramp--up time
      TA : Real;
      l_errorThres : Real;
      l_decelerFactor : Real;
   END_VAR


BEGIN
    
    
    //setpoint x[n] is in %
    //define parameters
    #YAmax := 0.01;  //maximum ROC of output
    #TU := #i_rampTime; //ramp time (ROC is limited)
    #TRU := #i_RndTime; //rounding time (ROC is changing)
    #TA := 0.005;  //Determines YB value (rate of rate of change of Y). If changed->adapt also the #l_errorThres
    #YB := (#TA / #TRU) * #YAmax;  //determine rate of change of ROC of Y
    #l_errorThres := 1.0;       //threshold from which error to start phase 3    
    #l_decelerFactor := 3.0;    //how fast we want to converge to sp during phase 3
    
    
    
    IF #i_reset THEN
      #YA_new := 0.0;
      #YA_old := 0.0;
      #Y_new := 0.0;
      #Y_old := 0.0;
      #ph1_started_up := false;
      #ph2_started_up := false;
      #ph3_started_up := false;
      #ph1_started_dn := false;
      #ph2_started_dn := false;
      #ph3_started_dn := false;
    END_IF;
    
    #deadband := 0.1;
    #error := DINT_TO_REAL(#i_x) - #Y_old;
    
    IF ABS(#error) <= #deadband THEN   //x[n]=y[n]
      #timer1 := 0; 
      #Imp_Clock := false;
      #YA_new := 0.0;   
      #ph1_started_up := false;
      #ph2_started_up := false;
      #ph3_started_up := false;
      #ph1_started_dn := false;
      #ph2_started_dn := false;
      #ph3_started_dn := false;
    ELSE
      IF #i_Clock AND NOT #Imp_Clock THEN //solong as x[n]!=y[n] count with clock pulse
        #Imp_Clock := true;               //Zeitgeber ist überflüssig
        #timer1 := #timer1 + 1;   
      ELSIF NOT #i_Clock THEN
        #Imp_Clock := false;
      END_IF;
      IF #error > 0 THEN
          IF #ph1_started_dn OR #ph2_started_dn OR #ph3_started_dn THEN  //sudden change of sp to higher value than y[n]       
              #ph1_started_dn := false;
              #ph2_started_dn := false;
              #ph3_started_dn := false;
          END_IF;
          IF #timer1 > 0 AND #YA_new < #YAmax AND (NOT #ph3_started_up OR #error > #l_errorThres) THEN
              #ph1_started_up := true;
              #YA_new := #YA_old + #YB;  //rounding interval
              #Y_new := #Y_old + #YA_new;
          ELSIF #timer1 > 0 AND #YA_new >= #YAmax AND #error > #l_errorThres THEN
              #ph2_started_up := true;
              #YA_new := #YAmax;    //ramp interval
              #Y_new := #Y_old + #YAmax;
          ELSIF #timer1 > 0 AND #ph2_started_up OR (#ph1_started_up AND #error <= #l_errorThres) THEN    
              #ph3_started_up := true;
              IF #YA_new > 20 * #YB THEN
                  #YA_new := #YA_old - #l_decelerFactor * #YB;  //rounding interval
              END_IF;
              #Y_new := #Y_old + #YA_new;
          END_IF;
      ELSE  //error<0
          IF #ph1_started_up OR #ph2_started_up OR #ph3_started_up THEN  //sudden change of sp to lower value than y[n]        
              #ph1_started_up := false;
              #ph2_started_up := false;
              #ph3_started_up := false;
          END_IF;
          IF #timer1 > 0 AND #YA_new > - #YAmax AND (NOT #ph3_started_dn OR #error < - #l_errorThres)  THEN
              #ph1_started_dn := true;
              #YA_new := #YA_old - #YB; //rounding interval
              #Y_new := #Y_old + #YA_new;
          ELSIF #timer1 > 0 AND #YA_new <= - #YAmax AND #error < - #l_errorThres THEN
              #ph2_started_dn := true;
              #YA_new := - #YAmax;
              #Y_new := #Y_old - #YAmax;
          ELSIF #timer1 > 0 AND #ph2_started_dn OR (#ph1_started_dn AND #error >= - #l_errorThres) THEN
              #ph3_started_dn := true;
              IF #YA_new < -20 * #YB THEN
                  #YA_new := #YA_old + #l_decelerFactor * #YB;  //rounding interval
              END_IF;
              #Y_new := #Y_old + #YA_new;
          END_IF;
      END_IF;
    END_IF;
    
    #YA_old := #YA_new;
    #Y_old := #Y_new;
    
    //output
    #o_Y := #Y_new;
    
    
    
    
    
    
    
    
    
    
    
    
END_FUNCTION_BLOCK
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
1. Mich stört die Konstante 20 bzw -20 im Quellkode, deren Bedeutung nirgends erklärt ist.

2. Um den FB intensiv zu testen, würde ich für eine graphische Darstellung von Eingangs- und Ausgangswert sorgen.
Dann verschiedene Kombinationen von Eingangswerten, Rampen- und Rundungszeiten eingeben und anschauen, ob die Kurven so aussehen, wie Du es erwartest.
Dabei sollte man auch vor "exotischen" Parametern nicht zurück schrecken, also z. B. Rundungszeit länger als Rampenzeit oder neuer Sollwert bevor der alte erreicht wurde.
Gruß
Erich
 
Ja das stimmt, ich habe noch viele Sachen im Code unerklaert liegen lassen, weil ich es nur noch als einen Testbaustein halte.

Diese 20 bzw. -20 ist als eine Grenze fuer die Verzoegerung (Phase 3) gedacht, so dass der Ausgang des Bausteins den Sollwert nicht langsamer annaehert als diesen ROC Wert!
 
Hallo pasnos,

bei "Steilheitsbegrenzer mit Rundung" dachte ich an eine einfache Rampenfunktion? Falls dem so ist, ist dein Code mit den Fallunterscheidungen viel zu kompliziert. Suche mal nach "Rampe".

Gruß, Onkel
 
.. Hallo, ne ich meine so einen Hochlaufgeber, der auch Rundungen hat! :)
KF40 :ROFLMAO: iss recht? So zu sagen ein Sollwertsprung mit einem PT2- bzw. PTn-Glied dahinter? Super Sache für eine Sollwertvorgabe bei kritischen Prozessen. Schalte einfach zwei PT1-Glieder in Reihe und du bekommst "Rundungen" oben und unten :ROFLMAO: . Falls du nicht weiter kommst, melde dich noch mal.
 
@pasnos:
Ich würde das so machen, dass ich einen Baustein erstelle, der als Input die benötigten Stützstellen deines Verlaufs bekommt - das werden ja nicht unendlich viele sein.
Gleichzeitig würde ich diesen Baustein über einen Weckalarm aufrufen - also in einem feststehenden Zeitraster (das ich dem Baustein auch als IN-Parameter mit übergeben würde) - z.B. 10 ms.
Nun könntest du dir die Hüllkurve abhängig von der vergangenen Zeit berechnen und die zugehörigen Werte ausgeben. Damit hättest du deine "eckige" Vorgabe.
Für diese Vorgabe legst du nun eine Glättung fest - das wäre dein Rundungswert.
Entsprechend dieses Glättungswertes berechnest du die entsprechende Anzahl von Ausgabe-Punkten vor deinem aktuellen Ausgabewert und die dahinter und bildest daraus einen Mittelwert. Diesen gibst du dann tatsächlich aus und erhältst somit eine entsprechend des Glättungswertes abgerundete Ausgabekurve.

Konntest du meinen Ausführungen folgen ?

Gruß
Larry
 
Zurück
Oben