Defekte Kurvenanpassung

McNugget

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

ich bin mal wieder am Verzweifeln.

Ich arbeite unter Codesys mit Wago 750-841.

Habe mal mehrere Baustein angehängt, die ich mal selber irgendwo aufgeschnappt und dann abgewandelt habe. Leider anscheinend ohne genug Ahnung von der Materie.. :-\

Der Baustein Lin_Trafo2_Glättung soll die Messwerte (12bit) linearisieren, transformieren und glätten.

Dann wird an Charcurve_50_1 übergeben.

Der Baustein soll Druckwerte auf eine nichtlineare Kurve skalieren. 50 Punkte (Temperaturwerte) werden per Array angelegt.

Leider rechnet der Baustein in hohen Word-Bereichen z.B. 32000 irgendwo falsch und gibt -45°C aus.

Ich sehe den Wald vor Bäumen nicht, habe jetzt ewig rumgedoktort und finde den Dreh nicht.

Vielleicht hat ja jemand hier mal Zeit und Lust, sich die Bausteine anzuschauen und mir Anregungen zu geben, bzw. mir zu erklären, wo der Fehler liegt.

Ausserdem bin ich dankbar über jeden Tipp, was man eleganter/besser machen könnte... Vielleicht mache ich ja noch Dinge zu Fuss, die z. B. bereits in der OSCAT.Lib implementiert sind.

Vielen Dank.

McNugget
 

Anhänge

  • K301.zip
    1,9 KB · Aufrufe: 19
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Ybbs,

ich habe die Wandlung mal nach REAL_TO_WORD verändert. Dann funktioniert es zwar auch, jedoch erhalte ich dann Temperaturwerte um die 600°.

Das ist ja auch nicht richtig..

Wie gesagt, knabbere schon etwas an dem Problem..

Gruss


McNugget
 
Zuletzt bearbeitet:
Hast Du evtl. in paar mehr Infos?

Wenn das Problem auftritt, dass er 600 °C ausgibt, welche Werte haben denn dann die Eingangs- und Ausgangsvariablen der beiden Bausteine?

1. Eingangswert am LinTrafoFb
2. Filterzeit
3. Ausgangswert am LinTrafoFb
4. Ist das "Filterkonstrukt" stabil oder schwingt es?
5. Was sind das für Filter-Bausteine "int1" und "int2"

6. Welchen Wert hat die Eingangsvariable "N" vom CharCurveFb und wie hast Du den berechnet?
7. Welche Werte enthält das Punkte-Array?

Wenn ich dich richtig verstanden habe, funktionieren die Bausteine nur bei bestimmten Wertebereichen nicht?
 
Halo ybbs

Zur Verdeutlichung habe ich mal einen Screenshot angehängt, um die Fragen 1, 2 und 6 zu beantworten.

Ich habe den Mess-Eingangswert (WORD) auf 32000 geforced, um den Fehler zu provozieren.

zu 4. Meiner Meinung nach schwingt es nicht, bzw. selbst wenn, wäre das Schwingen nicht so gross, dass es zu einem solch dauerhaften Problem führen sollte.

zu 5. Die Bausteine sind vom Typ FT_INT aus der OSCAT.Lib

zu 7. Das Array sieht folgendermassen aus:

TYPE POINTN :
STRUCT
X,Y: DINT;
END_STRUCT
END_TYPE



P:ARRAY[0..50] OF POINTN :=
(X :=05450 ,Y :=-4500),
(X :=05764 ,Y :=-4400),
(X :=06093 ,Y :=-4300),
(X :=06436 ,Y :=-4200),
(X :=06796 ,Y :=-4100),
(X :=07171 ,Y :=-4000),
(X :=07563 ,Y :=-3900),
(X :=07973 ,Y :=-3800),
(X :=08401 ,Y :=-3700),
(X :=08847 ,Y :=-3600),
(X :=09312 ,Y :=-3500),
(X :=09797 ,Y :=-3400),
(X :=10302 ,Y :=-3300),
(X :=10828 ,Y :=-3200),
(X :=11376 ,Y :=-3100),
(X :=11946 ,Y :=-3000),
(X :=12538 ,Y :=-2900),
(X :=13154 ,Y :=-2800),
(X :=13795 ,Y :=-2700),
(X :=14460 ,Y :=-2600),
(X :=15150 ,Y :=-2500),
(X :=15867 ,Y :=-2400),
(X :=16611 ,Y :=-2300),
(X :=17382 ,Y :=-2200),
(X :=18182 ,Y :=-2100),
(X :=19011 ,Y :=-2000),
(X :=19870 ,Y :=-1900),
(X :=20760 ,Y :=-1800),
(X :=21681 ,Y :=-1700),
(X :=22634 ,Y :=-1600),
(X :=23620 ,Y :=-1500),
(X :=24641 ,Y :=-1400),
(X :=25695 ,Y :=-1300),
(X :=26785 ,Y :=-1200),
(X :=27912 ,Y :=-1100),
(X :=29075 ,Y :=-1000),
(X :=30277 ,Y :=-900),
(X :=31517 ,Y :=-800),
(X :=32797 ,Y :=-700),
(X :=34117 ,Y :=-600),
(X :=35479 ,Y :=-500),
(X :=36883 ,Y :=-400),
(X :=38331 ,Y :=-300),
(X :=39822 ,Y :=-200),
(X :=41359 ,Y :=-100),
(X :=42941 ,Y :=000),
(X :=44571 ,Y :=100),
(X :=46248 ,Y :=200),
(X :=47974 ,Y :=300),
(X :=49750 ,Y :=400),
(X :=51576 ,Y :=500);



Es scheint eben so zu sein, dass ich irgendwo einen Überlauf produziere.


Gruss

McNugget
 

Anhänge

  • KW.jpg
    KW.jpg
    106,3 KB · Aufrufe: 37
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi McNugget,

die -45°C bekommst Du weil du im CharCurveFb die 58600.83 zu INT konvertierst => du bekommst den niedrigsten Wert Deiner Tabelle.

Wenn Du die Deklaration von IN nach z.B. "Word" änderst, bekommst Du wohl den vorletzten Wert, also 400 aus deiner Tabelle und den Fehler 2.
Warum? Weil Du es so programmiert hast ;)

Deine Tabelle endet bei einem X-Wert von 51576. Dein Eingangswert ist aber 58600. Tritt der Fall auf, so guckt Dein CharCurve FB ob der Wert größer ist als der Index-1 und gibt dann Fehler 2 und den Y-Wert von Index-1 aus.
Siehe auch den Screenshot im Anhang.

D.h. der FB kann einfach mit dem zu großen Wert nicht umgehen.
 

Anhänge

  • ScreenShot_CharCurveImFehlerfall.JPG
    ScreenShot_CharCurveImFehlerfall.JPG
    31,6 KB · Aufrufe: 22
OK.

Also wäre der Lösungsansatz die Variable auf WORD zu ändern und den FB auf z. B. 60 Wertepaare zu erweitern um noch höher gehen zu können?

Oder hast Du eine Idee, wie man das eleganter machen könnte?

Gruss

McNugget
 
Nunja, so richtig elegant ist es nicht, die Fehlermeldung eines FB zu ignorieren und mit den zweifelhaften Werten einfach weiter zu arbeiten. :sm14:
(sorry,konnte ich mir nicht verkneifen...)

Eine Interpolation zwischen 2 Stützpunkten halte ich grundsätzlich für besser als eine Extrapolation "ins Unbekannte". D.h. ich würde die Tabelle mit den Kurvenpunkten erweitern.

Wenn Du dennoch Werte auch ausserhalb der definierten Kurve "schätzen" möchtest, kannst Du dir folgendes mal ansehen... Mir gefällt die Funktion besser als der CharCurveFb und wenn ich so etwas bräuchte würde ich hier einfach noch eine Bereichs überwachung implementieren welche bei Über-/Unterschreiten der definierten Kurve ein Flag setzt.

Code:
FUNCTION LinearInterpolation : REAL
(* -------------------------------------------------------------------------
  Grundlage der Funktion war Linear_Int aus Oscat 3.10
  Angepasst für die Werte von McNugget
---------------------------------------------------------------------------- *)
VAR_INPUT
  In        : REAL;
  Points    : DINT;
END_VAR
VAR_IN_OUT
  XY        : ARRAY[1..MAX_POINTS,XValue..YValue] OF REAL;
END_VAR
VAR
  i         : DINT;
END_VAR
VAR CONSTANT
  MAX_POINTS : DINT := 51;
  XValue     : DINT := 1;
  YValue     : DINT := 2;
END_VAR



(*make sure n is bound within the array size *)
Points := MIN(Points,MAX_POINTS);

(* calculate the linear segement interpolation *)
i := 2;
(* search for segment and calculate output
	below and above the defined segments we interpolate the last segment *)
WHILE (i < Points) AND (XY[i,XValue] < In) DO
	i := i + 1;
END_WHILE;

(* calculate the output value on the corresponding segment coordinates *)
LinearInterpolation := (
  (XY[i,YValue] - XY[i-1,YValue]) * In - XY[i,YValue] * XY[i-1,XValue] + XY[i-1,YValue] * XY[i,XValue]) /
    (XY[i,XValue] - XY[i-1,XValue]);

Hier habe deine Kurvenwerte für die Funktion angepasst
Code:
	PGlobal:ARRAY[1..51,1..2] OF REAL:=		(* ARRAY of N points to describe the characteristic curve *)
		05450 , -45,
		05764 , -44,
		06093 , -43,
		06436 , -42,
		06796 , -41,
		07171 , -40,
		07563 , -39,
		07973 , -38,
		08401 , -37,
		08847 , -36,
		09312 , -35,
		09797 , -34,
		10302 , -33,
		10828 , -32,
		11376 , -31,
		11946 , -30,
		12538 , -29,
		13154 , -28,
		13795 , -27,
		14460 , -26,
		15150 , -25,
		15867 , -24,
		16611 , -23,
		17382 , -22,
		18182 , -21,
		19011 , -20,
		19870 , -19,
		20760 , -18,
		21681 , -17,
		22634 , -16,
		23620 , -15,
		24641 , -14,
		25695 , -13,
		26785 , -12,
		27912 , -11,
		29075 , -10,
		30277 ,   -9,
		31517 ,   -8,
		32797 ,   -7,
		34117 ,   -6,
		35479 ,   -5,
		36883 ,   -4,
		38331 ,   -3,
		39822 ,   -2,
		41359 ,   -1,
		42941 ,    0,
		44571 ,    1,
		46248 ,    2,
		47974 ,    3,
		49750 ,    4,
		51576 ,    5;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Du könntest auch versuchen, für deinen Werte eine Formel zu ermitteln, z.Bsp. kann Excel das für dich erledigen.
http://www.sps-forum.de/showthread.php?p=59633#post59633

Dann nimmst du nicht den Baustein, sondern rechnest deine Werte anhand der Formel um. Allerdings ist eins klar, außerhalb der oberen und unteren Begrenzung sind alle Werte höchst hypothetisch, daher mußt du so oder so deine Wertepaare erweitern.
 
Hallo ybbs, hallo Ralle,

vielen Dank für Eure Hilfe.

@ybbs: Habe Deinen Code eingesetzt, die Kurve um jeweils 10 Punkte nach oben und unten erweitert und nun läuft es erheblich besser als vorher. Vielen Dank!!!

@Ralle: Habe die Daten mal in Excel einkopiert und gesehen, dass das Polynom zwar schon drankommt, aber eben nicht genau genug. Es reicht für meine Zwecke aus, zwischen Stützpunkten zu interpolieren. Dasnke für Deine Info auf jeden Fall. Das kann ich sicher noch mal wieder nutzen.
Toll wäre es natürlich, die perfekte Formel für eine Nassdampftabelle für NH3 zu erhalten, und diese dann zur exakten Berechnung einzusetzen.
;)



Sollten die Werte, auch nur Randbereiche von mir eingegebene Tabelle erreichen, hätte ich bereits eine Störung. Insofern reicht mir das schon so aus.
Die Grenzwertverletzungen werte ich bereits in anderen Bausteinen aus.



Gruss

McNugget
 
Zurück
Oben