Step 7 Ungenauigkeit beim Rechnen mit REAL-Werten (Simatic Manager 315er CPU)

sargan26

Level-2
Beiträge
102
Reaktionspunkte
5
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,


ich habe eine schwierige Aufgabe zu lösen und komme da einfach auf keinen grünen Zweig. Ich bräuchte Hilfe wie man beim Rechnen mit REAL-Werten im Simatic Manager (300er CPU) die Genauigkeit erhöhen kann. Das Problem ist einigermaßen zeitkritisch weil nächste Woche die Inbetriebnahme beim Kunden ist.


https://support.industry.siemens.co...chen-formeln-verwendet-werden-?dti=0&lc=de-WW
„Generell gilt, dass REAL Zahlen mit einer Genauigkeit von 6 Nachkommastellen angegeben und berechnet werden. Bei Berechnungen ist dabei noch zu beachten, dass für jeden einzelnen Rechenschritt diese Genauigkeit ebenfalls gilt.“


Format des Datentyps REAL (Gleitpunktzahlen)

Gleitpunktzahlen in STEP 7 entsprechen dem Grundformat mit einfacher Breite,
wie in der Norm ANSI/IEEE Standard 754-1985 [...] beschrieben. [...]

Genauigkeit beim Rechnen mit Gleitpunktzahlen
---------------------------------------------------------------------------------
Vorsicht

Bei umfangreichen Berechnungen mit Zahlen, die große Größenunterschiede
(mehrere 10-er Potenzen) aufweisen, können Ungenauigkeiten im Rechenergebnis
entstehen.
---------------------------------------------------------------------------------

Die Gleitpunktzahlen in STEP 7 sind auf 6 Dezimalstellen genau. Sie können deshalb
bei der Angabe von Gleitpunktkonstanten nur maximal 6 Nachkommastellen angeben.

---------------------------------------------------------------------------------
Hinweis

Die Rechengenauigkeit von 6 Dezimalstellen bedeutet z. B., dass die Addition von
Zahl1 + Zahl2 = Zahl1 ergibt, wenn Zahl1 größer Zahl2 * 10 hoch y, mit y>6 ist:

100 000 000 + 1 = 100 000 000.
---------------------------------------------------------------------------------





Folgende Aufgabenstellung:
Bei einem Zahnrad werden 3 Höhenmessungen durchgeführt und dadurch soll die Parallelität berechnet werden (beurteilen ob die Fläche eben ist).


Das Problem:
Durch die hohe Ungenauigkeit beim Rechnen mit REAL-Werten ist der Endwert für die Parallelität auch ungenau. Und vor allem für wenn die Höhenmessungen nahe bei einander liegen (zB. Messpunkt 2 = 8.0 und Messpunkt 3 = 8.0001) kommt man mit den Rundungsfehlern genau auf 1 PI dann kommt irgendwas raus.




Lösungswege probiert:


Long Real statt Real verwenden


  1. [*=left]Gibt es beim Simatic Manager / 300er CPU nicht


Open Source Bibliothek OSCAT (http://www.oscat.de/) , dort kann man mit Pseudo Long Reals rechnen


  1. [*=left]Allerdings gibt es nur die Funktion Addieren und Multiplizieren keine Division, Subtraktion, Winkelfunktionen…


Additionen und Subtraktionen mit DINT statt REAL rechnen


  1. [*=left]Hat das Ergebnis bei ein paar Zwischenschritten etwas verbessert allerdings nicht viel am Endergebnis geändert




Anhang:
Im Google drive wäre ein leeres Simatic Manager Projekt wo nur die Berechnung drin ist. In der VAT könnten Sie zB. die Teilehoehe_3 ändern und vergleichen ob es mit der Excel Berechnung zusammen stimmt (natürlich dann auch bei der Excel die Teilehöhe 3 ändern). In der Excel sind Zeilen mit zwischen Rechenschritten versteckt, mit einem Doppelklick zwischen Zeile 8 und 21 kann man diese öffnen.
Im Word Dokument ist es nochmal etwas ausführlicher beschrieben mit Bildern (geht hier leider nicht).


https://drive.google.com/drive/folders/12n_vZPzx69ZD6_lCgbHebOk4fjsK9Dq1?usp=sharing


 

Anhänge

  • Parallelitaet.zip
    131,3 KB · Aufrufe: 9
Ich hab mir dein Projekt nicht angeschaut.
Aber mal so als Ansatz:
Am einfachsten macht am sowas mit DINT.
Ich vermute mal, dass du den Messwert von einem Sensor auch in 32Bit bekommst.
Also solange wie möglich mit den "Rohdaten" (Digits, Mikrometer) rechnen.
Solange man keine speziellen Befehle braucht, ist das erstmal kein Problem.
Braucht man aber Wineklfunktionen oder ähnliches, dann muss man halt googeln.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Denkst du zu kompliziert oder ich zu einfach? Nur um sicher zu sein, dass ich das richtig verstanden habe: Du hast ein Zahnrad mit 46,5mm Durchmesser. Mittig darauf ist der gedachte Messkreis mit 19mm. Auf diesem Kreis verteilst du symetrisch (alle 120°) deine drei Messpunkte. Man geht davon aus, dass die Oberfläche eben ist, aber nicht unbedingt parallel, andernfalls müsste man ja viel öfters messen. Die drei Messpunkte sind also alle gleich weit weg von der Mitte. Dann sollte doch der Mittelpunkt des Messkreises auf der Höhe des Durchschnitts der drei Messwerte liegen? Und der Punkt von den dreien (ggf. auch zwei), welcher am weitesten vom Durchschnittswert abweicht, sollte dann der interessierende Punkt sein? Von der Seite betrachtet, ist das dann ein rechtwinkliges Dreieck mit dem spitzen Winkel am Mittelpunkt der Mimik, die Hypethenuse trifft dann, wenn sie verlängert wird, wieder den Punkt des Ritzels welcher interessiert. Oder vereinfacht gesagt, im Verhältnis 46,5 zu 19 die Abweichung zum Durchschnittswert multiplizieren, dann verdoppeln (weil die maximale Erhöhung an einem der drei Messpunkte zwangsläufi auf der gegenüberliegenden Seite ohne Messpunkt den gleichen Ausschlag vom Durchschnittswert in die andere Richtung haben muss und fertig? Stimmt allerdings nicht unbedingt mit dem Ergebnis in deinem Excel überein, ich könnte mir aber auch vorstellen, dass es auch hier zu Rundungsproblemen kommen könnte.
 
Oder vereinfacht gesagt, im Verhältnis 46,5 zu 19
...
Stimmt allerdings nicht unbedingt mit dem Ergebnis in deinem Excel überein, ich könnte mir aber auch vorstellen, dass es auch hier zu Rundungsproblemen kommen könnte.

Manchmal ist es auch ganz sinnvoll in der SPS (oder auch auf dem PC) mit Brüchen zu rechnen. Damit kann man Rundungsfehler ganz deutlich reduzieren.
 
Lösungswege probiert:
[..]
Additionen und Subtraktionen mit DINT statt REAL rechnen


  1. [*=left]Hat das Ergebnis bei ein paar Zwischenschritten etwas verbessert allerdings nicht viel am Endergebnis geändert
Ich bin einig mit Blockmove.Anzahl Impulse von den Zahnrad mittels ein DINT zählen, die Unterschied (Parallelitätsfehler) auch in DINT berechnen und nur am Ende ins REAL umwandeln.
Dies musste funktionieren.
Kannst du dein Code hier posten, am besten als SCL ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich möchte da auch nicht Rundungsfehler in Excel ausschließen. Das rechnet war genauer als mit 32 Bit, aber wenn of genug Potenzen, Sinus, Cosinus, Tangens, Quadratwurzel usw. gerechnet wird, können sich auch da minimale Rundungsfehler aufsummieren bzw, vervielfältigen.
 
Hallo, hier wäre die SCL-Quelle. Die Excel Datei kann ich hier leider nicht als Anhang einfügen, wäre beim Google Drive Link drin.

Code:
FUNCTION_BLOCK "Berechnung_Parallelitaet"

VAR_INPUT
   I_Messkreisdurchmesser           :REAL;              // Messkreisdurchmesser
   I_Messpunkt_1_Z                  :REAL;              // Messpunkt 1 gemessener Z Wert
   I_Messpunkt_2_Z                  :REAL;              // Messpunkt 2 gemessener Z Wert
   I_Messpunkt_3_Z                  :REAL;              // Messpunkt 3 gemessener Z Wert
END_VAR


VAR_OUTPUT
   O_Parallelitaet_Flaeche          :REAL;              // Parallelität Zahnradfläche (mm)     
END_VAR


VAR
   PI                               :REAL;              // Kreiszahl
   Messpunkt_1_X                    :REAL;              // Messpunkt 1 berechneter X Wert
   Messpunkt_2_X                    :REAL;              // Messpunkt 2 berechneter X Wert
   Messpunkt_3_X                    :REAL;              // Messpunkt 3 berechneter X Wert
   Messpunkt_1_Y                    :REAL;              // Messpunkt 1 berechneter Y Wert
   Messpunkt_2_Y                    :REAL;              // Messpunkt 2 berechneter Y Wert
   Messpunkt_3_Y                    :REAL;              // Messpunkt 3 berechneter Y Wert
   Vektor_r2_r1_X                   :REAL;              // Vektor R2 - R1 X Wert
   Vektor_r2_r1_Y                   :REAL;              // Vektor R2 - R1 Y Wert
   Vektor_r2_r1_Z                   :REAL;              // Vektor R2 - R1 Z Wert
   Vektor_r3_r1_X                   :REAL;              // Vektor R3 - R1 X Wert
   Vektor_r3_r1_Y                   :REAL;              // Vektor R3 - R1 Y Wert
   Vektor_r3_r1_Z                   :REAL;              // Vektor R3 - R1 Z Wert
   Normalvektor_X                   :REAL;              // Normalvektor X Wert
   Normalvektor_Y                   :REAL;              // Normalvektor Y Wert
   Normalvektor_Z                   :REAL;              // Normalvektor Z Wert 
   Normalvektor_Festan_X            :REAL;              // Normalvektor Festanschlag X Wert
   Normalvektor_Festan_Y            :REAL;              // Normalvektor Festanschlag Y Wert
   Normalvektor_Festan_Z            :REAL;              // Normalvektor Festanschlag Z Wert 
   Winkel_Fest_Stempel_rad          :REAL;              // Winkel zwischen Festanschlag und Stempel (rad)
   Winkel_Fest_Stempel_Grad         :REAL;              // Winkel zwischen Festanschlag und Stempel (°)
END_VAR


    // PI berechnen
    PI := 4 * ATAN(1);
    
    // Messpunkt 1
    Messpunkt_1_X := I_Messkreisdurchmesser / 2.0;
    Messpunkt_1_Y := 0;
   
    // Messpunkt 2
    Messpunkt_2_X := I_Messkreisdurchmesser / 2.0 - ((COS(30*PI/180))*I_Messkreisdurchmesser/2);
    Messpunkt_2_Y := I_Messkreisdurchmesser / 2.0 + ((SIN(30*PI/180))*I_Messkreisdurchmesser/2);
  
    // Messpunkt 3
    Messpunkt_3_X := I_Messkreisdurchmesser / 2.0 + ((COS(30*PI/180))*I_Messkreisdurchmesser/2);
    Messpunkt_3_Y := I_Messkreisdurchmesser / 2.0 + ((SIN(30*PI/180))*I_Messkreisdurchmesser/2);
     
    // Berechnung Vektoren
    Vektor_r2_r1_X := Messpunkt_2_X - Messpunkt_1_X;
    Vektor_r2_r1_Y := Messpunkt_2_Y - Messpunkt_1_Y;
    Vektor_r2_r1_Z := I_Messpunkt_2_Z - I_Messpunkt_1_Z;
    Vektor_r3_r1_X := Messpunkt_3_X - Messpunkt_1_X;
    Vektor_r3_r1_Y := Messpunkt_3_Y - Messpunkt_1_Y;
    Vektor_r3_r1_Z := I_Messpunkt_3_Z - I_Messpunkt_1_Z;
    
    Normalvektor_X := (Vektor_r2_r1_Y * Vektor_r3_r1_Z) - (Vektor_r3_r1_Y * Vektor_r2_r1_Z);
    Normalvektor_Y := (Vektor_r2_r1_Z * Vektor_r3_r1_X) - (Vektor_r2_r1_X * Vektor_r3_r1_Z);
    Normalvektor_Z := (Vektor_r2_r1_X * Vektor_r3_r1_Y) - (Vektor_r2_r1_Y * Vektor_r3_r1_X);
    
    Normalvektor_Festan_X := 0.0;
    Normalvektor_Festan_Y := 0.0;
    Normalvektor_Festan_Z := 4.0;
    
    // Berechnung Parallelität
    Winkel_Fest_Stempel_rad := ACOS(((Normalvektor_X*Normalvektor_Festan_X)+(Normalvektor_Y*Normalvektor_Festan_Y)+(Normalvektor_Z*Normalvektor_Festan_Z))/
    ((SQRT(SQR(Normalvektor_X)+SQR(Normalvektor_Y)+SQR(Normalvektor_Z)))*(SQRT(SQR(Normalvektor_Festan_X)+SQR(Normalvektor_Festan_Y)+SQR(Normalvektor_Festan_Z)))));
    
    Winkel_Fest_Stempel_Grad := Winkel_Fest_Stempel_rad * 180.0 / PI; 
    
    O_Parallelitaet_Flaeche := (TAN(Winkel_Fest_Stempel_Grad*PI/180))*46.5;
    
    IF O_Parallelitaet_Flaeche < 0 THEN
        O_Parallelitaet_Flaeche := O_Parallelitaet_Flaeche * -1.0;
    END_IF;


END_FUNCTION_BLOCK
 
Die Frage ist, wie genau diese Parallelität angegeben werden muß. Bei 4 Stellen hinter dem Komma (1/10000-stel!!!!) haut das doch noch hin, dann wird es ungenau. Aber interessiert es wirlich, ob die Paralleltät nun 0,00016 oder 0,0000064 ist? Vielleicht reicht es ja zu sagen, alles kleiner 0,0001 ist genau genug? Dann müßte man sich ein paar Extrembeispiele hernehmen (große Werte, große und kleine Unterschiede) und mal sehen, ob das im Limit liegt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Messtaster hat die Auflösung 0,0001mm, den wollte der Kunde extra so genau. Deshalb muss die Berechnung auch bei kleinen Höhenunterschieden funktionieren, was sie derzeit durch die großen Ungenauigkeiten beim Rechnen / Rundungsfehler nicht tut :/
 
Moin sargan26,

kann man vielleicht die Vorkommastellen von den Nachkommastellen trennen?

Wenn die Vorkommastellen schon eine Abweichung haben, braucht man vielleicht die Nachkommastellen gar nicht berücksichtigen bzw. erst, wenn die Abweichung <10.0 ist?

Dann könnte man mit einer Vorkommastellen + 5 Nachkommastellen (0,00010) rechnen, ohne ungenau zu werden bzw. die 5. Nachkommastelle wäre nicht mehr tragend, aber Berechnungsrelevant (Rundung).

Ich habe gelernt, das es auf drei tragende Stellen gerundet werden sollte. Jegliche höhere Auslösung geht in Richtung Messungenauigkeit. Sprich: wie groß ist denn Dein Messbereich?


VG

MFreiberger
 
Hallo, hier wäre die SCL-Quelle. [..]
Die Berechnungen in dein SCL code sind alle in REAL.
Wie mit die Berechnungen mit DINTs die 'nicht viel am Endergebnis geändert' ?
Warum brauchst du die trigonometrische Berechnungen ?
Genügt es nicht mit ein Go / No-Go von die Unterschiede von die Messpunkte ?
Was haltest du von den Vorschlag die Berechnungen mit DINTs und nur auf die Unterschiede ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Rundungsprobleme fangen doch schon beim PI an, egal in welchem Datenformat diie Messwerte sind.
Ich wiederhole meine Frage: sehe ich das zu einfach oder müssen wirklich Vektoren berechnet werden?

Code:
FUNCTION_BLOCK "Berechnung_Parallelitaet"

VAR_INPUT
   I_Messkreisdurchmesser           :REAL;      // Messkreisdurchmesser
   I_Messpunkt_1_Z                  :REAL;      // Messpunkt 1 gemessener Z Wert
   I_Messpunkt_2_Z                  :REAL;      // Messpunkt 2 gemessener Z Wert
   I_Messpunkt_3_Z                  :REAL;      // Messpunkt 3 gemessener Z Wert
END_VAR

VAR_OUTPUT
   O_Parallelitaet_Flaeche          :REAL;      // Parallelität Zahnradfläche (mm)     
END_VAR

VAR
   Durchschnitt                     :REAL;      //Durchschnittswert der drei Messpunkte
   AbweichVonDurchschnitt1          :REAL;      //Abweichung des Messwerts 1 vom Durchschnitt
   AbweichVonDurchschnitt2          :REAL;      //Abweichung des Messwerts 2 vom Durchschnitt
   AbweichVonDurchschnitt3          :REAL;      //Abweichung des Messwerts 3 vom Durchschnitt
   MaxAbweichVonDurchschnitt        :REAL;      //maximale Abweichung vom Durchschnitt (ab Kreismittelpunkt)
END_VAR

    Durchschnitt:=(I_Messpunkt_1_Z + I_Messpunkt_2_Z + I_Messpunkt_3_Z)/3.0;
    AbweichVonDurchschnitt1 := I_Messpunkt_1_Z-Durchschnitt;
    AbweichVonDurchschnitt2 := I_Messpunkt_2_Z-Durchschnitt;
    AbweichVonDurchschnitt3 := I_Messpunkt_3_Z-Durchschnitt;
    
    IF ABS(AbweichVonDurchschnitt1) >= ABS(AbweichVonDurchschnitt2) THEN
        IF ABS(AbweichVonDurchschnitt1) >= ABS(AbweichVonDurchschnitt3) THEN
            MaxAbweichVonDurchschnitt := AbweichVonDurchschnitt1;
        ELSE
            MaxAbweichVonDurchschnitt := AbweichVonDurchschnitt3;
        END_IF;
    ELSE
        IF ABS(AbweichVonDurchschnitt2) >= ABS(AbweichVonDurchschnitt3) THEN
            MaxAbweichVonDurchschnitt := AbweichVonDurchschnitt2;
        ELSE
            MaxAbweichVonDurchschnitt := AbweichVonDurchschnitt3;
        END_IF;
    END_IF;
    
    O_Parallelitaet_Flaeche := 2 * (46.5 / I_Messkreisdurchmesser) * ABS(MaxAbweichVonDurchschnitt);
    


END_FUNCTION_BLOCK
 
Code:
...
    Winkel_Fest_Stempel_Grad := Winkel_Fest_Stempel_rad * 180.0 / PI; 
    
    O_Parallelitaet_Flaeche := (TAN(Winkel_Fest_Stempel_Grad*PI/180))*46.5;
    
    IF O_Parallelitaet_Flaeche < 0 THEN
        O_Parallelitaet_Flaeche := O_Parallelitaet_Flaeche * -1.0;
    END_IF;
...
... würde ich vereinfachen zu:
Code:
...
    O_Parallelitaet_Flaeche := ABS(TAN(Winkel_Fest_Stempel_rad)) * 46.5;
...
Die Umrechnung des Winkels von RAD in DEG, nur, um ihn in der nächsten Zeile von DEG in RAD zurück zu rechnen, bringt doch rein gar nichts, ausser evtl. Ungenauigkeiten.
Die Multiplikation mit 46.5 ich zwar nicht, aber vielleicht ist dies eine Konstante, die bereits einen RundungsFehler durch "Vereinfachung" enthält?

PS:
Noch 'n Bisschen EinsparPotenzial:
Code:
    Messpunkt_2_Y := I_Messkreisdurchmesser / 2.0 + ((SIN(30*PI/180))*I_Messkreisdurchmesser/2);
  
    Messpunkt_3_Y := I_Messkreisdurchmesser / 2.0 + ((SIN(30*PI/180))*I_Messkreisdurchmesser/2);
... ersetzen durch ...
Code:
    Messpunkt_2_Y := I_Messkreisdurchmesser * 3.0 / 4.0;
  
    Messpunkt_3_Y := I_Messkreisdurchmesser * 3.0 / 4.0;
... ganz ohne WinkelFunktion, also recht gut für DINT-Berechnung geeignet.

Der Messtaster hat die Auflösung 0,0001mm
Und der Messtaster gibt die Werte aus, mit denen Du dann rechnest? Oder wird der Messtaster selbst "ungenau" positioniert und misst dann relativ zu seiner ungenauen Position einen genauen Abstand?

Hast Du mal Onkel Dagoberts "SonnenstrahlenEinfluss" betrachtet/gemessen? Schon, wenn man auf µm "genau" messen will, sollte man das Thema Temperatur(-Schwankung) nicht ignorieren.
 
Zuletzt bearbeitet:
Der Messtaster hat die Auflösung 0,0001mm ../
Und wie hoch ist der Messfehler und wie die Wiederholgenauigkeit des Sensors? Und was hast du für Analogeingänge? Wenn die Summe der Rundungsfehler tatsächlich überwiegt, würde ich Haralds Vorschlag aus #13 annehmen. Bzw. würde ich mir auch ansehen, was es bei der S7-1500SP für Analogeingänge gibt. Hardwareseitig hat sich gegenüber der Classic-Welt auch eine Menge getan.

Bzw. muss man sich ja bei einer solch anspruchsvollen Messung um die ganze Apparatur und um jeden Sonnenstrahl Gedanken machen. Sind denn diese Rahmenbedingungen überhaupt gegeben?
 
Zuletzt bearbeitet:
Ich Hab mal den Tangens ducht eine Taylorreihe ersetzt.
Da kann man dann sehen, dass bei Werten

z1 8.0
z2 8.0
z3 8.005

für die Parallelität 0,016022 (tan) und 0,01606429 (Taylor) herauskommt.

Ab z3 8,0048 kommt für den tan immer 4,065 * 10^-6 raus, Taylor wird 0.0.

Das liegt bei der Tylorreihe daran dass der Winkel so klein wird (Winkel_Fest_Stempel_rad - PI geht gegen 0). Winkel_Fest_Stempel_Grad ist nun 180.0, da geht nichts mehr.
Umsteigen auf DINT könnte noch ein wenig bringen, da ist aber auch schnell Schluß, weil man ja etwas "Luft" zum Rechnen benötigt.

Winkel_Fest_Stempel_rad und PI müssen mit also höherer Genauigkeit berechnet werden. Je mehr Stellen, umso besser.


PS: Hoffe das kapiert noch jemand, was ich da zusammengeschrieben habe 8-0
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn ich mich recht erinnere ist in der Oscat-Bibliothek oder wie die auch immer... Bausteine für Lreal auf der 300'er CPU.

Dauert zwar länger aber du hast 12 Dezimalstellen... und dann sollte echt mal gut sein ( 1/10 µm wer braucht das denn so genau, nen Lufthauch oder ein Stapler in 10m Entfernung oder nur die Hallenbeleuchtung an/aus und dein Messergebnis ist für Nüsse.)

P.S.: Hoffe die Messanordnung steht auf einem eigenen Fundament...
 
Moin sargan26,

Das Problem ist einigermaßen zeitkritisch weil nächste Woche die Inbetriebnahme beim Kunden ist.

hätte man dieses, nicht ganz triviale, Thema nicht etwas eher im Projektverlauf bearbeiten sollen ;)?

Schön wäre es, mal eine Rückmeldung zu hören, ob einer der aufgeführten Lösungsvorschläge hilfreich ist.

VG

MFreiberger
 
Danke für alle Antworten und Vorschläge!

So sieht die aktuelle Version aus, ist aber immer noch nicht so genau, wahrscheinlich machen wir die Berechnung in der Datenbank mit einer Hochsprache.

Code:
FUNCTION_BLOCK "Berechnung_Parallelitaet"

VAR_INPUT
   I_Messkreisdurchmesser           :REAL;              // Messkreisdurchmesser
   I_Messpunkt_1_Z                  :REAL;              // Messpunkt 1 gemessener Z Wert
   I_Messpunkt_2_Z                  :REAL;              // Messpunkt 2 gemessener Z Wert
   I_Messpunkt_3_Z                  :REAL;              // Messpunkt 3 gemessener Z Wert
END_VAR


VAR_OUTPUT
   O_Parallelitaet_Flaeche          :REAL;              // Parallelität Zahnradfläche (mm)     
END_VAR


VAR
   PI                               :REAL;              // Kreiszahl
   Messpunkt_1_X                    :REAL;              // Messpunkt 1 berechneter X Wert
   Messpunkt_2_X                    :REAL;              // Messpunkt 2 berechneter X Wert
   Messpunkt_3_X                    :REAL;              // Messpunkt 3 berechneter X Wert
   Messpunkt_1_Y                    :REAL;              // Messpunkt 1 berechneter Y Wert
   Messpunkt_2_Y                    :REAL;              // Messpunkt 2 berechneter Y Wert
   Messpunkt_3_Y                    :REAL;              // Messpunkt 3 berechneter Y Wert
   Vektor_r2_r1_X                   :REAL;              // Vektor R2 - R1 X Wert
   Vektor_r2_r1_Y                   :REAL;              // Vektor R2 - R1 Y Wert
   Vektor_r2_r1_Z                   :REAL;              // Vektor R2 - R1 Z Wert
   Vektor_r3_r1_X                   :REAL;              // Vektor R3 - R1 X Wert
   Vektor_r3_r1_Y                   :REAL;              // Vektor R3 - R1 Y Wert
   Vektor_r3_r1_Z                   :REAL;              // Vektor R3 - R1 Z Wert
   Normalvektor_X                   :REAL;              // Normalvektor X Wert
   Normalvektor_Y                   :REAL;              // Normalvektor Y Wert
   Normalvektor_Z                   :REAL;              // Normalvektor Z Wert 
   Normalvektor_Festan_X            :REAL;              // Normalvektor Festanschlag X Wert
   Normalvektor_Festan_Y            :REAL;              // Normalvektor Festanschlag Y Wert
   Normalvektor_Festan_Z            :REAL;              // Normalvektor Festanschlag Z Wert 
   Winkel_Fest_Stempel_rad          :REAL;              // Winkel zwischen Festanschlag und Stempel (rad)
   Winkel_Fest_Stempel_Grad         :REAL;              // Winkel zwischen Festanschlag und Stempel (°)
   PI_DINT                               :DINT;              // Kreiszahl
   Messpunkt_1_X_DINT                    :DINT;              // Messpunkt 1 berechneter X Wert
   Messpunkt_2_X_DINT                    :DINT;              // Messpunkt 2 berechneter X Wert
   Messpunkt_3_X_DINT                    :DINT;              // Messpunkt 3 berechneter X Wert
   Messpunkt_1_Y_DINT                    :DINT;              // Messpunkt 1 berechneter Y Wert
   Messpunkt_2_Y_DINT                    :DINT;              // Messpunkt 2 berechneter Y Wert
   Messpunkt_3_Y_DINT                    :DINT;              // Messpunkt 3 berechneter Y Wert
   Vektor_r2_r1_X_DINT                   :DINT;              // Vektor R2 - R1 X Wert
   Vektor_r2_r1_Y_DINT                   :DINT;              // Vektor R2 - R1 Y Wert
   Vektor_r2_r1_Z_DINT                   :DINT;              // Vektor R2 - R1 Z Wert
   Vektor_r3_r1_X_DINT                   :DINT;              // Vektor R3 - R1 X Wert
   Vektor_r3_r1_Y_DINT                   :DINT;              // Vektor R3 - R1 Y Wert
   Vektor_r3_r1_Z_DINT                   :DINT;              // Vektor R3 - R1 Z Wert
   Normalvektor_X_DINT                   :DINT;              // Normalvektor X Wert
   Normalvektor_Y_DINT                   :DINT;              // Normalvektor Y Wert
   Normalvektor_Z_DINT                   :DINT;              // Normalvektor Z Wert 
   Normalvekt_Festan_X_DINT            :DINT;              // Normalvektor Festanschlag X Wert
   Normalvekt_Festan_Y_DINT            :DINT;              // Normalvektor Festanschlag Y Wert
   Normalvekt_Festan_Z_DINT            :DINT;              // Normalvektor Festanschlag Z Wert 
   Winkel_Fest_St_rad_DINT          :DINT;              // Winkel zwischen Festanschlag und Stempel (rad)
   Winkel_Fest_St_Grad_DINT         :DINT;              // Winkel zwischen Festanschlag und Stempel (°)
END_VAR
     
    // Es werden soviele Werte von REAL auf DINT und umgekehrt umgewandelt um die Genauigkeit der Berechnungen zu erhöhen, 
    // REAL hat nur eine Genauigkeit von 6 Stellen nach dem Komma. 
        
    // PI berechnen
    PI := 4 * ATAN(1);              


    // Messpunkt 1
    Messpunkt_1_X := 0.0;
    Messpunkt_1_Y := 0.0;
   
    // Messpunkt 2
    Messpunkt_2_X := 17.3205081;
    Messpunkt_2_Y := 0.0;
  
    // Messpunkt 3
    Messpunkt_3_X := 8.66025404;
    Messpunkt_3_Y := 15.0;
     
    // Berechnung Vektoren
    Vektor_r2_r1_Z_DINT := REAL_TO_DINT(I_Messpunkt_2_Z * 1000000) - REAL_TO_DINT(I_Messpunkt_1_Z * 1000000);
    Vektor_r3_r1_Z_DINT := REAL_TO_DINT(I_Messpunkt_3_Z * 1000000) - REAL_TO_DINT(I_Messpunkt_1_Z * 1000000);   
  
    Vektor_r2_r1_X := 17.3205081;
    Vektor_r2_r1_Y := 0.0;
    Vektor_r2_r1_Z := DINT_TO_REAL(Vektor_r2_r1_Z_DINT) / 1000000;
    Vektor_r3_r1_X := 8.66025404;
    Vektor_r3_r1_Y := 15.0;
    Vektor_r3_r1_Z := DINT_TO_REAL(Vektor_r3_r1_Z_DINT) / 1000000;
    
    Normalvektor_X_DINT := REAL_TO_DINT((Vektor_r2_r1_Y * Vektor_r3_r1_Z) * 1000000) - REAL_TO_DINT((Vektor_r3_r1_Y * Vektor_r2_r1_Z) * 1000000);
    Normalvektor_Y_DINT := REAL_TO_DINT((Vektor_r2_r1_Z * Vektor_r3_r1_X) * 1000000) - REAL_TO_DINT((Vektor_r2_r1_X * Vektor_r3_r1_Z) * 1000000);
    Normalvektor_Z_DINT := REAL_TO_DINT((Vektor_r2_r1_X * Vektor_r3_r1_Y) * 1000000) - REAL_TO_DINT((Vektor_r2_r1_Y * Vektor_r3_r1_X) * 1000000);


    Normalvektor_X := DINT_TO_REAL(Normalvektor_X_DINT) / 1000000;
    Normalvektor_Y := DINT_TO_REAL(Normalvektor_Y_DINT) / 1000000;
    Normalvektor_Z := DINT_TO_REAL(Normalvektor_Z_DINT) / 1000000;
    
    Normalvektor_Festan_X := 0.0;
    Normalvektor_Festan_Y := 0.0;
    Normalvektor_Festan_Z := 4.0;
    
    // Berechnung Parallelität
    Winkel_Fest_Stempel_rad := ACOS((DINT_TO_REAL(
    REAL_TO_DINT(Normalvektor_X*Normalvektor_Festan_X*1000000)
    +REAL_TO_DINT(Normalvektor_Y*Normalvektor_Festan_Y*1000000)
    +REAL_TO_DINT(Normalvektor_Z*Normalvektor_Festan_Z*1000000)) / 1000000)
    /
    ((SQRT(
    DINT_TO_REAL(
    REAL_TO_DINT(SQR(Normalvektor_X)*10000)
    +REAL_TO_DINT(SQR(Normalvektor_Y)*10000)
    +REAL_TO_DINT(SQR(Normalvektor_Z)*10000)) / 10000
    ))
    *
    (SQRT(
    DINT_TO_REAL(
    REAL_TO_DINT(SQR(Normalvektor_Festan_X)*10000)
    +REAL_TO_DINT(SQR(Normalvektor_Festan_Y)*10000)
    +REAL_TO_DINT(SQR(Normalvektor_Festan_Z)*10000)) / 10000
    )
    )));
    
    Winkel_Fest_Stempel_Grad := Winkel_Fest_Stempel_rad * 180.0 / PI; 


    O_Parallelitaet_Flaeche := ABS(TAN(Winkel_Fest_Stempel_rad)*46.5);


END_FUNCTION_BLOCK
 
Zurück
Oben