Volumenberechnung in liegendem Zylinder mit Step-7

mikel

Level-1
Beiträge
51
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo alle miteinander,

ich stehe zur Zeit vor folgendem Problem:

Die Volumenberechnung eines stehenden ca. 6000l - Tanks wurde bisher mittels Differenzdruck-Messung ermittelt, Druck und Fuellhoehe verhalten sich dabei linear zueinander.

Jetzt hat der Konstrukteur den Tank liegend einbauen lassen.

Hatte jemand schon mal ein aehnliches Problem? Im Moment finde ich jedenfalls nicht den richtigen Ansatz.

Die Programmierung erfolgt mit Step7 Prof. V5.3, also auch SCL moeglich.

Bin fuer jede Anregung dankbar. Habe das ganze Osterwochende im Hotel Zeit eine Loesung zu finden.

Gruss aus Italien (Bologna) Micha
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Hoehe muss ich ueber den Differenzdruck bestimmen, war bei stehendem Zylinder auch ausreichend. Ansonsten wie immer, als letztes darf der Programmierer ran, wenn der Kunde schon vor der Tuer steht und die Anlage abnehmen will. Also keine Zeit was neues zu bestellen.

Gruss Micha
 
Hallo,

was fertiges habe ich nicht. Bei sowas messen wir den Füllstand mit Ultraschall, in den Meßumformern ist die Formel für den liegenden Zylinder schon drin und raus kommt das Volumen....

zur Lösung: Volumen ist Fläche x Höhe, Höhe ist bekannt -> Länge des liegenden Zylinders.
Problem ist die Berechnung der Fläche des Kreisabschnitts, dazu siehe hier:

http://www.reality-software.de/bluesunsoftware/glexs/fl%E421.htm

Du mußt noch umstellen: da du nicht den Winkel alpha, sondern die Höhe h gegeben hast, muß der Winkel aus der Höhe ermittelt werden:
aus h = r-(r*cos(alpha-pi/360)) wird dann

cos(alpha-pi/360) = (r-h) / r

Mit dem winkel alpha kannst Du dann s und b ermitteln und dann alles unten in die Formel für die Fläche einsetzen.
Vorsicht: bei mehr als 50% Höhe denke ich, mußt du das Volumen des leeren Teils ermitteln und von 100% abziehen.
Ich weiß nicht, ob Deine Steuerung mit der Berechnung der ganzen Winkelfunktionen klar kommen wird....

Wenn du das ganze Wochenende noch Zeit hast: Viel Spaß!
Schönen Gruß aus dem verregneten Thüringen
Peter
 
Danke für die schnelle Hilfe, :D

ansonsten das Wetter hier ist auch nicht besonders, Bedeckt und Regnerisch, also genau richtig zum Arbeiten. :wink:

Ich wünsche Euch dann noch ein schönes Osterwochenende, hier ist nur Montag frei.

Gruß Micha
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich kenne es so, daß der Hersteller zu liegenden und stehenden Tanks eine sogenannte Peiltabelle mitliefert. Diese wurde durch Ausmessen des Volumens bestimmt und liefert z.B pro cm Füllhöhe einen Volumenwert. Der Sinn ist, daß Abweichungen von der idealen Zylinderform berücksichtigt werden.
Eine solche Tabelle kannst du in einem DB ablegen. Zwischenwerte kannst du durch Interpolation bestimmen.
 
hallöchen mal eine kleine abänderung von zottels vorschlag


nimm deinen druck

und lass wasser ( oder was auch immer ) kontrolliert einlaufen soll heisen messe es was reingeht

schreib dir alle paar 100 bzw 1000 l die werte in einen db und deinen druck wert und rechne dir aus was du da drinnen hast


aber mal anders radar oder ultraschall wären soviel leichter und ihr habt nicht das problem mit staub so wie wir

frohe ostern
 
Ich werde nicht ohne Berechnung auskommen, es handelt sich bei der Anlage um ein geschlossenes System für Perchlorethylen (PER). Wasser darf auf keinen in die Tanks gelangen, könnte auch nicht ohne großen Aufwand aus der Anlage restlos entleert werden. Und fast 6000l Wasser zum Auslietern zu verschwenden ist bestimmt nicht sehr Umweltbewust, abgesehen von dem Wasserpreis.

Ich stell Euch mein Ergebnis ins Forum, wenn es zu meiner Zufriedenheit ausfällt. Vieleicht kann es ja mal jemand von Euch gebrauchen.

PS: Andere Messsysteme sind aus Kostengründen erst einmal unter den Tisch gefallen. (Vieleicht ist mein Stundensatz immer noch zu tief? :wink: )

Gruß Micha
 
Zuviel Werbung?
-> Hier kostenlos registrieren
kpeter schrieb:
...aber mal anders radar oder ultraschall wären soviel leichter und ihr habt nicht das problem mit staub so wie wir...
Nee, Radar und Ultraschall liefern dir auch nur die Höhe. Der einzige mir bekannte Weg zu einer direkten Füllmengenmessung wäre durch Wiegen. Volumen immer nnoch indirekt über die Dichte.
 
Bon Giorno, Micha,

ich hatte mal so etwas für die Befüllung eines Brauchwasser-Vorratstanks benötigt. Wegen der relativ hohen Ausführungszeit hatte ich die Berechnung nur einmal pro Minute ausgeführt. Bei meiner Anwendung war das völlig ausreichend.


Code:
(************************************************************************************************************************)
FUNCTION "TANKINHALT": REAL                                 // Tankinhalt [l]
TITLE = 'Berechnung des Inhalts eines liegenden Zylinders anhand der Füllhöhe' 
//
//   V = [pi*r^2/2 - r^2*arcsin(1-h/r) - (r-h)*sqrt(h(2r-h))] * l
//
(************************************************************************************************************************)
KNOW_HOW_PROTECT
VERSION : '1.0'
AUTHOR  : Onkel Dagobert
NAME    : TANK
FAMILY  : Entenhausen
(************************************************************************************************************************)

VAR_INPUT
  FUELLSTAND                : INT := 0;                     // Füllstand [cm]
  DURCHMESSER               : INT := 0;                     // Durchmesser des Tanks [cm]
  LAENGE                    : INT := 0;                     // Länge des Tanks [cm]
END_VAR

VAR_TEMP
  r                         : REAL;                         // Radius [cm]
  h                         : REAL;                         // Füllstand [cm]
  l                         : REAL;                         // Länge [cm]
  a, b, c                   : REAL;
END_VAR

// V = [pi*r^2/2 - r^2*arcsin(1-h/r) - (r-h)*sqrt(h(2r-h))] * l
BEGIN
  r := INT_TO_REAL(DURCHMESSER)/2;
  h := INT_TO_REAL(FUELLSTAND);
  l := INT_TO_REAL(LAENGE);
  a := 3.14159265358979 * SQR(r)/2;
  b := ASIN(1-h/r)*SQR(r);
  c := (r-h)*SQRT(h*(2*r-h));
  TANKINHALT:=(a-b-c)*l/1000;
END_FUNCTION;

// eine weitere, ebenfalls funktionierende Lösung
BEGIN
  r := INT_TO_REAL(DURCHMESSER)/2;
  h := INT_TO_REAL(FUELLSTAND);
  l := INT_TO_REAL(LAENGE);
  a := (r-h)/r;
  b := SQRT(1-SQR(a));
  b := ACOS(a) - a*b;
  b := SQR(r)*b;
  TANKINHALT := b*l/1000;
END_FUNCTION;


Gruss, Onkel
 
Also, wenn deine mathematischen Funktionen nicht ausreichen in der CPU, würde ich auch zu einem Plygonzug tendieren. Wobei man aber von der Form des Behälters nicht weis, wieviel jetzt reingegangen ist nehme ich an.
Die Stirnflächen des Zylinders sind bestimmt nicht Plan. Somit könnte man den Polygonzug nur durch austesten (also 1000l rein und messen) bestimmen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
hallo

ich hatte sowas mal für ne s5 geschrieben. dann wurde das irgendwann mal auf s7 umgebaut und ich habe den fc etwas angepasst.

ist in awl/fup.

in scl wie oben ist das natürlich viel einfacher.

Code:
DATA_BLOCK "DB 111 Tankinhalt 1"
TITLE =
VERSION : 0.1


  STRUCT 	
   DB_VAR : REAL ;	//vorläufige Platzhaltervariable
   r : REAL  := 1.450000e+002;	//r = radius
   h : REAL ;	//h = inhalt in cm
   rh : REAL ;	//rh
   s : REAL ;	//s
   alpha1 : REAL ;	//alpha1
   alpha : REAL ;	//alpha
   lb : REAL ;	//lb
   a : REAL ;	//a = Füllstand in Liter
   aqm : REAL ;	//aqm = Füllstand in m^3
   l : REAL  := 7.750000e+002;	//l = länge
   dummy1 : REAL ;	//dummy1
   dummy2 : REAL ;	//dummy2
   dummy3 : REAL ;	//dummy3
   dummy4 : REAL ;	//dummy4
   dummy5 : REAL ;	//dummy5
   dummy6 : REAL ;	//dummy6
   dummy7 : REAL ;	//dummy7
   dummy8 : REAL ;	//dummy8
   dummy9 : REAL ;	//dummy9
   dummy10 : REAL ;	//dummy10
   dummy11 : REAL ;	//dummy11
   dummy12 : REAL ;	//dummy12
   dummy13 : REAL ;	//dummy13
   dummy14 : REAL ;	//dummy14
   dummy15 : REAL ;	//dummy15
   dummy16 : REAL ;	//dummy16
   fuellen_aus : REAL  := 2.450000e+002;	//füllen aus
   fuellen_ein : REAL  := 2.350000e+002;	//füllen ein
   leeren_aus : REAL  := 2.450000e+002;	//entleeren aus
   leeren_ein : REAL  := 2.500000e+002;	//entleeren ein
  END_STRUCT ;	
BEGIN
   DB_VAR := 0.000000e+000; 
   r := 0.000000e+000; 
   h := 0.000000e+000; 
   rh := 0.000000e+000; 
   s := 0.000000e+000; 
   alpha1 := 0.000000e+000; 
   alpha := 0.000000e+000; 
   lb := 0.000000e+000; 
   a := 0.000000e+000; 
   aqm := 0.000000e+000; 
   l := 0.000000e+000; 
   dummy1 := 0.000000e+000; 
   dummy2 := 0.000000e+000; 
   dummy3 := 0.000000e+000; 
   dummy4 := 0.000000e+000; 
   dummy5 := 0.000000e+000; 
   dummy6 := 0.000000e+000; 
   dummy7 := 0.000000e+000; 
   dummy8 := 0.000000e+000; 
   dummy9 := 0.000000e+000; 
   dummy10 := 0.000000e+000; 
   dummy11 := 0.000000e+000; 
   dummy12 := 0.000000e+000; 
   dummy13 := 0.000000e+000; 
   dummy14 := 0.000000e+000; 
   dummy15 := 0.000000e+000; 
   dummy16 := 0.000000e+000; 
   fuellen_aus := 0.000000e+000; 
   fuellen_ein := 0.000000e+000; 
   leeren_aus := 0.000000e+000; 
   leeren_ein := 0.000000e+000; 
END_DATA_BLOCK

FUNCTION "FC 111 Tankinhalt 1" : VOID
TITLE =berechnung des tankinhalts 1
AUTHOR : 'V.L.'
VERSION : 0.1

BEGIN
NETWORK
TITLE =feste daten

      L     1.450000e+002; //tankradius
      T     "DB 111 Tankinhalt 1".r; 

      L     7.750000e+002; //tanklänge
      T     "DB 111 Tankinhalt 1".l; 

NETWORK
TITLE =nicht erlaubte werte verhindern

      L     "DB 111 Tankinhalt 1".h; // füllstand in cm
      L     1.500000e-001; // 0.15 cm
      >=D   ; 
      SPB   m001; 
      L     1.500000e-001; 
      T     "DB 111 Tankinhalt 1".h; 
m001: NOP   0; 

      L     "DB 111 Tankinhalt 1".h; // füllstand in cm
      L     2.899900e+002; // 289.99 cm
      <=D   ; 
      SPB   m002; 
      L     2.899900e+002; 
      T     "DB 111 Tankinhalt 1".h; 
m002: NOP   0; 

NETWORK
TITLE =rh = r - h

      L     "DB 111 Tankinhalt 1".r; 
      L     "DB 111 Tankinhalt 1".h; 
      -R    ; 
      T     "DB 111 Tankinhalt 1".rh; 
      NOP   0; 
NETWORK
TITLE =dummy1 = r * r

      L     "DB 111 Tankinhalt 1".r; 
      SQR   ; 
      T     "DB 111 Tankinhalt 1".dummy1; 
      NOP   0; 
NETWORK
TITLE =dummy2 = rh * rh

      L     "DB 111 Tankinhalt 1".rh; 
      SQR   ; 
      T     "DB 111 Tankinhalt 1".dummy2; 
      NOP   0; 
NETWORK
TITLE =dummy3 = r * r - rh * rh ~~~~~ = dummy1 - dummy2

      L     "DB 111 Tankinhalt 1".dummy1; 
      L     "DB 111 Tankinhalt 1".dummy2; 
      -R    ; 
      T     "DB 111 Tankinhalt 1".dummy3; 
      NOP   0; 
NETWORK
TITLE =dummy4 = sqrt(r * r - rh * rh) ~~~~~ = sqrt (dummy3)

      L     "DB 111 Tankinhalt 1".dummy3; 
      SQRT  ; 
      T     "DB 111 Tankinhalt 1".dummy4; 
      NOP   0; 
NETWORK
TITLE =s = 2 * sqrt(r * r - rh * rh) ~~~~~ = 2 * dummy4

      L     "DB 111 Tankinhalt 1".dummy4; 
      L     2.000000e+000; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".s; 
      NOP   0; 
NETWORK
TITLE =dummy5 = 2 * rh

      L     "DB 111 Tankinhalt 1".rh; 
      L     2.000000e+000; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".dummy5; 
      NOP   0; 
NETWORK
TITLE =dummy6 = rh * 2 / s ~~~~~ = dummy5 / s

      L     "DB 111 Tankinhalt 1".dummy5; 
      L     "DB 111 Tankinhalt 1".s; 
      /R    ; 
      T     "DB 111 Tankinhalt 1".dummy6; 
      NOP   0; 
NETWORK
TITLE =dummy7 = atan(rh * 2 / s) ~~~~~ = atan(dummy6)

      L     "DB 111 Tankinhalt 1".dummy6; 
      ATAN  ; 
      T     "DB 111 Tankinhalt 1".dummy7; 
      NOP   0; 
NETWORK
TITLE =dummy8 = atan(rh * 2 / s) * 180 ~~~~~ = dummy7 * 180

      L     "DB 111 Tankinhalt 1".dummy7; 
      L     1.800000e+002; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".dummy8; 
      NOP   0; 
NETWORK
TITLE =alpha1 = atan(rh * 2 / s) * 180 / pi ~~~~~ = dummy8 / pi

      L     "DB 111 Tankinhalt 1".dummy8; 
      L     3.141500e+000; 
      /R    ; 
      T     "DB 111 Tankinhalt 1".alpha1; 
      NOP   0; 
NETWORK
TITLE =alpha = 90 - alpha1

      L     9.000000e+001; 
      L     "DB 111 Tankinhalt 1".alpha1; 
      -R    ; 
      T     "DB 111 Tankinhalt 1".alpha; 
      NOP   0; 
NETWORK
TITLE =dummy9 = r * pi



      L     "DB 111 Tankinhalt 1".r; 
      L     3.141500e+000; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".dummy9; 
      NOP   0; 
NETWORK
TITLE =dummy10 = r * pi * 2 ~~~~~ = dummy9 * 2

      L     "DB 111 Tankinhalt 1".dummy9; 
      L     2.000000e+000; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".dummy10; 
      NOP   0; 
NETWORK
TITLE =dummy11 = r * pi * 2 * alpha ~~~~~ = dummy10 * alpha

      L     "DB 111 Tankinhalt 1".dummy10; 
      L     "DB 111 Tankinhalt 1".alpha; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".dummy11; 
      NOP   0; 
NETWORK
TITLE =lb = r * pi * 2 * alpha / 180 ~~~~~ = dummy11 / 180

      L     "DB 111 Tankinhalt 1".dummy11; 
      L     1.800000e+002; 
      /R    ; 
      T     "DB 111 Tankinhalt 1".lb; 
      NOP   0; 
NETWORK
TITLE =dummy12 = lb * r

      L     "DB 111 Tankinhalt 1".lb; 
      L     "DB 111 Tankinhalt 1".r; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".dummy12; 
      NOP   0; 
NETWORK
TITLE =dummy13 = s * rh

      L     "DB 111 Tankinhalt 1".s; 
      L     "DB 111 Tankinhalt 1".rh; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".dummy13; 
      NOP   0; 
NETWORK
TITLE =dummy14 = (lb * r - s * rh) ~~~~~ = dummy12 - dummy13

      L     "DB 111 Tankinhalt 1".dummy12; 
      L     "DB 111 Tankinhalt 1".dummy13; 
      -R    ; 
      T     "DB 111 Tankinhalt 1".dummy14; 
      NOP   0; 
NETWORK
TITLE =dummy15 = (lb * r - s * rh) / 2 ~~~~~ = dummy14 / 2

      L     "DB 111 Tankinhalt 1".dummy14; 
      L     2.000000e+000; 
      /R    ; 
      T     "DB 111 Tankinhalt 1".dummy15; 
      NOP   0; 
NETWORK
TITLE =dummy16 = (lb * r - s * rh) / 2 * l ~~~~~ = dummy15 * l

      L     "DB 111 Tankinhalt 1".dummy15; 
      L     "DB 111 Tankinhalt 1".l; 
      *R    ; 
      T     "DB 111 Tankinhalt 1".dummy16; 
      NOP   0; 
NETWORK
TITLE =a = dummy16 / 1000 = Füllstand in Liter

      L     "DB 111 Tankinhalt 1".dummy16; 
      L     1.000000e+003; 
      /R    ; 
      T     "DB 111 Tankinhalt 1".a; 
      NOP   0; 
NETWORK
TITLE =aqm = a / 1000 = Füllstand in m^3

      L     "DB 111 Tankinhalt 1".a; 
      L     1.000000e+003; 
      /R    ; 
      T     "DB 111 Tankinhalt 1".aqm; 
      NOP   0; 
END_FUNCTION
 
Ich habe das so gelöst


-------------------------------------------
r² * 2acos(r-h) - sin(2acos(r-h))
- --- ---
2 r r
----------------------------------------------

L #radius
L #FH = füllhöhe des Tanks Scalierter wert mit FC105
-R

L #radius
/R
T #E1

ACOS
L 2.000000e+000
*R
SIN
T #E2

L #E1
ACOS
L 2.000000e+000
*R

L #E2
-R
T #E3

L #radius
L #radius
*R

L 2.000000e+000
/R

L #E3
*R

L #laenge
*R
L 1.220000e+000
*R
T #inhalt
 
Ersteinmal vielen Dank für Eure zahlreichen Beiträge,

nun zu meinem Lösungsansatz:

Bekannt sind der Radius r die Länge und die Füllhöhe h, wobei die Höhe aus Differenzdruck und Dichte der Flüssigkeit ermittel wird.

Als erstes wird Alpha berechnet, aus h=r * (1-cos(Alpha/2)) wird cos(Alpha/2)=(r-h)/r.

Danach bestimmt man das Bogenmaß, BM=(PI/180) * Alpha.

Die Fläche ergibt aus A=r² / 2 * (BM - sin(Alpha))

==> V := A * L

FUNCTION TankVolume : REAL

TITLE = 'Berechnung des Volumens eines liegenden Zylinders'
//
// Inputs Radius und Länge des Zylinders in dm, sowie aktuelle Füllhöhe in dm
// alle Längenwerte in [dm], damit ersparen wir uns das Umrechnen ;-)
// V=A*L [dm³] bzw. [l]
// A= r*r/2 * (BM-sin(Alpha)) [dm²]
// Alpha=2* acos((R-H)/R) [°]
// BM= PI*Alpha/180 [°]
// Release: 28.03.2005
// TODO: Korrekturfaktor für die gewölbten Seitenflächen
//

VERSION : '1.0'
AUTHOR : mg
NAME : name
FAMILY : family

// Bausteinparameter
VAR_INPUT
// Eingangsparameter
vH :REAL; // aktuelle Füllstandshöhe
vR :REAL; // Radius des Zylinders
vL :REAL; // Länge des Zylinders
END_VAR

CONST
// Konstanten
PI := 3.141592;
END_CONST

VAR_TEMP
// temporäre Variablen
vAlpha :REAL; // Winkel
vBM :REAL; // Bogenmass
vA :REAL; // Fläche
END_VAR

BEGIN
// Anweisungsteil
;
vAlpha := 2 * ACOS((vR - vH) / vR);
vBM := PI / 180 * vAlpha;
vA := vR**2 / 2 * (vBM - SIN(vAlpha));
;
TankVolume := vA * vL;
;
END_FUNCTION


Mein SCL-Baustein sieht damit so aus, die Korrektur für die gewölbten Seitenflächen werde ich durch Anpassung der Länge versuchen, damit bekomme ich zwar kein 100% genaues Ergebnis, aber in den Bereich <5% sollte ich schon kommen.
 

Anhänge

  • tank.txt
    1,1 KB · Aufrufe: 37
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich war wohl zu voreilig,

nach dem ich endlich geschnallt habe, dass die Trignometrischen Funktionen bereits das Bogenmaß liefern, funktioniert meine Simultion mit dem geändertem SCL-Baustein.

Code:
FUNCTION TankVolume : REAL

TITLE = 'Berechnung des Volumens eines liegenden Zylinders'
//
// Inputs Radius und Länge des Zylinders in dm, sowie aktuelle Füllhöhe in dm
// alle Längenwerte in [dm], damit ersparen wir uns das Umrechnen ;-) 
// V=A*L [dm³] bzw. [l]
// A= r*r/2 * (BM-sin(Alpha)) [dm²]
// Alpha=2* acos((R-H)/R) in Bogenmaß
// Release: 28.03.2005
// TODO: Korrekturfaktor für die gewölbten Seitenflächen
// 

VERSION : '1.0'
AUTHOR  : mg
NAME    : name
FAMILY  : family

// Bausteinparameter
VAR_INPUT
  // Eingangsparameter
  vH :REAL;  // aktuelle Füllstandshöhe
  vR :REAL;  // Radius des Zylinders
  vL :REAL;  // Länge des Zylinders
END_VAR

CONST
  // Konstanten
  PI := 3.141592;
END_CONST

VAR_TEMP
  // temporäre Variablen
  vAlpha :REAL; // Winkel
  vA     :REAL; // Fläche    
END_VAR

BEGIN
  // Anweisungsteil
  ;
  vAlpha := 2 * ACOS((vR - vH) / vR);
  vA := vR**2 / 2 * (vAlpha - SIN(vAlpha));
  ;
  TankVolume := vA * vL;
  ;
END_FUNCTION

Gruß Micha
 
Hallo

Ich häng gerade an dem gleichen Problem und kämpf gerade an der Seitenwölbung für einen Zylindrisch liegenden Tank hat jemand schon eine Lösung gefunden?

Gesamtvolumen ist kein Problem.

V = h² [pi] / 3 * (3r-h) aber dann fängt der spaß schon an.

Hilfe wäre super!
Danke schon mal.

Michi
 
eist sind die liegenden Tanks (Zylindrisch) nicht Zylindrisch sondern aus statischen Gründen noch die geraden Flächen ausgewölbt. und da befindet sich ja auch noch Material also noch zwei abgeschnittene "Kugeln" noch hinten und vorne auf den Tank
 
Ah verstehe. Wenn es exakte Halbkugeln sind, hätte man es einfacher, zu der Formel von mikel kommt dann noch das Volumen einer Kugel entsprechend hinzu. Oder sind die Kugelwände kleiner als 1/2 Kugel?
 
Zurück
Oben