Search code examples
javamodbus

How can I use DigitalIn in ProcessImage - Modbus


I'm working on a modbus UDP implementation [ J2Mod(2.3.4) ] in Java. I have found almost no useful documentation. I have a boolean array like flags.

  1. Slave will read it via SimpleProcessImage->DigitalIn
  2. Slave will use that flags and change them
  3. Then write it to SimpleProcessImage->DigitalOut in every 10 secs.

I need help on 1st step. When I use master.readCoils(i, 1) and master.writeCoils(i, true). It only use DigitalOut. It write to DigitalOut and read from DigitalOut.

for (int i = 0; i < interSize ; i++) {
            SimpleDigitalOut dout = (SimpleDigitalOut) image.getDigitalOut(i);
            dout.set(i%5==0);
            image.setDigitalOut(i, dout);
}

If I change DigitalOut on slave side as shown above, I can get changed values through DigitalOut. But I need to use them both; DigitalOut and DigitalIn.

Here's my code for slave.

public class Slave {
    private SimpleProcessImage image;
    private ModbusSlave slave;
    private int interSize = 62000;
    int step;

    public Slave(){

        image = new SimpleProcessImage();
        step=0;

        for (int i = 0; i < interSize; i++) {
            image.addDigitalOut(i, new SimpleDigitalOut(false));
            image.addDigitalIn(i, new SimpleDigitalIn(false));
         }

         (new Timer()).scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                    read();
                    write();
            }
        }, 0, 10000);

        startServer();
    }

private void read() {
        System.out.print("Read In : ");
        for (int i = 0; i < interSize; i++) {
            System.out.print((image.getDigitalIn(i).isSet() ? 1 : 0) + " ");
        }

        System.out.print("Read Out: ");
        for (int i = 0; i < interSize; i++) {
            System.out.print((image.getDigitalOut(i).isSet() ? 1 : 0) + " ");
        }
}

    public void startServer() {
        try {
            slave = ModbusSlaveFactory.createUDPSlave(502);
            slave.addProcessImage(0, image);
            slave.open();
        } catch (ModbusException e) {
            e.printStackTrace();
        }
    }
}

Also here my client

public class Client {
    private ModbusUDPMaster master;
    int interSize = 62000 ;

    Client() {
        master = new ModbusUDPMaster("127.0.0.1", 502);

        try {
            master.connect();
        } catch (Exception e) {
            e.printStackTrace();
        }

        write();
        while(true){
             read();
        }
    }

    public static void main(String... args) {
        new Client();
    }

    private void write() {
        for (int i = 0; i < interSize; i++) {
            try {
                master.writeCoil(i, i%3==0);
            } catch (ModbusException e) {
                e.printStackTrace();
            }
        }
    }

    private void read() {
        try {
            for (int i = 0; i < interSize; i++) {
                System.out.print(master.readCoils(i, 1).toString());
            }
        } catch (ModbusException e) {
            e.printStackTrace();
        }
    }
}

Solution

  • If anybody still looking for answer, as shown here, you can read DigitalIn via readInputDiscretes function.

    Read Discretes

    // master.readInputDiscretes(<discrete ref>, <count>);  // Uses a UNIT ID of 1
    master.readInputDiscretes(<unit id>, <discrete ref>, <count>);