Menu

Additional use case: Modbus via tcp-to-modbus gateway

2013-03-12
2015-09-20
  • Chris Owens

    Chris Owens - 2013-03-12

    There are cases in which an application may wish to communicate with a modbus device that is sitting behind a "serial device server", for example, a Moxa 5130 (http://www.moxa.com/product/NPort_5100A.htm).

    This is Modbus-over-TCP (not the same as Modbus-TCP); also known as Modbus-RTU/IP. The application builds a Modbus-RTU message, including checksum, and then sends it over a TCP/IP connection to the gateway device, which puts the message on the Modbus wire -- the server takes any modbus messages it receives over the modbus wire and sends them back over the TCP connection to the requesting application.

    I have written some code to handle this (it's a pretty trivial extension) and am happy to contribute it.

     
    • Sumeet Garg

      Sumeet Garg - 2014-05-27

      Hi Chris,

      We also have the requirement for connecting to devices behind serial device server.
      We will need to connect to MOXA Nport 5232. As you have mentioned your implementation is Modbus RTU over TCP/IP, I guess this would work in our case as well.
      Please let me know if you can share some samples on implementation.

      Thanks,
      Sumeet

       
    • Julie Haugh

      Julie Haugh - 2014-07-20

      This should be the standard case of making the packet "headless". What am I missing here?

       
  • R. J. Mathar

    R. J. Mathar - 2014-07-17

    Here are the simplest adaptations to this use case, which is the most
    common one I suppose. One could (should) create new classes
    for that purpose, but changing the original files would also work if
    just a local copy of the j2mod package is needed:
    i) in the function writeMessage in io/ModbusTCPTransport.java add
    the CRC to the contents by adding 4 lines before the final write():

    ...
    if (message != null && message.length > 0)
             m_ByteOut.write(message);
    
    /* block of 4 lines to be inserted: RJM 2014-07-08 */
    int len = m_ByteOut.size();
    int[] crc = ModbusUtil.calculateCRC(m_ByteOut.getBuffer(), 0, len);
    m_ByteOut.writeByte(crc[0]);
    m_ByteOut.writeByte(crc[1]);
    
    m_Output.write(m_ByteOut.toByteArray());
    ...
    

    ii) as a basis for the main reader start from cmd/ReadInputRegistersTest.java
    and insert a setheadless() in the loop over the repeats:

    // 3. Create the command.
    req = new ReadInputRegistersRequest(ref, count);
    req.setUnitID(unit);
    req.setHeadless(); // RJM 2014-07-08
    

    and insert a setHeadless() in the (derived) class also in the loop:

     if (trans instanceof ModbusTCPTransaction) {
         ((ModbusTCPTransaction) trans).setReconnecting(true);
         ((ModbusTCPTransport) transport).setHeadless(); // RJM 2014-07-08
     }
    

    Optionally add a function for JUMO devices:

    /**
    * Convert four successive bytes to a JUMO specific float value.
    * @param b1 The array of two bytes, in the MODBUS order
    * @param b2 The array of two bytes, in the MODBUS order
    * @return The float value obtained by glueing the two bytes
    */
    public static float toFloat(final byte[] b1, final byte[] b2, final boolean swap)
    {
            /* two ways of doing it: first b1 or first b2 ?
            */
            int bits ;
            if ( swap )
            {
                    bits = b2[0] & 0xff ;
                    bits = (bits << 8) + (b2[1] & 0xff) ;
                    bits = (bits << 8) + (b1[0] & 0xff);
                    bits = (bits << 8) + (b1[1] & 0xff);
            }
            else
            {
                    bits = b1[0] & 0xff ;
                    bits = (bits << 8) + (b1[1] & 0xff) ;
                    bits = (bits << 8) + (b2[0] & 0xff);
                    bits = (bits << 8) + (b2[1] & 0xff) ;
            }
            return Float.intBitsToFloat(bits) ;
    } /* toFloat */
    
     
  • José Manuel Pires

    Hello.

    I'm actually trying to communicate via TCP/IP to a RTU slave setup but I'm not able to modify the libraries of j2mod, is there another way to get working CRC calculations on my TCP transaction? I have a full TCP/IP master working, but needing CRC calculations and slaveID setup to the modbus message.

    thanks in advance

     
  • Julie Haugh

    Julie Haugh - 2015-09-20

    You need to mark the packets as "headless". When you do that the 6 byte TCP header is skipped and the two byte CRC is added.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.