Brauche Hilfe um etwas zu berechnen, Stromzähler

Ich komme einfach nicht auf die richtige Formel dafür, bzw, verstehe ich nicht genau was und wie ich das in php berechnen soll:

Aufgabe:

Der Stromzähler liefert dir Antwort:

HEX : 43 70 80 00

Binär: 0100 0011 0111 0000 1000 0000 0000 0000

From this you can determine the following information.
·The sign bit is 0, indicating a positive number.
·The exponent value is 10000110 binary or 134 decimal. Subtracting 127 from 134 leaves 7, which is the actual exponent.
·The mantissa appears as the binary number 11100001000000000000000
There is an implied binary point at the left of the mantissa that is always preceded by a 1. This bit is not stored in the hexadecimal representation of the floating-point number. Adding 1 and the binary point to the beginning of the mantissa gives the following: 1.11100001000000000000000
Now, we adjust the mantissa for the exponent. A negative exponent moves the binary point to the left. A positive exponent moves the binary point to the right. Because the exponent is 7, the mantissa is adjusted as follows:
11110000.1000000000000000
Finally, we have a binary floating-point number. Binary bits that are to the left of the binary point represent
the power of two corresponding to their position. For example, 11110000 represents (1 x 27) + (1 x 26) + (1x 25) + (1 x 24) + (0 x 23)+ (0 x 22) + (0 x 21)+ (0 x 20) = 240.
Binary bits that are to the right of the binary point also represent a power of 2 corresponding to their position. As the digits are to the right of the binary point the powers are negative. For example: .100 represents (1 x 2-1) + (0 x 2-2)+ (0 x 2-3) + … which equals 0.5.
Adding these two numbers together and making reference to the sign bit produces the number +240.5.

Hier die komplette Doku : https://dl.dropboxusercontent.com/u/2476467/SDM630M%20protocol%20V2013-1.pdf

und hier mein Script:

<?
$RegVar = 59976 /*[Stromzähler Gesamt\Stromzähler Gesamt]*/   ;
//**********************Funktion für String in Hex umzuwandeln !!!!*************
function string2hex ( $string ) {
  $hex = NULL;
  for ( $ix=0; $ix < strlen($string); $ix=$ix+1 ) {
    $char =  substr( $string, $ix, 1 );
    $ord = ord ( $char );
    if ( $ord < 16 ) {
      $hex .= '0'.dechex( $ord );
    }
    else {
      $hex .= dechex( $ord );
    }

    // add line break or space
    if ( $ix && ($ix % 16) == 15 ) {
      $hex .= "
";
    }
    else {
      $hex .= " ";
    }
  }

  // strip trailing space or linebreak
  return substr( $hex, 0, -1 );
}

function hex2string( $hex ) {
  $string = NULL;

  // strip linebreaks and spaces
  $hex = str_replace( array("
","\r"," "), "", $hex );

  for ( $ix=0; $ix < strlen($hex); $ix=$ix+2 ) {
    $ord = hexdec( substr( $hex, $ix, 2 ) );
    $string .= chr( $ord );
  }

  return $string;
}

// Umrechnung
$data = RegVar_GetBuffer($RegVar);
$value = "01 04 04 43 70 80 00 00 00";
//$value = String2Hex($data);
$value = explode(' ', $value);

$wert3=$value[3];
$wert4=$value[4];
$wert5=$value[5];
$wert6=$value[6];

//print "$wert3
$wert4
$wert5
$wert6
";

$wert3=base_convert($wert3,16,10);
$wert4=base_convert($wert4,16,2);
$wert5=base_convert($wert5,16,2);
$wert6=base_convert($wert6,16,2);

$wert3="127-$wert3"; // Exponent

//print "$wert5
";
//print "$wert3
$wert4
$wert5
$wert6
";


$wert41="1$wert4";
$wert51="$wert5";

//print "
$wert41
";
$wert6="$wert41$wert51$wert6";
//print $wert6;
$wert7=substr ($wert6, 0, 8);
$wert8=substr ($wert6, 8, 3);
$wert9=substr ($wert6, 16, 20);
//print "$wert7
$wert8
$wert9
";

$test=bindec($wert6);

$ergebins1=bindec($wert7);
$ergebins2=bindec($wert8);
$ergebins3=bindec($wert9);
$end="$ergebins1,$ergebins2,$ergebins3";

//print $test;
print $end;
//setvalue(48720 /*[Stromzähler Gesamt\Stromzähler Gesamt\Buffer]*/ ,$end);



//$buffer=getvalue(48720 /*[Stromzähler Gesamt\Stromzähler Gesamt\Buffer]*/ );
//setvalue($al1,$buffer);
RegVar_SetBuffer($RegVar, ""); //Variable löschen
?>

Morgen,

Code unterstützt nur den positiven Exponent, aber denke das sollte kein Problem sein das anzupassen:


$value = "01 04 04 43 70 80 00 00 00";
$value = explode(' ', $value);

$wert3=hexdec($value[3]);
$wert4=hexdec($value[4]);
$wert5=hexdec($value[5]);
$wert6=hexdec($value[6]);

$sign = $wert3 >> 7;
$exponent = (($wert3 & 0x7F) << 1) + (($wert4 & 0x80) >> 7) - 127;
$mantisse = (($wert4 | 0x80) << 16) + ($wert5 << 8) + $wert6;
$zaehler= 0;
if ($sign == 0) {
	# exponent is positive
	$zaehler= $mantisse / (0x7FFFFF >> $exponent);
}
else
{
        # exponent is negative
	echo "Only supports positive exponents";
}
echo $zaehler;

VG
Michael

Hi ich könnte dich knutschen !

Ich danke dir so sehr !!! Jetzt muss ich nur rausbekommen, wie das Script erweitere, das es auch mit negativen exponents klar kommt :wink:

Denke du musst das Teilen (/) durch Mal (*) ersetzen:

$zaehler= $mantisse * (0x7FFFFF >> $exponent);

Könnte aber sein, dass du da noch am Offset verschieben musst (also am 0x7FFFFF rumspielen). Kann ich aber nicht probiern, weil ich dafür kein Beispiel hab :wink:

VG
Michael

Hi also negative Zahlen habe ich eigentlich nicht…

Aber wenn zum Beispiel der Zähler 01 04 04 40 C6 C0 83 1F D8 ausspuckt, das sind ca. 0,811A dann sagt dein Script:

Warning: Division by zero in C:\IP-Symcon\scripts\25518.ips.php on line 84

Line 84:

$zaehler= $mantisse / (0x7FFFFF >> $exponent);

Auch wenn ich / gegen * austausche…

Hm wie bekommt das hin ?

1000 x Danke für deine Hilfe !!!

Sry … war in der Mittagspause, da hat wohl das Gehirn etwas wenig Sauerstoff bekommen.

Die Zeile

$zaehler= $mantisse / (0x7FFFFF >> $exponent); 

Macht im Endeffekt folgendes:


$teiler = 0x7FFFFF / pow(2, $exponent);
$zaehler = $mantisse / $teiler;

Wenns jetzt auch für negative Exponenten funktionieren soll, dann einfach:


$teiler = 0x7FFFFF * pow(2, $exponent);
$zaehler = $mantisse / $teiler;

Ich hoffe das funktioniert.

VG
Michael

Hi super es es klappt !!!

Ich habe das:

$zaehler= $mantisse / (0x7FFFFF >> $exponent);  

gegen das ausgetauscht :

$teiler = 0x7FFFFF / pow(2, $exponent); 
$zaehler = $mantisse / $teiler; 

Seit klappt es auch mit den 0,xxx Werten :wink:

10000000000x Danke :wink: