Reading and Writing 4 byte floating point from modbus



  • Hello,

    I am implementing a control solution for a breadboard rocket test bench using the Monarco HAT and Rexygen. I can read and write commands with success using modbus with all devices so far but I am having difficulties with some values that need to be read and write using 4 byte floating point (IEEE 32-bit single precision, MSB first) values.

    How do I convert the read values to something human readable for my HMI and then convert analog inputs back to this format to send the correct command back?

    For now the read values shows things like:

    b6e8fec4-9440-470e-b96c-73c1bd7be27b-image.png

    The upper one is a modbus value of temperature in the 4 byte floating point format and the lower one an integer of a second flow controller showing the same temperature. Just as an example.

    Almost all commands and information I need does not need to be floating point but the critical input (the set-point of the controller) must be of this number format.

    Thank you!



  • Hi Bruno,
    how did you set your Modbus RTU registers at Monarco HAT? Please, open your MBM driver block in the Exec file of your project. Click on Configure button and Modbus registers editor will appear. For reading a 4 byte floating point real number, you should add an Item with proper Item Address, Type REGISTER_DOUBLE and marked Readable. The MSB first format should be the native format of Rexygen numbers, so you don't need to check the Swap Bytes box, but maybe the Swap Words box will be useful. With a right configuration of this two boxes (Swap Bytes and Swap Words), you should observe correct real numbers direct at the output of the MBM__FLWF_TEMPERATURE flag and no additional conversion should be needed.
    I usually use this site for checking the proper byte order: http://www.binaryconvert.com/convert_double.html
    If you have the opportunity to directly monitor the values of communicated bytes, please post them here.
    Documentation for Modbus in Rexygen is there: https://www.rexygen.com/doc/ENGLISH/MANUALS/MbDrv/MbDrv_ENG.html

    Cheers,
    Jan



  • Thank you Jan

    Swap Words did the trick:

    475f6e4b-38fa-49a3-9220-e2f5e0c4442b-image.png

    There are other registers that I am not able to read even with the same settings (REGISTER_FLOAT type and Swap Words ticked)

    Today I'll test the other way: try to write a float type πŸ™‚

    Ont he same subject, but other type of data, from the 917050-Manual-mini-CORI-FLOW.pdf page 29:

    Type
    Unsigned char 1 byte unsigned integer (0…255)
    Unsigned int 2 byte unsigned integer, MSB first (0…65535)
    Unsigned long 4 byte unsigned integer, MSB first (0…4294967295)
    Float 4 byte floating point, IEEE 32-bit single precision, MSB first
    Unsigned char '[x]' x byte array (text string)

    This last one is a ASCII text . Please, any tips if it is possible to read or write these types of data? They give an example at page 35:

    Fluid Name:
    Request
    01 03 81 88 00 05 2D DF
    01 slave address of instrument Address = 0x01
    03 function code 0x03 is Read Holding Register
    8188 starting address
    0005 quantity of registers (5 register2 = 10 bytes)
    2DDF CRC

    Response
    01 03 0A 41 69 72 20 20 20 20 20 20 20 86 7F
    01 slave address
    03 function code 0x03 is Read Holding Register
    0A number of Bytes
    697220202020202020 Fluid Name in ASCII
    86 7F CRC (Generated from the MODBUS slave)

    Thank you!



  • Other doubt is about RW data and use of Goto and From.

    If I have a RW type of register why I can not use the same register for both? Now I created a pair of them for this - one to write the value and a second one to read the current set value.



  • Dear Bruno,
    in my opinion, Rexygen does not natively support the string type in Modbus registers. If reading ASCII values ​​is enough for you, use several REGISTER_16 or REGISTER_32 items and INTSM blocks (www.rexygen.com/doc/ENGLISH/MANUALS/BRef/INTSM.html). Use settings:

    • shift = 0, mask = 255 for reading LSB
    • shift = 8, mask = 255 for second byte, etc.

    For example REGISTER_16 (UINT16) value 0x4272 = 17010 will be divided to LSB = 0x72 = 114 and MSB = 0x42 = 66.
    d7b31cfd-ce43-4622-aca5-bf2cd8f42914-image.png

    If you want to convert ASCII characters into a string, you should use a Python block (https://www.rexygen.com/doc/ENGLISH/MANUALS/BRef/PYTHON.html).

    Cheers,
    Jan



  • @brunofporto Hi Bruno,
    you can read and write into one register simultaneously, but you need two items in the Modbus Master registers table. Rexygen doesn't support Read and Write flags at one Master Item. You should set something like this into your table for one register value:
    8b435268-4377-45db-8768-4a04c4dc68a5-image.png

    You can also look here, where similar problem was solved:
    https://forum.rexygen.com/topic/23/read-write-modbus/9?_=1608627568594



  • @reitinge Thank you very much! That is what I am doing right now πŸ™‚ It works good enough.


Log in to reply