1

I am working on a client application that is supposed to send a signal to modbus that opens and close a gate with ip address and non-changeable port number 502. The instruction say to create a win-socket client application and send command buffer. I don't understand how to send the command buffer. This is a snapshot of commands. Modbus Commands

I have created a Java socket client class but I don't know what message to send and what datatype to use to send a message. or am I supposed to use one of the modbus libraries to send a signal. Thank you!

socket = new Socket("192.168.0.8, 502);
OutputStream output = socket.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(output);
BufferedWriter bw = new BufferedWriter(writer);

short buffer = ??; // don't know what to send here

//String sendMesage = buffer;
bw.write(buffer);
bw.flush();
System.out.println("Message sent to the server: " + buffer);

InputStream receive = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(receive);
BufferedReader bufferedReader = new BufferedReader(reader);
sanki
  • 59
  • 2
  • 9

3 Answers3

3

Based on the code snippet you show on your question, one gets the impression you are attempting to write a Modbus client from scratch.

Modbus is a quite simple protocol but it would take quite an effort to write an debug a new client and, since the protocol is open, there is plenty of code already written, debugged and tested. See, for instance, here.

On what command to send it's not easy to tell if you don't mention what device, in particular, you're connecting to and what exactly you want to do with it. In a frequent scenario, you have a machine or a sensor in a remote area of your factory that is logging data from its sensors and reacting from that data in a certain manner. With Modbus, you can send requests for data to your machine (reading coils/bits or registers/numeric values) to monitor what it's doing and send commands to control it (writing Modbus coils or registers) from a distant control room with an HMI or any other kind of computer.

EDIT: Now that you have decided to use EasyModbus you are closer to what you want. But it seems that what you're after is reading data from your device, so you don't need to write registers. You can try with this snippet (source):

public static void main(String[] args) 
    {
        ModbusClient modbusClient = new ModbusClient("127.0.0.1", 1536);
        try
        {
            modbusClient.Connect();
            //Read Int value from register 0 (Barrier Command)
            System.out.println(modbusClient.ReadHoldingRegisters(0, 1));
            //Read Float Value from Register 1 and 2 (Barrier Status)
            System.out.println(ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(1, 2)));

        }
        catch (Exception e)
        {
        System.out.println(e.toString());
        }   
    }

If you look at the Modbus address map from your device (I took it from this manual, assuming that one is your device):

enter image description here

One important thing to note is that you have both 16 bit and 32 bit values on your device. Since Modbus registers are 16 bit, for 32 bit data types you need to read two registers. This only applies to register number 1 (Barrier Status according to the mapping above). For all others you can read and display as integer values.

Marcos G.
  • 3,371
  • 2
  • 8
  • 16
2

I got the answer. Well atleast half of it. Instead of creating a socket class in java, I used Easymodbus.jar client library. All I had to do was to connect to the server using ip Address of the modbus and look up the method EasyModbus Methods with the function code (in my case it was function code 6) and call that method with the parameter provided in the manual. I am posting the code just in case somebody needs it. This is for the modbus controller by Magnetic autocontrol GMBH.

    ModbusClient modbusClient = new ModbusClient("192.168.0.135", 502);
    modbusClient.Connect();
    modbusClient.WriteSingleRegister(00, 0001);

I am still trying to figure out to get the output send by the server. Is there anyone who could help me? Thank you!

sanki
  • 59
  • 2
  • 9
0

you can check the below class by passing required arguments.

import java.io.BufferedInputStream;
import java.io.FilterInputStream;
import java.io.OutputStream;
import java.net.Socket;

class Test3 {
      public static void main(String argv[]) {
        if (argv.length < 4) {
          System.out.println("usage: java test3 dns_name unit reg_no num_regs");
          System.out.println("eg java test3 ipaddress 5 0 10");
          return;
        }
        try {
          String ip_adrs = argv[0];`enter code here`
          int unit = Integer.parseInt(argv[1]);
          int reg_no = Integer.parseInt(argv[2]);
          int num_regs = Integer.parseInt(argv[3]);
          System.out.println("ip_adrs = "+ip_adrs+" unit = "+unit+" reg_no = "+
          reg_no+" num_regs = "+num_regs);

          // set up socket
          Socket es = new Socket(ip_adrs,502);
          OutputStream os= es.getOutputStream();
          FilterInputStream is = new BufferedInputStream(es.getInputStream());
          byte obuf[] = new byte[261];
          byte ibuf[] = new byte[261];
          int c = 0;
          int i;

          // build request of form 0 0 0 0 0 6 ui 3 rr rr nn nn
          for (i=0;i<5;i++) obuf[i] = 0;
          obuf[5] = 6;
          obuf[6] = (byte)unit;
          obuf[7] = 3;
          obuf[8] = (byte)(reg_no >> 8);
          obuf[9] = (byte)(reg_no & 0xff);
          obuf[10] = (byte)(num_regs >> 8);
          obuf[11] = (byte)(num_regs & 0xff);

          // send request
          os.write(obuf, 0, 12);

          // read response
          i = is.read(ibuf, 0, 261);
          if (i<9) {
            if (i==0) {
              System.out.println("unexpected close of connection at remote end");
            } else {
              System.out.println("response was too short - "+i+" chars");
            }
          } else if (0 != (ibuf[7] & 0x80)) {
            System.out.println("MODBUS exception response - type "+ibuf[8]);
          } else if (i != (9+2*num_regs)) {
            System.out.println("incorrect response size is "+i+
                " expected"+(9+2*num_regs));
          } else {
            for (i=0;i<num_regs;i++) {
              int w = (ibuf[9+i+i]<<8) + ibuf[10+i+i];
              System.out.println("word "+i+" = "+w);
            }
          }
          // close down
          es.close();
        } catch (Exception e) {
          System.out.println("exception :"+e);
        }
      }
    }