Modbus connection via Qronox PCD3 M6893

1 day ago
11 hours ago
  • Hello,
    I am currently scaling 4-20mA signals and the scaled output (temperature) has to be sent via modbus protocol to a tool like doctor modbus or modbus poll. I have defined my inputs as real as and the output is also real, but to send this output via modbus it has to be of word. So how will i convert real into word and then send the generated output via modbus?

     
  • risele - 1 day ago

    First, if you don't need to change conversion rules in runtime, take a look at "Unit conversion" module (Application -> add object -> UnitConversion). You can specify there biderectional conversion with different units, limits and so on.

    Second, since MODBUS don't have "real" types but only general 16-bit registers and Real is 32-bit, generally you need a byte-was conversion Real <> two Words. Note, that depending on the devices on both sides, there are two options: Real-> Word1, Word2 or Real-> Word2, Word1, where Word1 is minor register in Modbus register pair and Word2 is major.

    You can use simple union:

    TYPE u_Real :
    UNION
        rVal:REAL;
        wVal:ARRAY[0..1] OF WORD;   
        dwVAL:DWORD; //same as previous, may be easier to specify the MB register
    END_UNION
    END_TYPE
    

    and convert it as following:

    VAR
        myUnion:u_Real;
    
        rValue_TO_SEND:REAL;
        rValue_TO_GET:REAL;
    END_VAR
    myUnion.rVal:=rValue_TO_SEND;
    rValue_TO_GET:=myUnion.rVal;
    

    Note, that WORD-order should be properly set in MODBUS registers, otherwise you will get strange values. This tool is helpful: https://www.scadacore.com/tools/programming-calculators/online-hex-converter/

    Alternative, you can use functions as REAL_TO_DW and DW_TO_REAL from OSCAT_BASIC, for example.

     

    Last edit: risele 11 hours ago
  • Thank you for your suggestions, based on it I will modify the code

     

    Last edit: nehaltrivedi96 12 hours ago
    • risele - 11 hours ago

      You are welcome.
      Also note, that it's valid only if you modbus-device use same real/float value representation (IEEE 754). That's true for most of systems.
      But some devices may have other representation, such as integer + position of the decimal point, for example 123.456 is integer = 123456 and position = 3

      Also note, that, ones again, depending on endianess of each system, you may also need to swap not just words, but bytes.

      TYPE u_Real :
      UNION
          rVal:REAL;
          wVal:ARRAY[0..1] OF WORD;   
          bVal:ARRAY[0..3] OF BYTE;   
          dwVAL:DWORD; //same as previous, may be easier to specify the MB register
      END_UNION
      END_TYPE
      

      than swapping may be something as

      VAR
      A,B,C,D:BYTE; //Bytes of the real value
      uIn, uOut:u_Real;
      rVal:REAL;
      ModbusReg1,ModbusReg2:WORD;
      END_VAR
      
      uIn.rVal:=rVal;
      uOut.A:=uIn.D;
      uOut.B:=uIn.C;
      uOut.C:=uIn.B;
      uOut.D:=uIn.A;
      
      ModbusReg1:=uOut.wVal[0];
      ModbusReg1:=uOut.wVal[2];
      

      Or you even need to reorder bits... Ones again, sending float/real values is not defined by Modbus protocol itself, so it is hardware- and software-dependent.

      The Modbus Poll (and most of modbus tools) have configuration parameters that will properly swap bytes on their side.

      Ones again, that's very helpful:
      https://www.scadacore.com/tools/programming-calculators/online-hex-converter/

       

      Related

      Talk.ru: 2


      Last edit: risele 11 hours ago

Log in to post a comment.