Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 14 von 14

Thema: Phoenix Modbusserver

  1. #11
    Registriert seit
    16.11.2013
    Beiträge
    6
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Mobi,

    vielen Dank für Dein Beispiel. Die Umwandlung hat super funktioniert.
    Die Umwandlung von IEEE754 zu Real zurück konnte ich natürlich nicht verwenden.
    Dazu mußte erst mal ein PHP Script geschrieben werden. Nach einigen Unklarheiten mit der Reihenfolge der bits, funktioniert es nun.
    Gerne veröffentliche ich das hier auch, wenn klar ist, dass es einwandfrei läuft.

    LG
    Upuaut

  2. #12
    Registriert seit
    16.11.2013
    Beiträge
    6
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hallo nochmal,

    hier noch die passende Umwandlung von IEEE754 zurück in Float für PHP.
    Bisher funktionert es zuverlässig, war aber letztendlich umsonst, da ich nun den Wert des Counterbausteines durch 1 teile, weil die Gleitkommazahl aus dem PCWORX Projekt zu ungenau ist. In PHP teile ich dann erst wieder... Siehe hier:

    Gleitkommaberechnung ILC130 mit PCWORX

    Leider ist mir bis heute nicht klar, warum es Counterbausteine gibt (sowohl in der Solar Libary alsauch in der Building Automation Libary), die eigentlich nicht genau mit einem aufaddieren eines 0,002er Wertes klarkommen, aber die Anzahl der Impulse pro Einheit als Divisor in Float angegeben haben möchte. Man sollte diese Bausteine nur für ganze Zahlen schreiben.
    Das ist ja auch nicht nur bei Phoenix so...
    Das Fatale daran ist; Es fällt einem erst nach einer gewissen Zeit auf, weil der Counter am Anfang (kurz nach der Installation eines neuen Zählers) noch genau ist, später dann aber nur noch Blödsinn herauskommt.

    Code:
    <?
    /********************************************************************************************/
    /* Umrechnung von IEEE754 nach FLOAT siehe Wikipedia http://de.wikipedia.org/wiki/IEEE_754     */
    /*                                                                                             */
    /* Beispiel von Wikipedia mit IEE754 01000001100100110011001100110011 welche der Float Zahl */
    /* 18,4 entpricht gerundet.                                                                    */
    /* IEEE754 Rechner : http://www.h-schmidt.net/FloatConverter/IEEE754.html                     */
    /* BIN -> DEC  DEC -> BIN http://acc6.its.brooklyn.cuny.edu/~gurwitz/core5/nav2tool.html     */
    /*                                                                                             */                                                    */
    /********************************************************************************************/
    
    // Beginn Beispiel
    
    //$input = "01000001100100110011001100110011"; // IEEE754 Zahl = 18,4
    // 17972 -> 100011000110100
    // 7096 ->  1101110111000
    
    //echo "Erster Wert : " . bindec("100011000110100") . "<br>";    // Bit 0-15  Dezimal Zahl = 16787
    //echo "Zweiter Wert: " . bindec("001101110111000") . "<br>";    // Bit 16-31 Dezimal Zahl = 13107
    //ieee754ToFloat(17972 /*[Objekt #17972 existiert nicht]*/,7096) . "<br>";
    
    // Ende Beispiel
    
    SetValue(21829 /*[Steuerung Haus\Energie\Strom\Strom\Stromzähler]*/,ieee754ToFloat(GetValue(37365 /*[Steuerung Haus\Modbus\ModBus Adresse 1\Value]*/),GetValue(11651 /*[Steuerung Haus\Modbus\ModBus Adresse 0\Value]*/))/500);
    SetValue(16749 /*[Steuerung Haus\Energie\Gas\Gas\Gaszähler]*/,ieee754ToFloat(GetValue(55831 /*[Steuerung Haus\Modbus\ModBus Adresse 5\Value]*/),GetValue(38100 /*[Steuerung Haus\Modbus\ModBus Adresse 4\Gaszähler]*/))/100);
    SetValue(47637 /*[Steuerung Haus\Energie\Wasser\Wasser\Wasserzähler]*/,ieee754ToFloat(GetValue(30433 /*[Steuerung Haus\Modbus\ModBus Adresse 9\Value]*/),GetValue(54533 /*[Steuerung Haus\Modbus\ModBus Adresse 8\Wasserzähler]*/))/1000);
    
    
    
    function ieee754ToFloat($Wert1,$Wert2) {
    
    //echo "Wert 1 : " . $Wert1 . " Wert 2 : " . $Wert2 . "\n";
    
        $_32BIT_CONSTANT_BIAS_B = 127;
    
        // Workaround START
        // PHP lässt bei der Umwandlung von dec nach bin führende Nullen weg.
        // Da aber alle 32 Bits für das korrekte funktionieren des Algorithmus IEEE754 nach DEC wichtig sind
        // werden durch diese 2 Schleifen die fehlenden Nullen wieder hinzugefügt.
    
        $Wert1 = decbin($Wert1);
    
        if(strlen($Wert1) < 16) {
            while(strlen($Wert1) < 16) {
                $Wert1 = "0" . $Wert1;
            }
        }
    
        $BIT_0_15 = $Wert1;
    
        $Wert2 = decbin($Wert2);
    
        if(strlen($Wert2) < 16) {
            while(strlen($Wert2) < 16) {
                $Wert2 = "0" . $Wert2;
            }
        }
    
        $BIT_16_31 = $Wert2;
    
        // Workaround ENDE
    
       //echo "Wert 1 : " .     $BIT_0_15 . " Wert 2 : " .     $BIT_16_31 . "\n";
    
        $input =  $BIT_0_15 . $BIT_16_31;
        $mantisse = "1" . substr($BIT_0_15 . $BIT_16_31,9,31);
        //echo "Mantisse : " . $mantisse . "\n";
        $vorzeichen = substr($input,0,1);
        $bias = substr($input,1,8);
        $exponent = bindec($bias) - $_32BIT_CONSTANT_BIAS_B;
        $vorkommaStellen =  substr($mantisse,0,$exponent + 1);
        $nachKommastellen = "0" . substr($mantisse,$exponent + 1,strlen($mantisse));
    
        // Durchlaufe schrittweise den String $nachKommastellen im BINÄR-FORMAT
        // Hier werden Bitweise die 2er Potenzen addiert
        $sum = 0;
        for ($i = 0;$i < strlen($nachKommastellen);$i++) {
            // Lese Bit für Bit aus dem String $nachKommastellen
            $BIT = substr($nachKommastellen,$i,1);
            // Rechne bei jedem Durchlauf das aktuelle Bit mal 2 hoch -i  // Siehe Wikipedia
            // und rechne den Wert zur aktuellen Summe dazu
            $sum = $sum + $BIT * pow(2,-$i);
        }
        $floatWert = bindec($vorkommaStellen) . "," . substr($sum,2,strlen($sum));
        $vorzeichen = substr($BIT_0_15,0,1);
    
        if($vorzeichen == 1) {
            $floatWert = (-1) * $floatWert;
        }
    
        //Debugausgabe START
        /*
        echo "BIT 0 - 15: " . $BIT_0_15 . "\n";
        echo "BIT 16 - 31: " .$BIT_16_31 . "\n";
        echo "Vorzeichen: " . $vorzeichen . "\n";
        echo "Bias: BIN: " . $bias . " DEC: " . bindec($bias) . "\n";
        echo "Exponent:" . $exponent . "\n";
        echo "Vorkommastellen: BIN: " . $vorkommaStellen . " DEC: " . bindec($vorkommaStellen) . "\n";
        echo "Nachkommastellen: BIN: " . $nachKommastellen . " DEC: " . bindec($nachKommastellen) . "\n";
        echo "Nachkommastellen : " . $sum . "\n";
        echo "Ergebnis: " . $floatWert;
        */
        //Debugausgabe ENDE
    
        return $floatWert;
    
    }
    ?>
    Vielleicht kann ja jemand etwas damit anfangen.

    Eine Frage hätte ich noch dazu; Wenn ich nun einen DWORD Wert über Modbus senden will, zerlege ich diesen ja auch wieder in zwei mal WORD, oder (siehe Beispiel)?
    Danach bekomme ich aber keinen sinnvollen Werte wieder zusammengesetzt. Wie sende ich aber sonst eine 32bit große ganze Zahl über Modbus in PCWORX? Im Moment mache ich es über den IEEE754 Baustein von Mobi als umgewandelte Floatzahl (z.B. 7233842,0) und dann über mein Script.

    DWORD2.jpg

    LG
    Upuaut

  3. #13
    Registriert seit
    25.06.2008
    Ort
    Blomberg/Lippe
    Beiträge
    1.293
    Danke
    51
    Erhielt 130 Danke für 124 Beiträge

    Standard

    Vielleicht kann das die ILC 190 ETH 2TX besser. Die ist extra ausgelegt auf Gleitkomma-Arithmetik.
    Aber das ist mir vor Jahren auch schon aufgefallen, das liegt halt daran wie die Zahl gespeichert wird.
    Gruß
    Mobi


    „Das Einfache kompliziert zu machen ist alltäglich. Das Komplizierte einfach zu machen –
    das ist Kreativität“ (Charles Mingus).

  4. #14
    Registriert seit
    24.07.2013
    Beiträge
    9
    Danke
    2
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Vielen Dank für die Funktionsbausteine zur IEEE754-Umwandlung Mobi.

    Ich bin gerade auf ein anderes Problem gestoßen:
    Und zwar möchte ich Messwerte per Modbus bereitstellen, das ein LabView Proramm einliest. Dieses Programm ließt gewissen Werte als "double" ( 64-bit) ein, sprich 4 Modbus Register (4 Word).

    Ist es möglich ein LREAL in PC-Worx irgendwie in 4 Words zu zerlegen, damit ich sie bereitstellen kann?

    Ich verwende eine ILC131 ETH.

    Vielen Dank

Ähnliche Themen

  1. Phoenix ILC 170 ETH + IL ETH BK + IB IL AI 4/U
    Von valik.vak im Forum PHOENIX CONTACT
    Antworten: 24
    Letzter Beitrag: 17.06.2011, 11:22
  2. Profibusslave an Phoenix-SPS
    Von Ritschi im Forum PHOENIX CONTACT
    Antworten: 6
    Letzter Beitrag: 05.04.2011, 10:50
  3. Phoenix Bluetooth PC <-> CPU
    Von fr4nk im Forum PHOENIX CONTACT
    Antworten: 9
    Letzter Beitrag: 28.07.2008, 10:57
  4. Phoenix IBS RT 24 DI 32-T
    Von ralfm im Forum PHOENIX CONTACT
    Antworten: 0
    Letzter Beitrag: 26.02.2005, 11:38
  5. PC-Worx von Phoenix
    Von schlumpf_schlaubi im Forum PHOENIX CONTACT
    Antworten: 2
    Letzter Beitrag: 13.10.2004, 15:18

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •