4 Byte in ein REAL zusammenführen

JandeFun

Level-1
Beiträge
65
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

ich habe das folgende Problem. Ich möchte über eine Profibus Verbindung Daten aus einem Gerät auslesen. Die Verbindung steht und die Daten werden auch übermittelt.
Leider liegt auf der ersten Adresse ein Wert im Byte und folgend, dazu mehrere Werte im Float Format.
Byte Byte Adresse: 0
Float Byte Adresse: 1-4
Float Byte Adresse: 5-6
etc.

Über den System Manager kann ich leider nur 8 / 16 / 32 Word Blöcke zum auslesen des Gerätes konfigurieren, wodurch meine komplette Adressierung um genau ein Byte verrutscht. Damit werden die Float Werte nicht richtig angezeigt.

Ich übernehme die Werte in ein Array in der Größe 0..123 Byte, da ich nun 62 Word konsistent vom Gerät einlese.
Im PLC wollte ich nun aus den einzelnen Bytes die jeweiligen REAL Werte wieder mittels eines Pointers zusammensetzen, was mir allerdings nicht so ganz gelingt.
Scheinbar lässt sich der Pointer nicht um eine Byte Breite erhöhen.

pt:pOINTER TO WORD;
testarray: ARRAY [0..3] OF BYTE := 10,20,30,40;
testREAL: REAL;

pt := ADR(testREAL);
pt^ := testarray [0];
pt := (pt + 1);
pt^ := testarray [1];
pt := (pt + 1);
pt^ := testarray [2];
pt := (pt + 1);
pt^ := testarray [3];
pt := (pt + 1);
testREAL;

Was ist das dem Code Schnipsel falsch? Gibt es eine andere Möglichkeit die Werte ins richtige Format zu bekommen?

Vielen Dank für eure Antworten.

Sytem: Twin Cat 32 / Build: 2014
 
Vielen Dank

Das funktioniert schon mal offline ohne Fehler.

Trotzdem würde ich gerne verstehen, warum der erste Code nicht funktioniert.

Ist vielleicht die erhöhung um 1 nicht mit einem Byte gleichzusetzen?
 
Ein REAL besteht aus Mantisse und Exponent:
http://de.wikipedia.org/wiki/Fließkommazahl#Mantisse

Mit deinem Code könntest du ggf. die 4 Byte in ein DWORD kopieren und dieses dann in REAL wandeln...

Grundsätzlich sollte es doch total egal sein, um welches Zahlenformat es sich handelt. Alle Zahlenwerte werden letztendlich im 2er Komplement in einem Bitmuster dargestellt. Die Anzeige des Zahlenwertes, ob REAL oder INT ist nur eine Interpretation des Bit Musters.
Wenn ich eine Real Zahl in 4 Byte zerlege, das Bitmuster nicht verändere und sie dann in der gleichen Reihenfolge wieder zusammensetze muss auch die gleiche Zahl wieder herauskommen, wenn die Interpretation des Bitmusters wieder REAL ist. Richtig?
 
pt := Pointer TO Word => muss natürlich Pointer TO REAL heißen.

Das komische ist, wenn ich den Pointer das erste mal um eine Byte Adresse erhöhe, kommt eine Zahl heraus, die überhaupt nicht dem Pointer Format ähnlich ist, wie nach dem Befehl

pr := ADR(TestREAL);

Muss ich die 1 zur Erhöhung vielleicht anders deklarieren?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das komische ist, wenn ich den Pointer das erste mal um eine Byte Adresse erhöhe, kommt eine Zahl heraus, die überhaupt nicht dem Pointer Format ähnlich ist, wie nach dem Befehl

pr := ADR(TestREAL);
Das ist schon seltsam, bei mir funktioniert das wie erwartet. Was kommt denn für eine Adresse heraus, wenn Du
pt:=ADR(testarray[1]); schreibst?
 
Hallo

nun funktioniert es auch bei mir. Ich hatten den "Pointer To REAL" deklariert. Durch die erhöhung des Pointers um 1 hat das System scheinbar um 4 Byte erhöht ( REAL Breite).

Richtig muß es heißen:

VAR
TestCounter: REAL;
pt0: POINTER TO BYTE;(*Hier lag der Fehler*)
pt: POINTER TO BYTE;(*Hier lag der Fehler*)
BereichLeistungsmessungRohwerte: ARRAY [0..3] OF BYTE;
LEISTUNGSMESSUNG_DATEN_TEST: REAL;
END_VAR

TestCounter := TestCounter + 1.111564;

(* Werte in 4 Byte teilen*)
pt0 := ADR (TestCounter);
BereichLeistungsmessungRohwerte [0] := pt0^;
pt0 := (pt0 + 1);
BereichLeistungsmessungRohwerte [1] := pt0^;
pt0 := (pt0 + 1);
BereichLeistungsmessungRohwerte [2] := pt0^;
pt0 := (pt0 + 1);
BereichLeistungsmessungRohwerte [3] := pt0^;

(*Wert aus 4 Byte zusammensetzen*)
pt := ADR (LEISTUNGSMESSUNG_DATEN_TEST);
pt^ := BereichLeistungsmessungRohwerte [0];
pt := (pt + 1);
pt^ := BereichLeistungsmessungRohwerte [1];
pt := (pt +1);
pt^ := BereichLeistungsmessungRohwerte [2];
pt := (pt +1);
pt^ := BereichLeistungsmessungRohwerte [3];

LEISTUNGSMESSUNG_DATEN_TEST;
 
Zurück
Oben