Menu

Modbus RTU Over Tcp/Ip, the response always get NULL!

Draco Wang
2016-03-14
2016-06-01
  • Draco Wang

    Draco Wang - 2016-03-14

    Hello,
    I am using J2mod(j2mod-1.06.jar), it's amazing project, i love it very much.
    There is a case in which an application try to communicate with a modbus device(Modbus RTU Over tcp/ip),here is the codes:

    String hostName = "127.0.0.1";
    int port = Modbus.DEFAULT_PORT;
    Socket socket = new Socket(hostName, port);
    ModbusTCPTransport transport = new ModbusTCPTransport(socket);
    ReadInputRegistersRequest rtureq = new ReadInputRegistersRequest(1, 20);
    ReadInputRegistersResponse rtures =  null;
    
    rtureq.setUnitID(1);
    rtureq.setHeadless(false);
    ModbusTransaction rtu_tran = transport.createTransaction();
    rtu_tran.setRequest(rtureq);
    
    do{
          rtu_tran.execute();       
          rtures= (ReadInputRegistersResponse)rtu_tran.getResponse();//
    
        // rtures always is NULL!
          if (rtures != null) { 
              for (int n = 0; n < rtures.getWordCount(); n++) {
                  System.out.println("Word " + n + "=" + rtures.getRegisterValue(n));
              }
          }
     }
    while(true);
    

    What's wrong with the codes ?
    Thank you in advance!

     
  • Julie Haugh

    Julie Haugh - 2016-03-14

    You've definitely stumped me - I don't see anything obviously wrong with the code you've written. You should have gotten a response or an exception. The only thing I can think of is this is a timing issue. I don't see where you've set a response timeout.

     
    • Draco Wang

      Draco Wang - 2016-03-14

      Julie Haugh, thank you very much.
      I am also confused with the codes, it worked well with Modbus TCP.
      Only one strange thing is when i debug this application , this code
      "rtu_tran.execute();" spent more time (about 5 seconds),but there is not any exception .
      Thanks again for your quickly reply . :)

      By the way, where to set the timeout?

       

      Last edit: Draco Wang 2016-03-14
  • Julie Haugh

    Julie Haugh - 2016-03-14

    It sounds like the request isn't being recognized. Are you sure you are supposed to be using Modbus/RTU with the slave?

     
  • Draco Wang

    Draco Wang - 2016-03-14

    Sure,
    As i am using Modbus Slave simulator, it has five connection types:
    1,serial port
    2,Modbus TCP/IP
    3,Modbus UDP/IP
    4,Modbus RTU Over TCP/IP
    5,Modbus RTU Over UDP/IP

    I tested 1,2,3 based J2MOD, all worked well.
    Don't know what happened with Modbus RTU Over TCP/IP.
    Thank you .

     

    Last edit: Draco Wang 2016-03-14
  • Draco Wang

    Draco Wang - 2016-03-14

    I opened the communication traffic window in the simulator,
    Here is the difference :
    1, use the application
    000000-Rx:00 00 00 00 00 06 01 04 00 00 00 0A
    000001-Rx:00 00 00 00 00 06 01 04 00 00 00 0A
    2, use Modbus Poll simulator,
    000002-Rx:01 04 00 00 00 0A 70 0D
    000003-Tx:01 04 14 00 00 00 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B7 04
    000004-Rx:01 04 00 00 00 0A 70 0D
    000005-Tx:01 04 14 00 00 00 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 47 F4

    Rx is not same with Modbus RTU Over TCP/IP.

     

    Last edit: Draco Wang 2016-03-14
  • Julie Haugh

    Julie Haugh - 2016-03-16

    Sorry for not responding sooner.

    From that trace it appears that the message isn't being sent "headless" despite the code you have above which looks like it should have done precisely that.

     
  • Julie Haugh

    Julie Haugh - 2016-03-16

    This always confuses me as well.

    The answer is that ModbusMessage.setHeadless(b) doesn't control whether or not the message is sent over the transport with a Modbus/TCP header. That's determined by the transport and you need to add the line

    transport.setHeadless();

    before you set the unit number for the message.

    But also, the statement

    rtureq.setHeadless(false);

    is the opposite of what you would have wanted if that did work -- you've told j2mod you do NOT want the message without a header, which means you do want the header. In your case it wouldn't have mattered because the transport determines whether or not a header is included.

    The reason this confuses me is because changing the "headless" setting on a message is used for writing Modbus bridges. Raw messages are received on one transport (RTU or TCP), the header is added or removed, and the message transmitted on another transport.

     
    • Draco Wang

      Draco Wang - 2016-03-22

      Julie,thanks for your kindly help.
      I am not quite understanding what you mean, i changed the code:

      ModbusTCPTransport transport = new ModbusTCPTransport(socket);
      ReadInputRegistersRequest rtureq = new ReadInputRegistersRequest(1, 20);
      ReadInputRegistersResponse rtures = null;

      transport.setHeadless(); // new line

      rtureq.setUnitID(1);
      //rtureq.setHeadless(false); //or rtureq.setHeadless(true),
      ModbusTransaction rtu_tran = transport.createTransaction();
      rtu_tran.setRequest(rtureq);

      not working as well! the response is null .

      Thank you very much.

       
  • Marcio Monteiro

    Marcio Monteiro - 2016-06-01

    Julie,
    I have the need for something similar to that presented by Draco Wang . The application runs with Modbus TCP with a simulator . The problem is running with Modbus RTU over TCP. I understand the concepts of SetHeadless, but my application is different.I'm using J2mod .
    Thank you very much in advance.

    public class Modbus_ip {

    public static void main(String[] args) {
    
        try{
         //Read And Write Register Sample
        //int port = Modbus.DEFAULT_PORT;
        int port = 502;
        //String refe = "4000";//HEX Address
        //int ref=Integer.parseInt(refe,16);//Hex to int          
        int ref=5;
        int count = 6; //the number Address to read
        int SlaveAddr=1;
        String astr = "127.0.0.1"; //Modbus Device                 
        // String astr = "179.245.65.131"; //Modbus Device
    
        InetAddress addr = InetAddress.getByName(astr);
        TCPMasterConnection con = new TCPMasterConnection(addr); //the connection
        ModbusTCPTransaction trans = null; //the transaction
    
        //1.Prepare the request
        /************************************/
        ReadMultipleRegistersRequest Rreq = new ReadMultipleRegistersRequest(ref,count);
        ReadMultipleRegistersResponse Rres = new ReadMultipleRegistersResponse();
    
        Rreq.setHeadless(false);
        Rreq.setUnitID(SlaveAddr); //set Slave Address
    
        //2. Open the connection
        con.setPort(port);
        con.connect();
        con.setTimeout(5000);
    
       /* Socket socket = new Socket(astr, port);
        ModbusTCPTransport transport = new ModbusTCPTransport(socket);
        ModbusTransaction rtu_tran = transport.createTransaction();
        transport.setHeadless();*/
    
        //3. Start Transaction
        trans = new ModbusTCPTransaction(con);
        trans.setRetries(1);
    
        trans.setReconnecting(true);
        trans.setRequest(Rreq);
        trans.execute();
    
        /*Print Response*/
        Rres = (ReadMultipleRegistersResponse) trans.getResponse();
    
        System.out.println("Connected to=  "+ astr + con.isConnected() + " / Start Register " + ref);
    

    // count=1;
    for (int k=0;k<count;k++){
    System.out.println("The value READ: " + Rres.getRegisterValue(k));
    }

    /****************Close Connection**************/
        con.close();
        System.out.println("\nConnected = " + con.isConnected());
        System.exit(0);//edit Java bug error
    
    } 
    catch (Exception ex) {
    ex.printStackTrace();
    
    }
    
    }
    

    }

     

Log in to post a comment.