Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!
für eine CAN-Bus Nachricht ist in meinem CAN-Bus Protokoll ein Wert als 24 Bit Integer definiert.
Der Benutzer kann auf dem Frontpanel einen gewünschten Double-Wert eingeben, dieser wird dann in ein 24 Bit FXP umgewandelt. Mein CAN-Bus Treiber erwartet ein U8 Byte Array, der Wert muss also noch auf 3 Byte aufgeteilt werden.
Jetzt habe ich beim ausprobieren folgendes festgestellt, was ich mir nicht erklären kann:
Im Blockdiagramm wird die Umwandlung nach FXP einmal mit dem Element "Nach Festkomma" und einmal mit "Typ Cast" gemacht:
Meiner Meinung nach müssten bei beiden Verfahren die gleichen Ergebnisse rauskommen, dem ist aber nicht so. Das Ergebnis von "Output 1" ist so wie ich es bei einem Eingabewert von 4000000 erwartet habe, das Ergebnis von "Output 2" kann ich mir nicht erklären...
Kann mir evtl jemand erklären warum dies so ist?
Falls ich das falsche Unterforum gewählt habe, bitte ich den Beitrag entsprechend zu verschieben.
Danke!
Gruß
Stefan
31.07.2015, 10:34 (Dieser Beitrag wurde zuletzt bearbeitet: 31.07.2015 10:41 von GerdW.)
erstmal eine wichtige Info: ein FXP belegt im Speicher, egal wie du es parametriert hast, immer 64 bit. Steht auch in der LabVIEW-Hilfe!
Dann:
Ein Typecast interpretiert nur die Daten im Speicher um!
Einmal wandelst du deinen Input per Konvertierfunktion in ein FXP um, im anderen Fall per Typecast. Das sind zwei vollkommen unterschiedliche Dinge und kann nicht gut gehen…
Weiterhin:
Zitat:in meinem CAN-Bus Protokoll ein Wert als 24 Bit Integer definiert.
Warum ist dein Input dann ein DBL?
Warum wandelst du dann in FXP um?
Warum wandelst du den Integer nicht direkt in 3 Bytes um?
(Umwandlung quasi zu Fuß…)
Weil die Werte noch skaliert werden und ich dem Benutzer eine vereinfachte Eingabe ermöglichen möchte. Er soll sich nicht noch damit befassen müssen den Sollwert (beispielsweise für eine Drehzahl) umzurechnen.
Beispiel: 8000000(int24) := 20000rpm das entspricht dann einer Auflösung von 0,0025rpm
Der Benutzer soll einfach zum Bespiel 3765,54 rpm eingeben können (und nicht 1506216(int24) rpm). Im Programm wird es dann umgerechnet, gerundet und in ein U8-Byte-Array umgewandelt.
Zitat:Warum wandelst du dann in FXP um?
Weil ich den FXP auf 24Bit einstellen kann (auch wenn er im Speicher 64 Bit belegt)
Zitat:Warum wandelst du den Integer nicht direkt in 3 Bytes um?
So ähnlich war auch mein erster Ansatz, den ich aber wieder verworfen hatte, da ich nicht zum richtigen Ergebnis gekommen bin... Werde es mal so wie in deinem Screenshot versuchen. Evtl. hatte ich hier High und Low Byte vertauscht...
Zitat:Der Benutzer soll einfach zum Bespiel 3765,54 rpm eingeben können (und nicht 1506216(int24) rpm). Im Programm wird es dann umgerechnet, gerundet und in ein U8-Byte-Array umgewandelt.
Ich habe nur nicht verstanden warum (siehe erster Post) zwei unterschiedliche Werte rauskommen wenn ich einmal mit "Nach Fixpoint" und einmal mit "Typ Cast" arbeite...
100% klar ist es mir leider immer noch nicht. Ich weiß jetzt, dass die beiden Funktion anscheinend was völlig unterschiedliches machen, was mir vorher nicht bewusst war.
Ich dachte, dass nach der Funktion "Nach FXP" ein entsprechender Fixpoint rauskommt und mit TypCast (FXP am Typ Anschluss) das gleiche...
Gruß
Stefan
31.07.2015, 12:58 (Dieser Beitrag wurde zuletzt bearbeitet: 31.07.2015 13:00 von GerdW.)
Zitat:100% klar ist es mir leider immer noch nicht.
Computer arbeiten nur mit Bits und Bytes, erst die Programme bringen Ordnung hinein: Was die Bytes bedeuten, legt erst das Programm fest!
Bei einer Konvertierung wird die Zahl so umgewandelt, dass im Zieldatentyp der gleiche Wert herauskommt. Beispiel: aus einem U8 mit Wert 123=0x7b wird ein DBL mit den 8 Bytes "40 5E C0 00 00 00 00 00". Beides mal der Wert 123, aber vollkommen unterschiedliche Bytes im Speicher!
Ein TypeCast lässt den Speicher, in dem ein Wert liegt, unverändert und interpretiert diesen Wert nur anders. Aus einem I32 mit den Bytes "01 02 03 04" kann man ein U8-Array mit 4 einzelnen Bytes machen. Oder zwei U16 mit "01 02" und "03 04". Oder ein SGL, welcher dann dummerweise den Wert "2.38794E-38" hat…
Ein TypeCast ist KEINE Konvertierung. Das sind zwei vollkommen unterschiedliche Funktionen!
Du hast in einem Fall einfach die Bytes im Speicher uminterpretiert und im anderen Fall erst andere Bytes daraus gemacht und dann nochmal uminterpretiert!
Es geht hier doch darum, eine Gleitkommazahl mit Fixkomma (z.B mit zwei Kommastellen) in ein 24 bit Integerformat (als 3 Byte-Array) zu konvertieren. Das geht natürlich nur innerhalb eines gewissen Zahlenbereichs. Es sollen auch negative Werte vorkommen dürfen (Wenn nicht, würde die Hin- und Rückkonvertierung etwas einfacher als in den unten angehängten VI. Außerdem würde der dann nur im positiven liegende Zahlenbereich verdoppelt).
Zur Lösung dieses Problems solltest Du das Format FXP vergessen. Das ist z.B dazu geeignet, im Finanzwesen bei Berechnungen mit Millionenbeträgen noch alles auf den Pfennig Cent genau zu haben. Was es in Labview zu suchen hat, weiß ich nicht, es wird dort jedenfalls kaum verwendet - wenn überhaupt.
Der Zahlenbereich, in dem die Übertragung im Beispiel mit 2 Kommastellen funktioniert, ist
-83886.08 .. 83886.07
..und hier noch das alternative Progrämmchen mit Typecast - um diesen Vergleich gings doch:
(Die beiden 3-Byte-Array sind natürlich gleich. Der Code ist etwas einfacher, aber nicht unbedingt einfacher zu kapieren)
Danke, wieder etwas dazugelernt. Und um das zu erfahren, war doch der Versuchsballon mit der hingeworfenen Bemerkung "..wird kaum verwendet, wenn überhaupt" keine schlechte Idee
Gruß Ludwig