TIA Umwandlung negativer Wert von LINT auf LREAL

ModbusDani1995

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

ich lese Werte über Modbus RTU in ein Array of LINT ein.

Wenn ich dann einen negativen Wert von LINT auf LREAL konvertiere bekomm ich beim LREAL Wert das negative Maximum vom DINT Wert.
wenn ich mir den DINT Wert in Binär anzeigen lasse ist das erste Bit auch 1 was für einen negativen Wert stehen würde.
Am Gerät wird ein kleiner negativer Wert angezeigt.

Wie kann ich einen Negativen LINT Wert auf LREAL konvertieren?

LG Daniel
 

Anhänge

  • Datenumwandlung_SCL.PNG
    Datenumwandlung_SCL.PNG
    931,7 KB · Aufrufe: 54
  • Erstes_Bit_1_bei_negativen_Werten.PNG
    Erstes_Bit_1_bei_negativen_Werten.PNG
    628,7 KB · Aufrufe: 48
  • Negative LREAL Werte.PNG
    Negative LREAL Werte.PNG
    768,7 KB · Aufrufe: 49
  • Werte_am_Gerät.PNG
    Werte_am_Gerät.PNG
    823,6 KB · Aufrufe: 51
@PN/DP

Die Werte in grün funktionieren alle die lese ich als DINT aus und Konvertiere ich zu Real. Die Werte in Rot lese ich al LINT aus weil die ja 4 Wörter lang sind. hab es auch schon mit LongWord probiert.

1721141707175.png

1721141595353.png
 
Da passt was an der Zahlendarstellung der negativen Rohwerte nicht.
Da scheint ja Bit 63 nur das Vorzeichen darzustellen, aber für einen negativen Integer fehlt doch die korrekte Zweierkomplement-Darstellung.

Denke so heisst das...
...also damit meine ich das INT#-1 in Hex ja als 16#FFFFFFFF dargestellt wird und nicht nur das höchste Bit auf 1 gesetzt wird.

Wenn ich aus Screenshot des Anfangsbeitrages den Wert von ReadClient2[9] in den Windows-Calc abtippe, dann bekomme ich die selben elends hohen Werte wie beim OP.
Code:
BIN    1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 1011 0010 0111 0100
HEX    8    0    0    0    0    0    0    0    0    0    0    6    B    2    7    4

Soll der Wert vielleicht -438900 darstellen?
Die richtige HEX-Darstellung für -438900 wäre aber 16#FFFFFFFFFFF94D8C.
Man könnte jetzt manuell das Vorzeichenbit aus-maskieren, wandeln und dann irgendwo mal -1 rechen... Siehe Screenshot.

Aber es gibt in der S7 sicher elegantere Wege wie man das machen kann, gibt denke ich sogar Befehle für wandeln nach Zweierkomplement. Da können die Kollegen hier sicher helfen.

Edit: Kleine Korrektur nach nettem Hinweis von Ludewig.
 

Anhänge

  • WinCalc_800000000006B274.jpg
    WinCalc_800000000006B274.jpg
    37,7 KB · Aufrufe: 20
  • LINT_KonvertiernungsVeranschaulichung.jpg
    LINT_KonvertiernungsVeranschaulichung.jpg
    252,9 KB · Aufrufe: 21
Zuletzt bearbeitet:
Bekommst du denn überhaupt LINT aus deinem Gerät?
Hast du mal eine Beschreibung der Modbus-Werte deines Gerätes?
Wie immer: RTFM
Auf Seite 59 des Dokuments ist erklärt, dass negative Werte nur durch ein Vorzeichenbit im MSB gekennzeichnet sind.
Je nach "instrument model" gibt es 2 verschiedene Codierungen:
- nur Vorzeichenbit
- oder Zweierkomplement
Kann man das "instrument model" irgendwo einstellen oder ist damit der Gerätetyp gemeint und nicht änderbar?

Diese Werte mit Nur-Vorzeichenbit müssen für eine weitere Verwendung in der S7 zunächst in das "richtige" DINT- oder LINT-Format ins Zweierkomplement gewandelt werden (MSB entfernen und dann mit -1 multiplizieren). Das gilt nicht nur für 64 Bit Ganzzahlen, sondern auch für 32 Bit Ganzzahlen.

(irgendwo hatten wir hier im Forum schon mal so eine eigenwillige Codierung negativer Ganzzahl-Werte bei bestimmten chinesischen(?) Geräten)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Scheinbar wurde hier der falsche Zähler bestellt (bezogen auf das Datenformat).
In der Anleitung steht, dass der Zähler, je nach Bestelltyp, 2 Varianten des Vorzeichenbits liefert:
Letztes Bit für negativ, oder 2er Komplement. Für die Siemens-Datentypen richtig wäre eigentlich das 2er Komplement.

Jetzt wären hier also 2 Möglichkeiten:
Die LINT-Auswertung umbauen, also das letzte Bit ausmaskieren, und dann je nach Zustand desselben " * -1 ", oder halt eben nicht.
Oder, da der Zähler das offenbar unterstützt, die Werte einfach von Haus aus als REAL auslesen, Register 1000 ff ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das funktioniert nur scheinbar. Auch da sind negative Werte mit nur einem Vorzeichenbit codiert und müssen erst in Zweierkomplement konvertiert werden.
Zu den grünen Werten: ( Also natürlich an den TE @ModubusDani1995 und nicht an Harald)
Auf deinen anfänglichen Bildchen hättest du (ein bisschen gerundet):
L1: - 2.000.000 A
L2: - 2.000.000 A
L3: +1,77 A
Die wahrscheinlichkeit tendiert stark gegen 0 das dass korrekt ist.

Bei dieser extremen Schiefbelastung fliegt dir wahrscheinlich der Trafo um die Ohren, und der Netzbetreiber erschießt dich Standesrechtlich ...
 
Zuletzt bearbeitet:
Die DWord/LWord mit Ganzzahl-Werten mit Vorzeichenbit kann man z.B. so in "normales" Zweierkomplement konvertieren:
Code:
FUNCTION "INT31_DINT" : DInt
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      dwInt31 : DWord;
   END_VAR
   VAR_TEMP
      diTemp : DInt;
   END_VAR

BEGIN
#diTemp := DWORD_TO_DINT(#dwInt31); // auf Input nur einmal zugreifen
IF #diTemp < 0 THEN //MSB = 1 (negativ) ?
    #INT31_DINT := 16#80000000 - #diTemp; // entspricht #INT31_DINT := -(#diTemp AND 16#7FFFFFFF); // (*)
ELSE
    #INT31_DINT := #diTemp;
END_IF;
   
END_FUNCTION
(*) Falls TIA SCL die AND-Verknüpfung von DInt anmeckert, kann man die Zeile auch in eine Addition mit einem numerischen Wert umformen:
#INT31_DINT := -(#diTemp + 16#80000000); oder #INT31_DINT := -(#diTemp - 16#80000000); (Plus oder Minus 16#80000000 ist egal).

Umwandlung LWord (64 Bit) in LINT funktioniert entsprechend mit 16#7FFFFFFF_FFFFFFFF bzw. 16#80000000_00000000
 
Zuletzt bearbeitet:
@MSB Da ist wieder das Problem das bei einem negativen Wert oder bei 0.0 das Maximum in dem Fall von DINT rauskommt.

Also alle positiven funktionieren aber bei 0 und - Werten kommt immer das maximum von LInt oder DInt. Die positiven Werte wurde alle kontrolliert und die stimmen mit der Anzeige am Gerät überein.

Diesen Vorschlag hab ich erfolgslos probiert. Ich habe auch /10000.0 schon versucht.

Versuch mal die " /10000" als "/LReal#10000.0" zu schreiben.
Nicht das hier nochmal falsch Konvertiert wird.


1721196655094.png
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die von Dir genutzte Geräte Variante nutzt zur Darstellung von negativen Zahlen kein Zweierkompliment, sondern das oberste Bit enthält das Vorzeichen.
Positive Zahlen kannst Du deshalb ganz normal in ein Real wandeln.
Du packst die Daten vielleicht besser erstmal in ein LWORD anstatt ein LINT, dann prüfst Du, ob das oberste Bit gesetzt ist. Ist dies nicht der Fall, kann die Zahl einfach in ein REAL gewandelt werden. Bei einer negativen Zahl löscht Du das oberste Bit, wandelst die Zahl in ein REAL und multiplizierst die Zahl mit -1.
Ist übrigens im Handbuch auch gut beschrieben:
1721198181015.png
 
Zuletzt bearbeitet:
@ModbusDani1995 und @oliver.tonn
habt ihr PN/DPs Beitrag in #13 nicht gesehen ?
Ich schon, nur der OP nicht, deswegen hatte ich nochmals einen Vorschlag gemacht.
Ich hätte aber fairerweise auch noch auf @PN/DPs Vorschlag hinweisen sollen. Ich wusste nicht, ob man in TIA auch bei einem xINT einzelne Bits beeinflussen kann, sonst hätte ich nur auf seinen Vorschlag verwiesen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
@MSB

Meinst du Registeradresse 1000? Gibts eigene Register wo man REAL Werte auslesen kann?
Oder wo hast du das mit der Adresse 1000 gelesen?

Oder, da der Zähler das offenbar unterstützt, die Werte einfach von Haus aus als REAL auslesen, Register 1000 ff ...
 
@MSB

Meinst du Registeradresse 1000? Gibts eigene Register wo man REAL Werte auslesen kann?
Oder wo hast du das mit der Adresse 1000 gelesen?

Oder, da der Zähler das offenbar unterstützt, die Werte einfach von Haus aus als REAL auslesen, Register 1000 ff ...

Du kannst Beiträge aus dem Forum auch direkt zitieren, indem du beim Beitrag unten rechts auf "Zitieren" klickst.
 
Zurück
Oben