Rohdaten Variable mit VBS verarbeiten

Bender25

Level-2
Beiträge
584
Reaktionspunkte
20
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo....

Wie ihr seht findet bei mir gerade ein großer Umschwung statt.

Habe folgendes Problem.

Ich lese und verarbeite einen Analogwert mittels eines FB. Dort werden Meßwertausfälle, Störungen, Schaltgrenzen, Meßbereich Anfang und Ende usw. gebildet und ausgegeben.

Nun ist meine überlegung diesen Instanz DB über eine Struktur auszulesen.
Was aber der nachteil an der Sache ist das ich Variablen ohne Ende verbrate wenn.

Schön an der Sache wär es nun und so meine überlegung, ob ich diesen Instanz DB direkt mit einer Rohdatenvariable auslese und mir die Störmeldungen selber mit VBS heraus picke.
Das geht soweit ja eigentlich relativ einfach.
Nur wie bekomme ich dann meinen Meßwert und Grenzwerte zusammen gebaut mit VBS? Muß ja irgendwie einen bereich angeben in dem mein Real wert liegt.??
Hoff ich habs irgendwie verständlich rüber gebracht was mein Problem ist :confused:

Dank euch schon mal
 
Denke mal, du meinst die Typumwandlung von den Byte-Rohdaten in Real?

Für Delphi sieh das so aus:

Code:
function S7_Float(Daten: Integer): Real;
var
  fiu: single;
begin
  move(Daten,fiu,4); { bloß keine impliziten Rechenoperationen durch casts! }
  S7_Float := fiu;
end;

Sollte in VBS fast genauso sein.
PS. Geht auf Zottel zurück :rolleyes: .
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ralle schrieb:
Denke mal, du meinst die Typumwandlung von den Byte-Rohdaten in Real?

Für Delphi sieh das so aus:

Code:
function S7_Float(Daten: Integer): Real;
var
  fiu: single;
begin
  move(Daten,fiu,4); { bloß keine impliziten Rechenoperationen durch casts! }
  S7_Float := fiu;
end;

Sollte in VBS fast genauso sein.
PS. Geht auf Zottel zurück :rolleyes: .


hmm danke mal... problem ist nur das ich kein Skript-Gott bin wie Zottel oder andere hier.... :(
Aber trozdem danke mal...;)
 
Hallo Bender25!

Ich weiss zwar nicht was eine Rohdatenvariable ist, aber möchtest du wissen wie man aus 4 einzelnen Bytes ein Real berechnet mit VB-Script oder was genau ist dein Problem?

Gruß Donnerkeil
 
Zuletzt bearbeitet:
Donnerkeil schrieb:
Hallo Bender25!

Ich weiss zwar nicht was eine Rohdatenvariable ist, aber möchtest du wissen wie man aus 4 einzelnen Bytes ein Real berechnet mit VB-Script oder was genau ist dein Problem?

Gruß Donnerkeil

ja genau so in der art. Ich habe eine Instanz DB in dem verschiedene Real Werte (Analogwert, Meßbereich Anfang, Meßbereich Ende, Grenzwert MAx Grenzwert Min, und einzelne Bits für MEßwertstörung usw) vorliegen.

Jetzt möchte ich gerne mit nur einer Variable (Rohdaten) den gesamten DB einlesen.
z.b. liegt der Analog Ausgabe WErt in Real auf Adresse 40. ist ist natürlich von dort an 4 Byte lang.
DIese 4 Byte muß ich quasi zusammen packen damit ich mein REal wert habe....

Hoff das es so verständlich ist.

Vielen dank euch mal
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Genau das tut eigentlich das Beispiel mit dem move-Befehl.​
Zu Fuß geht es auch mit dem Code unten:

Das "Zusammenaddieren" der Bytes mache ich wie folgt:

DBDat.SPSBuf ist ein Array aus Bytes

Daten ist ein Type wie folgt

Code:
//TypeCast
type int_short_union=record
case integer of
  1:(I32:Integer);
  2:(I16:array[0..1] of word);
  3:(I8:array[0..3] of byte);
end;
 
Daten: int_short_union;
 
Daten.I8[0] := DBDat.SPSBuf[SPS, L+3];
Daten.I8[1] := DBDat.SPSBuf[SPS, L+2];
Daten.I8[2] := DBDat.SPSBuf[SPS, L+1];
Daten.I8[3] := DBDat.SPSBuf[SPS, L];
 
Daten_Real := S7_Float(Daten.I32);
Code:
[LEFT]//Übergabe einer Gleitpunktzahl von S7 an Delphi[/LEFT]
//eingelesen werden 4 Byte, diese werden zu einer Integer-Zahl aufaddiert (-->Daten)
//und müssen dann in eine Delphi-Gleitpunktzahl umgewandelt werden
function S7_Float(Daten: Integer): Real;
var
  Exp, Mant, Count: Integer;
  Mant_r, D_Real: Real;
begin
  Exp := ((Daten shl 1) shr 24) - 127;
  Mant := (Daten shl 9) shr 9;
 
  Mant_r := 0;
  Count := 1;
  while Count <= 23 do
  begin
    //nachsehen, ob Bit an Stelle Count 0 oder 1
    if ((Mant and (1 shl (23 - Count))) > 0) then
      Mant_r := Mant_r + Power(2 , -Count);
    Count := Count + 1;
  end;
  //eine echte Null erzeugen !!!
  if ((Exp = -127) and (Mant = 0)) then
    Mant_r := 0
  else
    Mant_r := 1 + Mant_r;
  D_Real := Mant_r * Power(2, Exp);
  //Vorzeichen testen und einrechnen
  if ((Daten shr 31) > 0) then
    S7_Float := -D_Real
  else
    S7_Float := D_Real;
end;




 
Zuletzt bearbeitet:
Hallo,
hier eine VBS-Version für WinCC-Rohdaten (Bytearrays)

Code:
' Single entsprechend IEEE 754
'~~~~~~~~~~~~~~~~~~~

Function GetSingle (BYREF arr, ix)

    Dim vz, ex, ma, x

    If arr(ix) And &h80 Then vz = -1 Else vz = 1
    ex = (arr(ix) And &h7f) * 2 + arr(ix+1) \ 128 - 127                ' - Bias (127)
    ma = (((arr(ix+1) And &h7f) * &h100 + arr(ix+2)) * &h100 + arr(ix+3)) / &h800000

    If ex = -127 Then
        'Null und denormalisierte Werte
        If ma = 0 Then    x = 0    Else    x = vz * ma * 2^-127

    Elseif ex = 128 Then
        ' Unendlich und Overflow - hier sinnvolle Fehlerbehandlung einfügen !
        If ma = 0 Then    x = 1/0 Else    x = 2^1024

    Else
        x = vz * (1 + ma) * 2^ex

    End If

    GetSingle = x

End Function



' Test ohne WinCC (Code als Test.vbs) abspeichern und starten)
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dim arrTest

arrTest = Array (&h00, &h00, &h40, &h49, &h0f, &hdb)    ' Pi ab Offset 2

MsgBox GetSingle (arrTest, 2)
 
Ralle schrieb:
Genau das tut eigentlich das Beispiel mit dem move-Befehl.​

Zu Fuß geht es auch mit dem Code unten:

Das "Zusammenaddieren" der Bytes mache ich wie folgt:

DBDat.SPSBuf ist ein Array aus Bytes

Daten ist ein Type wie folgt

Code:
//TypeCast
type int_short_union=record
case integer of
  1:(I32:Integer);
  2:(I16:array[0..1] of word);
  3:(I8:array[0..3] of byte);
end;
 
Daten: int_short_union;
 
Daten.I8[0] := DBDat.SPSBuf[SPS, L+3];
Daten.I8[1] := DBDat.SPSBuf[SPS, L+2];
Daten.I8[2] := DBDat.SPSBuf[SPS, L+1];
Daten.I8[3] := DBDat.SPSBuf[SPS, L];
Code:
[LEFT]//Übergabe einer Gleitpunktzahl von S7 an Delphi[/LEFT]
//eingelesen werden 4 Byte, diese werden zu einer Integer-Zahl aufaddiert (-->Daten)
//und müssen dann in eine Delphi-Gleitpunktzahl umgewandelt werden
function S7_Float(Daten: Integer): Real;
var
  Exp, Mant, Count: Integer;
  Mant_r, D_Real: Real;
begin
  Exp := ((Daten shl 1) shr 24) - 127;
  Mant := (Daten shl 9) shr 9;
 
  Mant_r := 0;
  Count := 1;
  while Count <= 23 do
  begin
    //nachsehen, ob Bit an Stelle Count 0 oder 1
    if ((Mant and (1 shl (23 - Count))) > 0) then
      Mant_r := Mant_r + Power(2 , -Count);
    Count := Count + 1;
  end;
  //eine echte Null erzeugen !!!
  if ((Exp = -127) and (Mant = 0)) then
    Mant_r := 0
  else
    Mant_r := 1 + Mant_r;
  D_Real := Mant_r * Power(2, Exp);
  //Vorzeichen testen und einrechnen
  if ((Daten shr 31) > 0) then
    S7_Float := -D_Real
  else
    S7_Float := D_Real;
end;



Dank dir! Mir fehlt aber irgendwie noch irgendwas... Oh mann :rolleyes:
Ok so viel hab ich bisher.
1. ich muß mir 4 Bytes zusammen addieren .
2. dieses ergebnis kann ich dann dazu hernehmen um mir meinen Wert anzuzeigen.

Nur fehlt mir jetzt der punkt wie ich z.b. die 4 Byte ab adresse 40 z.b. addieren kann.

:confused:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Um 4 Byte eine 32Bit-Variable zu kopieren müßte doch auch folgendes gehen:

Code:
Daten32: Integer; //32-Bit-Var
Bytedat1, Bytedat2, Bytedat3, Bytedat4: Byte; //deine 4 Byte aus den Rohdaten
 
Daten32 := Bytedat4;
Daten32 := Daten32 SHL 8;
Daten32 := Daten32 + Bytedat3;
Daten32 := Daten32 SHL 8;
Daten32 := Daten32 + Bytedat2;
Daten32 := Daten32 SHL 8;
Daten32 := Daten32 + Bytedat1;
 
Danke euch beiden.

Werds heute mal im laufe des Tages versuchen. Weiß noch nicht ob ich es hin bekomme. Vom logischen ist es klar.
Mir fehlt derzeit noch die Stelle an der ich sage ab Adresse 20, 4Byte Addieren....

Aber schlag mich da einfach mal ein wenig mit euren beispielen herum. Danke mal.!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

In VB-Code kannst du es so schreiben:

Code:
Private Function Real2Single(byte1 As Byte, byte2 As Byte, byte3 As Byte, byte4 As Byte) As Single

Dim i As Integer
Dim x As Integer
Dim blnBit_LR(31) As Boolean
Dim blnVorzeichen As Boolean
Dim intExponent As Integer
Dim dblMantisse As Double
Const Bias = 127

'REAL-Datentyp zu Single konvertieren
'Einzelne Bits auslesen
x = 0
For i = 0 To 7
    If (byte4 And 2 ^ x) = (2 ^ x) Then
        blnBit_LR(i) = True
    Else
        blnBit_LR(i) = False
    End If
    x = x + 1
Next i
x = 0
For i = 8 To 15
    If (byte3 And 2 ^ x) = (2 ^ x) Then
        blnBit_LR(i) = True
    Else
        blnBit_LR(i) = False
    End If
    x = x + 1
Next i
x = 0
For i = 16 To 23
    If (byte2 And 2 ^ x) = (2 ^ x) Then
        blnBit_LR(i) = True
    Else
        blnBit_LR(i) = False
    End If
    x = x + 1
Next i
x = 0
For i = 24 To 31
    If (byte1 And 2 ^ x) = (2 ^ x) Then
        blnBit_LR(i) = True
    Else
        blnBit_LR(i) = False
    End If
    x = x + 1
Next i
'Vorzeichen bestimmen
blnVorzeichen = blnBit_LR(31)
'Exponenten bestimmen
x = 0
intExponent = 0
For i = 23 To 30
    If blnBit_LR(i) Then intExponent = intExponent + 2 ^ x
    x = x + 1
Next i
'Mantisse bestimmen
x = -1
dblMantisse = 0
For i = 22 To 0 Step -1
    If blnBit_LR(i) Then dblMantisse = dblMantisse + 2 ^ x
    x = x - 1
Next i
'Single-Wert berechnen
If intExponent = 0 And dblMantisse = 0 Then
    Real2Single = 0
Else
    Real2Single = (1 + dblMantisse) * 2 ^ (intExponent - Bias)
    'Vorzeichen verrechnen
    If blnVorzeichen Then Real2Single = Real2Single * (-1)
End If

End Function

Gruß
Donnerkeil
 
Zurück
Oben