auf bestimmte Nachkommastellen runden

Thomas E.

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

mit welcher Funktion kann ich im ST (TwinCAT v.2.11.xxxx) bei einer REAL-Zahl die Anzahl der Nachkommastellen begrenzen?

Ausgangszahl (REAL): 12,597212
Formatiert (REAL): 12,6 (eine Nachkommastelle)

Wobei ich gern noch die Anzahl der Nachkommastellen angegeben hätte. Und es soll eine REAL-Zahl bleiben, kein String!

Danke im Voraus
Grüße Thomas
 
Hallo,

es gibt keine elegante Lösung dafür, aber so geht es:

z.B: RealWert*10 --> REAL_TO_DINT-->DINT_TO_REAL--> RealWert/10

10 entspricht einer Nachkommastelle
100 entspricht zwei Nachkommastellen
usw...

man könnte auch eine Baustein dafür machen...
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe das jetzt auch mal probiert. Es funktioniert auch fast perfekt, der einzige Haken ist, dass die Kommastelle immer 0 ist.

rMotortemp_Zuluft_Dach:=DINT_TO_REAL (REAL_TO_DINT(Motortemp_Zuluft_Dach / 32.767 * 10) /10 );

Motortemp_Zuluft_Dach, ist ein Word das von ner AI Karte kommt, ich weis, ist blöd benannt :p#

Was mache ich da falsch ?

Grüße
Sebastian
 
Also wenn ich auf 2 Kommastellen runden möchte, mache ich es immer so:
Code:
MeinRealWert := DINT_TO_REAL(REAL_TO_DINT(MeinRealWert * 100)) / 100;
 
Hallo zusammen,

ich habe das jetzt auch mal probiert. Es funktioniert auch fast perfekt, der einzige Haken ist, dass die Kommastelle immer 0 ist.

rMotortemp_Zuluft_Dach:=DINT_TO_REAL (REAL_TO_DINT(Motortemp_Zuluft_Dach / 32.767 * 10) /10 );

Motortemp_Zuluft_Dach, ist ein Word das von ner AI Karte kommt, ich weis, ist blöd benannt :p#

Was mache ich da falsch ?

Grüße
Sebastian

Skalierst du den Wert des Analogeingang denn überhaupt.

Was für Werte hast du denn in deinem Motortemp_Zuluft_Dach? Wenn das ein Word ist, können da ja erstmal keine Kommastellen vorhanden sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich habe das jetzt auch mal probiert. Es funktioniert auch fast perfekt, der einzige Haken ist, dass die Kommastelle immer 0 ist.

rMotortemp_Zuluft_Dach:=DINT_TO_REAL (REAL_TO_DINT(Motortemp_Zuluft_Dach / 32.767 * 10) /10 );

Motortemp_Zuluft_Dach, ist ein Word das von ner AI Karte kommt, ich weis, ist blöd benannt :p#
Dein Fehler ist, dass Du gar nicht verstehst, was Dein AI Dir liefert und Du das Ganze dadurch falsch angehst. Dein AI wird Dir ein INT liefern, auch wenn bei der Hardware WORD stehen wird. Mit diesem Wert rechnest Du, ohne ihn vorher in ein REAL zu wandeln mit Konstanten, die Dein System als Ganzzahlen interpretiert so wie Du sie angegeben hast und dadurch fallen auch alle Nachkommastellen weg bei Deiner Berechnung, denn die gibt es bei Ganzzahlen nicht. Damit das klappen kann solltest Du Deinen Wert in ein DINT wandeln, dann mit 10 multiplizieren und durch 32767 (Oder meintest Du tatsächlich 32,767?) teilen. Das Ergebnis dann in REAL wandeln und durch 10 teilen, aber ACHTUNG, nicht durch 10, sondern durch 10.0 (Bei Codesys ist der Punkt das Komma), das macht nämlich einen Unterschied, auch wenn es nicht so aussieht, wobei, wenn die andere Zahl ein REAL ist vielleicht auch nicht, aber korrekter wäre es.
Übrigens habe ich den Hinweis schon bei einem anderen Thread gegeben. Hört auf alte Threads zu kapern, erstellt einen neuen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
der einzige Haken ist, dass die Kommastelle immer 0 ist.

rMotortemp_Zuluft_Dach:=DINT_TO_REAL (REAL_TO_DINT(Motortemp_Zuluft_Dach / 32.767 * 10) /10 );
Dein Analog-Eingang liefert 0..32767 = 0..100 (°C) ?

Du musst genau hinschauen wo Du die Klammern setzt - das "/10" muß hinter die letzte Klammer. In der Klammer wird noch Ganzzahl gerechnet, daher wird die Nachkommastelle immer 0. Wenn der ST-Compiler erzwingen würde, daß REAL-Konstanten mit Dezimalpunkt geschrieben werden müssen, dann wäre das vielleicht aufgefallen, daß dauernd unsichtbar zwischen Datentypen gesprungen wird. Ganz richtig müsstest Du schreiben:
Code:
rMotortemp_Zuluft_Dach:=DINT_TO_REAL(REAL_TO_DINT[COLOR="#0000FF"][B]([/B][/COLOR] INT_TO_REAL[COLOR="#FF0000"][B]([/B][/COLOR]Motortemp_Zuluft_Dach[COLOR="#FF0000"][B])[/B][/COLOR] / 32.767 * 10.0 [COLOR="#0000FF"][B])[/B][/COLOR]) / 10.0;

Harald
 
Dein Analog-Eingang liefert 0..32767 = 0..100 (°C) ?
Ganz richtig müsstest Du schreiben:
Code:
rMotortemp_Zuluft_Dach:=DINT_TO_REAL(REAL_TO_DINT[COLOR=#0000FF][B]([/B][/COLOR] INT_TO_REAL[COLOR=#FF0000][B]([/B][/COLOR]Motortemp_Zuluft_Dach[COLOR=#FF0000][B])[/B][/COLOR] / 32.767 * 10.0 [COLOR=#0000FF][B])[/B][/COLOR]) / 10.0;
Hallo Harald,
bitte korrigiere mich falls ich falsch liege, aber wenn der Punkt bei 32.767 tatsächlich ein Komma sein soll und Werte von 0..100°C geliefert werden sollen, müsste doch 327.67 genommen werden und nicht nicht 32.767, das wäre doch sonst ein Bereich von 0-1000°C, oder?
 
Du hast recht, mit den 32.767 (Punkt ist Dezimalpunkt) wird auf 0..1000 umgerechnet. Meine Vermutung "0..100" passt nicht.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Oliver,

erstmal danke für die Erklärung. Also es ist so, an der Analogeingangskarte hängt ein Messumformer der aus nem Pt100 ein 4-20mA Signal macht, Skalierung 0-100°C. Die Eingangskarte ist ne Wago 750-454. Laut Hardwarekonfiguration sollte da ein Word rauskommen ...

Wieso sollte ich einen neuen Thread erstellen ? Das passt doch zu diesem ganz gut ?
 
Ok das mit den Klammern hab ich verbummelt. Danke für den Hinweis Harald :)
Ja da sollen 0-100°C rauskommen, somit muss ich 327.67 rechnen.

rMotortemp_Zuluft_Dach:=DINT_TO_REAL (REAL_TO_DINT(Motortemp_Zuluft_Dach / 327.67 * 10)) / 10.0;

So funzt es nun. 0-100,0°C. Vielen Dank an Harald und Oliver.
 
Zuletzt bearbeitet:
Wieso sollte ich einen neuen Thread erstellen ? Das passt doch zu diesem ganz gut ?
Gut, dieser Thread war noch nicht als gelöst markiert, aber wäre er es könnte es Dir passieren, dass Du keine oder eine verspätete Antwort erhältst.
Dann kannst Du den Thread, da Du ihn nicht erstellt hast, nicht als gelöst markieren, dass geht nur als Ersteller und wenn einer ein ähnliches Problem hat kann er leichter eine Lösung finden, wenn der Thread entsprechend markiert ist.
 
rMotortemp_Zuluft_Dach:=DINT_TO_REAL (REAL_TO_DINT(Motortemp_Zuluft_Dach / 327.67 * 10)) / 10.0;

So funzt es nun.
Trotzdem Kritik: ist das wirklich sooo schwer oder sooo unzumutbar viel Arbeit, die erste 10 auch als 10.0 zu schreiben und "INT_TO_REAL(Motortemp_Zuluft_Dach)"? Gut, hier kommt der ST-Compiler alleine drauf daß der Programmierer "10.0" gemeint hat und Motortemp_Zuluft_Dach erst nach REAL konvertiert werden soll/muß - allerdings lediglich wegen dem einen Dezimalpunkt in 327.67. Ein flüchtiger Leser des Programmcodes sieht diese nicht ganz unwichtigen Details aber nicht. Wenn diese Konstante 327.67 wegfällt oder zufällig eine glatte Konstante wäre (z.B. der Programmierer würde "327.67 * 100" schreibfaul zu 32767 zusammenfassen), dann übersetzt der ST-Compiler die Zeile ganz anders als der Programmierer sich in seinen kühnsten Träumen vorstellt... und das Ergebnis wäre (fast) immer 0. Also einfach angewöhnen, REAL-Konstanten auch immer eindeutig mit Dezimalpunkt schreiben.

Harald
 
Danke für die Kritik.
Ich hatte es schlicht nicht für nötig gehalten. Aber deine Argumentation ist schlüssig, ich werde es ändern und in Zukunft so machen.
 
Zurück
Oben