Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. 16 bit signed Float einlesen über den Node-red Modbus

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    16 bit signed Float einlesen über den Node-red Modbus

    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      atelmblcd last edited by

      teste mal diesen Flow dieser müsste funktionieren laut

      https://nodejs.org/api/buffer.html#buff … t_noassert

      buf.readFloatBE(offset[, noAssert])

      buf.readFloatLE(offset[, noAssert])

      Added in: v0.11.15

      offset <integer>Number of bytes to skip before starting to read. Must satisfy: 0 <= offset <= buf.length - 4.

      noAssert <boolean>Skip offset validation? Default: false

      Returns: <number>Reads a 32-bit float from buf at the specified offset with specified endian format (readFloatBE() returns big endian, readFloatLE() returns little endian).

      Setting noAssert to true allows offset to be beyond the end of buf, but the resulting behavior is undefined.

      (0,1,2,3) liest die Register aus dem Buffer jeweils 8 bit.

      [{"id":"6f92b84.0ef3ac8","type":"modbus-read","z":"7d4de8d.1542118","name":"X320_Read","topic":"","showStatusActivities":false,"showErrors":false,"unitid":"","dataType":"HoldingRegister","adr":"272","quantity":"2","rate":"1","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"741a094c.1340b8","useIOFile":false,"ioFile":"","useIOForPayload":false,"x":330,"y":260,"wires":[[],["3de8b140.13ce2e","cca0874c.f3d76"]]},{"id":"3de8b140.13ce2e","type":"function","z":"7d4de8d.1542118","name":" 32bit","func":"msg.payload=msg.payload.buffer.readFloatLE(0,1,2,3);\nreturn msg;\n","outputs":1,"noerr":0,"x":510,"y":400,"wires":[["f6427835.8241b"]]},{"id":"f6427835.8241b","type":"debug","z":"7d4de8d.1542118","name":"","active":true,"console":"false","complete":"false","x":690,"y":540,"wires":[]},{"id":"cca0874c.f3d76","type":"modbus-response","z":"7d4de8d.1542118","name":"","registerShowMax":20,"x":600,"y":260,"wires":[]},{"id":"741a094c.1340b8","type":"modbus-client","z":"","name":"X320","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"tcpHost":"192.168.0.48","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":"1","commandDelay":"1","clientTimeout":"1000","reconnectTimeout":"2000"}]</number></boolean></integer>

      1 Reply Last reply Reply Quote 0
      • J
        JXA last edited by

        Hallo Jean,

        vielen Dank für deinen Flow,

        Über den Modbus Response werden die Daten jetzt angezeigt.

        Die Ausgabe ist jedoch noch nicht korrekt.

        Ausgegeben wird aktuell : -1.7142884334298003e-13

        Gruß

        Bastian

        1 Reply Last reply Reply Quote 0
        • J
          JXA last edited by

          Ich denke das ich den Grund für die fehlerhafte Anzeige gefunden habe.

          Die Funktion nutzt 4 x 8 bit (0,1,2,3)

          "32-bit sensor values are read from 16-bit register pairs. Consequently, senors addresses and registers

          must be even numbers"

          Es werden 2 Register ausgelesen die jedoch je 16 bit haben .

          Gibt es eine Möglichkeit die Funktion anzupassen?

          Gruß

          Bastian

          1 Reply Last reply Reply Quote 0
          • A
            atelmblcd last edited by

            @JXA:

            Ich denke das ich den Grund für die fehlerhafte Anzeige gefunden habe.

            Die Funktion nutzt 4 x 8 bit (0,1,2,3)

            "32-bit sensor values are read from 16-bit register pairs. Consequently, senors addresses and registers

            must be even numbers"

            Es werden 2 Register ausgelesen die jedoch je 16 bit haben . `

            genau wie du richtig erkannt hast

            wenn du die ersten 16 Bit einlesen willst dann (0,1)

            für die zweiten 16 bit (2,3)

            Es gibt noch interessante Gratis Werkzeuge

            ist schon 10 Jahre alt ob es mit win 10 läuft weis ich nicht

            http://store.chipkin.com/products/tools … us-scanner

            oder hier ein Modbus Simulator

            https://sourceforge.net/projects/modrssim

            in diesem Forum wird genau dein Problem besprochen

            https://groups.google.com/forum/#!topic ... t_Y7egwuio

            Csongor Varga hat die Antwort gepostet und einen Link reingeschrieben wo man einen Beispiel Flow laden kann.

            https://flows.nodered.org/flow/75a4715f ... 92abc493e4

            unten auf dem Forum hat Michael Hogan folgendes gepostet.

            I have done a fair amount of this for interfacing to some brushless motor control stuff.

            I initially used the Typed Array classes for my stuff, but then reverted to using the slightly older Buffer functions like buffer.readFloatLE() and so forth. Here's one reference:

            https://millermedeiros.github.io/mdoc/e ... ffers.html

            The reason that I did that is that we are using a Raspberry Pi as an edge gateway. While you can upgrade the Pi to use more recent versions of node.js and node-red, I found that it was dicey enough that it was better to use the versions that get installed with default Raspbian. Those versions do not support the typed array classes .. but they do support the various buffer.read* methods.

            At any rate, figured I'd put that out there for whatever it might be worth to folks converting raw bytes to typed values.

            Wenn du alte Software Versionen auf dem Raspi hast und die nicht geupdatet sind kann es sein dass die Array Methode nicht funzt.

            1 Reply Last reply Reply Quote 0
            • J
              JXA last edited by

              Guten Abend Jean,

              vielen Dank für die umfangreichen Informationen!

              Du "steckst" ja richtig in der Materie! WoW!

              Ich werde die Programme zeitnah testen, zuvor muss ich mir jedoch erst ein Win Rechner aufsetzen.

              Node Red läuft bei mir auf einem Debian Rechner, und (noch) nicht auf einem Raspi.

              15 Feb 19:47:25 - [info] Node-RED version: v0.17.5

              15 Feb 19:47:25 - [info] Node.js version: v9.5.0

              15 Feb 19:47:25 - [info] Linux 4.9.0-5-amd64 x64 LE

              15 Feb 19:47:27 - [info] Loading palette nodes

              15 Feb 19:47:37 - [info] Dashboard version 2.8.0 started at /ui

              Mit dem geposteten Sketch komme ich aktuell nicht wirklich weiter….

              Habe nochmal die beiden Register[272] für die Temperatur ausgelesen und über Modbus Response angezeigt.

              Ausgabe: 32771,16806 diese 32bit float Zahl sollte einer Temperatur von 20,8xx°C entsprechen

              Gruß

              Bastian

              1 Reply Last reply Reply Quote 0
              • A
                atelmblcd last edited by

                es müsste richtig eingelesen werden, nur muss der float von Hex oder bin nach dezimal umgerechnet werden.

                was steht in dem Bufffer Modbusresponse, dies müsste im Hex Format vorlirgen

                Hier ist ein Beispielcode zu finden

                https://gist.github.com/faisalman/4213592

                da muss aber ein Java Spezialist ran da ich die Hardware nicht habe kann ich nicht wirklich weiterhelfen aber ich bleibe dran.

                ich mache das immer mit try and error bis ich die Lösung habe.

                MfG

                Jean

                1 Reply Last reply Reply Quote 0
                • G
                  Garf last edited by

                  @JXA:

                  Mit dem geposteten Sketch komme ich aktuell nicht wirklich weiter….

                  Habe nochmal die beiden Register[272] für die Temperatur ausgelesen und über Modbus Response angezeigt.

                  Ausgabe: 32771,16806 diese 32bit float Zahl sollte einer Temperatur von 20,8xx°C entsprechen `
                  Wenn man die beiden Werte aus den Modbusregistern richtig einliest und als Dezimalzahl umrechnet, dann kommen dabei genau 20.831 raus.

                  Ergebnis für die Reihenfolge 32771, 16806: -0.531
                  3639_screen1.jpg

                  Ergebnis für die Reihenfolge 16806, 32771: 20.831
                  3639_screen2.jpg

                  Garf

                  1 Reply Last reply Reply Quote 0
                  • J
                    JXA last edited by

                    Hallo "Graf" vielen Dank für deine Hilfe!

                    Das auslesen der Register über node red funktioniert also "sauber",

                    das Problem liegt also in der "Funktion" um die Werte Dezimal anzeigen zu können.

                    Könntest Du die Funktion im Sample Code anpassen um die Sache besser zu verstehen?

                    Nochmals vielen Dank an "Starter" dafür!!

                    [{"id":"6f92b84.0ef3ac8","type":"modbus-read","z":"7d4de8d.1542118","name":"X320_Read","topic":"","showStatusActivities":false,"showErrors":false,"unitid":"","dataType":"HoldingRegister","adr":"272","quantity":"2","rate":"1","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"741a094c.1340b8","useIOFile":false,"ioFile":"","useIOForPayload":false,"x":330,"y":260,"wires":[[],["3de8b140.13ce2e","cca0874c.f3d76"]]},{"id":"3de8b140.13ce2e","type":"function","z":"7d4de8d.1542118","name":" 32bit","func":"msg.payload=msg.payload.buffer.readFloatLE(0,1,2,3);\nreturn msg;\n","outputs":1,"noerr":0,"x":510,"y":400,"wires":[["f6427835.8241b"]]},{"id":"f6427835.8241b","type":"debug","z":"7d4de8d.1542118","name":"","active":true,"console":"false","complete":"false","x":690,"y":540,"wires":[]},{"id":"cca0874c.f3d76","type":"modbus-response","z":"7d4de8d.1542118","name":"","registerShowMax":20,"x":600,"y":260,"wires":[]},{"id":"741a094c.1340b8","type":"modbus-client","z":"","name":"X320","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"tcpHost":"192.168.0.48","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":"1","commandDelay":"1","clientTimeout":"1000","reconnectTimeout":"2000"}]

                    1 Reply Last reply Reply Quote 0
                    • G
                      Garf last edited by

                      @JXA:

                      Das auslesen der Register über node red funktioniert also "sauber",

                      das Problem liegt also in der "Funktion" um die Werte Dezimal anzeigen zu können.

                      Könntest Du die Funktion im Sample Code anpassen um die Sache besser zu verstehen?

                      Nochmals vielen Dank an "Starter" dafür!! `

                      Ich kopiere mir keine Flows mit IP-Adressen die es in meinem Netzwerk nicht gibt in meine laufenden Flows. Dies führt nur zu Problemen. Bitte poste doch einfach mal ein paar Screenshots vom Inhalt des Function Node und die Bufferwerte.

                      Soviel ich aus dem Flow herauslesen kann, liest Du zwei Modbusregister in vier Buffer ein.

                      dataType":"HoldingRegister","adr":"272","quantity":"2"

                      "name":" 32bit","func":"msg.payload=msg.payload.buffer.readFloatLE(0,1,2,3);\nreturn msg

                      Was steht denn in den Buffern 2 und 3?

                      Ich kann es zwar nicht testen, aber wenn in den Buffern 0 und 1 die Werte 32771, 16806 stehen, dann müsttest Du nur die Reihenfolge des Einlesens ändern:

                      msg.payload.buffer.readFloatLE(1,0)

                      Dann sollte der gewünschte Wert richtig angezeigt werden. Ich kann dies leider nicht im wirklichen Wirkbetrieb testen, es sollte aber eigentlich so funktionieren.

                      Garf

                      1 Reply Last reply Reply Quote 0
                      • J
                        JXA last edited by

                        Hallo "Graf"

                        vielen Dank für deine Antwort!

                        Zur bisherigen Funktion:

                        ""name":" 32bit","func":"msg.payload=msg.payload.buffer.readFloatLE(0,1,2,3);\nreturn msg"

                        Der Gedanke die 16 bit je Register a 2x8Bit einzulesen…

                        Also Register 272=(0,1) 273=( 2,3)

                        Dank deiner Rechnung ist nun klar das dies nicht erforderlich ist!

                        Ich habe die Funktion nun geändert:

                        msg.payload.buffer.readFloatLE(1,0)

                        Was zum exakt gleichen Ergebnis führt!

                        Die Werte der Register werden im Screenshot im Modbus Response angezeigt.

                        Ist die Funktion korrekt von mir übernommen? Habe ich einen Fehler gemacht?

                        JXA
                        5860_flow_1.png
                        5860_funktion.png
                        5860_funktion_neu.png

                        1 Reply Last reply Reply Quote 0
                        • G
                          Garf last edited by

                          Hi JXA,

                          da muss ich meine Aussage von vorhin wohl doch etwas revidieren. Deine Einstellungen im Function-Node waren absolut richtig. Ich hatte einfach vergessen, dass die Javafunktion ja mit den Buffer 8-bit Werten rechnet. Das heißt das Modbusregister 1 und 2 (je 16bit) werden in je zwei Hexzahlen zerlegt und dann als Dezimalzahl umgerechnet.

                          Ich habe eben mal verucht die 8-bit Werte von der Reihenfolge 0,1,2,3 in 3,2,0,1 zu ändern. Dies funktioniert aber leider nicht.

                          Somit haben wir jetzt zwar eine schöne Javafunktion die uns die Rechenarbeit abnimmt, aber keine Möglichkeit zur Verfügung stellt die Modbusregister von hinten nach vorne einzulesen und umzurechnen. Da müssen wir uns wohl noch etwas einfallen lassen. Ich habe vor einigen Wochen selbst ein Funktion-Node programmiert, welches die Einträge in den Modbusregistern einliest und wieder als Dezimalzahl ausgibt. Ich lese dafür allerdings die Datawerte in msg.payload als Arraywerte ein und kann da auch frei bestimmen in welcher Reihenfolge die Werte eingelesen und zurückgerechnet werden. Damit war es mir dann auch möglich deine geposteten Werte in beiden Varianten einmal zu rechnen.

                          Garf

                          1 Reply Last reply Reply Quote 0
                          • J
                            JXA last edited by

                            Hallo Graf,

                            super, dann haben wir jetzt das Grundproblem geklärt und einen soliden Status!

                            Der aktuelle Sketch sollte ja nur zum testen dienen.

                            Ich möchte natürlich über Modbus mehrere Register auslesen und dann anzeigen.

                            Somit ist das speichern der Modbuswerte in einem Array unausweichlich.

                            Kannst du mir eine Sample code senden mit deinen selbst programmierten Funktions -Node?

                            Modbus->Array->Funktion->Ausgabe

                            Danke!

                            JXA

                            1 Reply Last reply Reply Quote 0
                            • G
                              Garf last edited by

                              @JXA:

                              Kannst du mir eine Sample code senden mit deinen selbst programmierten Funktions -Node? `
                              Wenn wir keine andere Lösung finden, dann schicke ich dir das selbst programmierte Funktion-Node zu. Im Moment befindet es sich aber noch in einer Rohfassunge und enthält viele Dinge die man in der praktischen Umrechnung nicht mehr braucht. Um Programmierfehler frühzeitig erkennen zu können, musste ich diese allerdings einbauen. Ich habe an dem Node nicht mehr weitergearbeitet, weil es für die Umrechnung ja bereits diese tolle Javascriptfunktion gibt. Wir müssen mal schauen, ob es da nicht auch schon eine Lösung für dein Problem gibt. Ich lese mich da gleich noch einmal ein.

                              Garf

                              1 Reply Last reply Reply Quote 0
                              • G
                                Garf last edited by

                                Ich glaube da schon etwas gefunden zu haben.

                                https://github.com/biancode/node-red-co … endianness

                                Mit der swap Funktion werden tatsächlich die Bufferwerte getauscht.

                                Lt. Response stehen als Werte im Buffer 3f 99 99 9a und nach dem swap 99 3f 9a 99. Mir ist nur noch nicht klar was buffer.swap16() macht und ob es die richtige Funktion für dein Problem ist. Da muss man wohl noch mal weiter nachlesen.

                                Ich bin mal optimistisch, damit könnten wir es irgendwie hinbekommen. Wenn Du magst, kannst Du ja schon mal ein Versuch starten.

                                1 Reply Last reply Reply Quote 0
                                • J
                                  JXA last edited by

                                  Hallo Graf,

                                  danke für die Info.

                                  Ich habe den "Buffer Swap" getestet.

                                  Er führt aktuell nicht zum gewünschten Ergebnis…

                                  Habe ich etwas vergessen??
                                  5860_swap.png

                                  1 Reply Last reply Reply Quote 0
                                  • G
                                    Garf last edited by

                                    Bei mir scheint es zu funktionieren. Du solltest nur das Debug-Node eingeschaltet lassen, welches uns die Meldungen zu dem Function swap-Node zeigt.

                                    Bitte den Inhalt des swap-Nodes posten.

                                    Ich habe folgende Eintragungen vorgenommen:

                                    msg.payload.buffer.swap16();
                                    
                                    msg.payload = msg.payload.buffer.readFloatBE(0,1,2,3);
                                    
                                    return msg;
                                    
                                    1 Reply Last reply Reply Quote 0
                                    • J
                                      JXA last edited by

                                      Habe die Änderung vorgenommen…
                                      5860_swap2.png
                                      5860_swap_function.png

                                      1 Reply Last reply Reply Quote 0
                                      • G
                                        Garf last edited by

                                        Erstaunlich, dass es funktioniert, Normalerweise hättest Du das BE durch LE ersetzen müssen. Bisher jedenfalls hast Du immer Littel Endian ausgelesen.

                                        Hier mal die Grundlagen dazu: https://de.wikipedia.org/wiki/Byte-Reihenfolge

                                        Lt. Bedienungsanleitung von deinem X-320 lässt sich die Byte-Reihenfolge einstellen:

                                        ` > Big Endian

                                        32-bit data is treated as two individual 16-bit words using IEEE 754 floating point format. Floating

                                        point format is used for sensor, pulse counter, analog, and frequency data as well as for setting

                                        output pulse duration.

                                        If the checkbox is set, the X-320™ will use big-endian architecture, and the most significant 16-bit

                                        word (big end) is sent first. If the box is cleared, then the X-320™ will use little-endian architecture,

                                        and the least significant word (little end) is sent first. The default setting for this box is

                                        unchecked,

                                        use little-endian.

                                        For example, in little-endian format, a 32-bit floating point number represented by '1234 ABCD' is

                                        sent as 'ABCD 1234'. `

                                        Um Big Endian auslesen zu können verwendest Du die Funktion msg.payload.buffer.readFloatBE(0,1,2,3) und für Littel Endian die Funktion msg.payload.buffer.readFloatLE(0,1,2,3).

                                        Nicht, dass wir uns hier ständig im Kreis drehen. Vielleicht im X-320 Big Endian einstellen und dann mal schauen was in den Modbusregistern 1 und 2 steht. Es könnte dir das Auslesen evtl. vereinfachen.

                                        1 Reply Last reply Reply Quote 0
                                        • J
                                          JXA last edited by

                                          Hallo Graf,

                                          danke für den Hinweis!

                                          Hatte ich mit keinem Gedanken mehr daran gedacht…

                                          Und jetzt funktioniert es!!!!

                                          Danke für DEINE (Eure) Hilfe!
                                          5860_working.png

                                          1 Reply Last reply Reply Quote 0
                                          • J
                                            JXA last edited by

                                            Hier noch die Funktion…...
                                            5860_swap_working.png

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            940
                                            Online

                                            31.9k
                                            Users

                                            80.2k
                                            Topics

                                            1.3m
                                            Posts

                                            5
                                            67
                                            11753
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo