• ramonhl

    Hello.
    When I run the next code I can see that the master.getValue(el), send the message to the server to close the socket.
    In the attached whireshark picture you can see it. In the whireshark picture the 192.168.2.101 is the controller (modbus tcp server) and the 192.168.2.69 is my computer.
    In this moment I have problems reading values every 500ms from one controller because every time that I read the master.getValue close the socket.

    Do you know How can we close the socket only at the end of the readings?

    Thanks.

    
     NumericLocator el = new NumericLocator(255, RegisterRange.HOLDING_REGISTER, 0, DataType.TWO_BYTE_INT_UNSIGNED);
            NumericLocator fjk = new NumericLocator(255, RegisterRange.HOLDING_REGISTER, 1, DataType.TWO_BYTE_INT_UNSIGNED);
    
            for (int i = 0; i < 1113; i++) {
                try {
                    System.out.println("el: " + master.getValue(el));
                    System.out.println("fjk: " + master.getValue(fjk));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
    

    posted in Modbus4J general discussion read more
  • ramonhl

    Hello.
    I am testing the ListeterTest2.java and works fine.

    public class ListenerTest2Mon1 {
        static Random random = new Random();
        static float ir1Value = -100;
    
        public static void main(String[] args) throws Exception {
            ModbusFactory modbusFactory = new ModbusFactory();
            final ModbusSlaveSet listener = modbusFactory.createTcpSlave(false);
            listener.addProcessImage(getModscanProcessImage(127));       
    
            // When the "listener" is started it will use the current thread to run. So, if an exception is not thrown
            // (and we hope it won't be), the method call will not return. Therefore, we start the listener in a separate
            // thread so that we can use this thread to modify the values.
            new Thread(new Runnable() {
                public void run() {
                    try {
                        listener.start();
                    }
                    catch (ModbusInitException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
            while (true) {
                updateProcessImage1((BasicProcessImage) listener.getProcessImage(127));
               
                synchronized (listener) {
                    listener.wait(100);
                }
            }
        }
    
        static void updateProcessImage1(BasicProcessImage processImage) {
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 0, DataType.TWO_BYTE_INT_UNSIGNED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 2, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 10, DataType.TWO_BYTE_INT_UNSIGNED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 12, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 20, DataType.TWO_BYTE_INT_UNSIGNED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 22, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED,
                    random.nextInt(10000));
        }
     
            static BasicProcessImage getModscanProcessImage(int slaveId) {
            BasicProcessImage processImage = new BasicProcessImage(slaveId);
            processImage.setAllowInvalidAddress(true);
            processImage.setInvalidAddressValue(Short.MIN_VALUE);
            processImage.setExceptionStatus((byte) 151);
    
            return processImage;
        }
    }
    

    But when I try to insert this code in my java program I have problems with the threads.
    I do:

    • Change the code of the listener test and create a new class.
    • In java I have a jframe with two buttons, start server, stop server.
    • In the jframe I create a new instance of my listener class.
    • In the start button I start using my class the listener.start().
    • The start button freezes, if I debug in the listener.start() the code stops.

    Do you have some example with listener in jframe or similar?

    Thanks in advance.

    Best regards.

    posted in Modbus4J general discussion read more
  • ramonhl

    Hello.
    I am using the last version of Modbus4J 2.0.2, converted to use Maven for dependency management.
    In my first Modbus4J project (1 year ago), I only add the different *.jar to my project and it works fine. (modbus4J.jar, seroUtils.jar, RXTXcomm.jar)
    But now I can not do it, if I add the new jar on my project I can see a lot of build errors, regarding for apache libs...
    I am using Eclipse and I installed the maven plugin but I do not know how I can insert the libraries in my project.

    Do you know How Can I build and test the files of com.serotonin.modbus4j.test of Modbus4J 2.0.2? (MasterTest.java, ListenerTest.java...)
    And How Can I integrate the new Modbus4J libraries on my project?

    Thanks in advance,

    Best regards.

    posted in Modbus4J general discussion read more
  • ramonhl

    Hello.
    I am testing the ListenerTest.java in Linux computer and Eclipse 4.3.2
    The code is the next:

    package com.ramonahl.test;
    
    import java.util.Random;
    
    import com.serotonin.modbus4j.BasicProcessImage;
    import com.serotonin.modbus4j.ModbusFactory;
    import com.serotonin.modbus4j.ModbusSlaveSet;
    import com.serotonin.modbus4j.ProcessImage;
    import com.serotonin.modbus4j.ProcessImageListener;
    import com.serotonin.modbus4j.code.DataType;
    import com.serotonin.modbus4j.code.RegisterRange;
    import com.serotonin.modbus4j.exception.IllegalDataAddressException;
    import com.serotonin.modbus4j.exception.ModbusInitException;
    import com.serotonin.modbus4j.ip.IpParameters;
    
    public class ListenerTest {
        static Random random = new Random();
        static float ir1Value = -100;
    
        public static void main(String[] args) throws Exception {
            // SerialParameters params = new SerialParameters();
            // params.setCommPortId("COM1");
            // params.setPortOwnerName("dufus");
            // params.setBaudRate(9600);
    
            IpParameters params = new IpParameters();
            String host = "127.0.0.1";
    		params.setHost(host );
    
            ModbusFactory modbusFactory = new ModbusFactory();
            // ModbusListener listener = modbusFactory.createRtuListener(processImage, 31, params, false);
            // ModbusListener listener = modbusFactory.createAsciiListener(processImage, 31, params);
            final ModbusSlaveSet listener = modbusFactory.createTcpSlave(false);
            // ModbusSlave listener = modbusFactory.createUdpSlave(processImage, 31);
    
            // Add a few slave process images to the listener.
            listener.addProcessImage(getModscanProcessImage(2));
            listener.addProcessImage(getModscanProcessImage(3));
            listener.addProcessImage(getModscanProcessImage(5));
            listener.addProcessImage(getModscanProcessImage(9));
    
            // When the "listener" is started it will use the current thread to run. So, if an exception is not thrown
            // (and we hope it won't be), the method call will not return. Therefore, we start the listener in a separate
            // thread so that we can use this thread to modify the values.
            new Thread(new Runnable() {
                public void run() {
                    try {
                        listener.start();
                    }
                    catch (ModbusInitException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
            while (true) {
                synchronized (listener) {
                    listener.wait(200);
                }
    
                for (ProcessImage processImage : listener.getProcessImages())
                    updateProcessImage((BasicProcessImage) processImage);
            }
        }
    
        static void updateProcessImage(BasicProcessImage processImage) throws IllegalDataAddressException {
            processImage.setInput(10, !processImage.getInput(10));
            processImage.setInput(13, !processImage.getInput(13));
    
            processImage.setInputRegister(20, DataType.FOUR_BYTE_FLOAT, ir1Value += 0.01);
    
            short hr1Value = ((Number) processImage.getHoldingRegister(80, DataType.TWO_BYTE_BCD)).shortValue();
            processImage.setHoldingRegister(80, DataType.TWO_BYTE_BCD, hr1Value + 1);
        }
    
        static class BasicProcessImageListener implements ProcessImageListener {
            public void coilWrite(int offset, boolean oldValue, boolean newValue) {
                System.out.println("Coil at " + offset + " was set from " + oldValue + " to " + newValue);
            }
    
            public void holdingRegisterWrite(int offset, short oldValue, short newValue) {
                System.out.println("HR at " + offset + " was set from " + oldValue + " to " + newValue);
            }
        }
    
        static BasicProcessImage getModscanProcessImage(int slaveId) {
            BasicProcessImage processImage = new BasicProcessImage(slaveId);
            processImage.setAllowInvalidAddress(false);
            processImage.setInvalidAddressValue(Short.MIN_VALUE);
    
            processImage.setCoil(10, true);
            processImage.setCoil(11, false);
            processImage.setCoil(12, true);
            processImage.setCoil(13, true);
            processImage.setCoil(14, false);
    
            processImage.setInput(10, false);
            processImage.setInput(11, false);
            processImage.setInput(12, true);
            processImage.setInput(13, false);
            processImage.setInput(14, true);
    
            processImage.setBinary(16, true);
            processImage.setBinary(10016, true);
    
            processImage.setHoldingRegister(10, (short) 1);
            processImage.setHoldingRegister(11, (short) 10);
            processImage.setHoldingRegister(12, (short) 100);
            processImage.setHoldingRegister(13, (short) 1000);
            processImage.setHoldingRegister(14, (short) 10000);
    
            processImage.setInputRegister(10, (short) 10000);
            processImage.setInputRegister(11, (short) 1000);
            processImage.setInputRegister(12, (short) 100);
            processImage.setInputRegister(13, (short) 10);
            processImage.setInputRegister(14, (short) 1);
    
            processImage.setBit(RegisterRange.HOLDING_REGISTER, 15, 0, true);
            processImage.setBit(RegisterRange.HOLDING_REGISTER, 15, 3, true);
            processImage.setBit(RegisterRange.HOLDING_REGISTER, 15, 7, true);
            processImage.setBit(RegisterRange.HOLDING_REGISTER, 15, 8, true);
            processImage.setBit(RegisterRange.HOLDING_REGISTER, 15, 14, true);
    
            processImage.setBit(RegisterRange.INPUT_REGISTER, 15, 0, true);
            processImage.setBit(RegisterRange.INPUT_REGISTER, 15, 7, true);
            processImage.setBit(RegisterRange.INPUT_REGISTER, 15, 8, true);
            processImage.setBit(RegisterRange.INPUT_REGISTER, 15, 15, true);
    
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 16, DataType.TWO_BYTE_INT_SIGNED, new Integer(-1968));
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 17, DataType.FOUR_BYTE_INT_SIGNED,
                    new Long(-123456789));
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 19, DataType.FOUR_BYTE_INT_SIGNED_SWAPPED, new Long(
                    -123456789));
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 21, DataType.FOUR_BYTE_FLOAT, new Float(1968.1968));
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 23, DataType.EIGHT_BYTE_INT_SIGNED, new Long(
                    -123456789));
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 27, DataType.EIGHT_BYTE_INT_SIGNED_SWAPPED, new Long(
                    -123456789));
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 31, DataType.EIGHT_BYTE_FLOAT, new Double(1968.1968));
    
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 80, DataType.TWO_BYTE_BCD, new Short((short) 1234));
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 81, DataType.FOUR_BYTE_BCD, new Integer(12345678));
    
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 12288, DataType.FOUR_BYTE_FLOAT_SWAPPED, new Float(
                    1968.1968));
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 12290, DataType.FOUR_BYTE_FLOAT_SWAPPED, new Float(
                    -1968.1968));
    
            processImage.setRegister(RegisterRange.INPUT_REGISTER, 16, DataType.TWO_BYTE_INT_UNSIGNED, new Integer(0xfff0));
            processImage.setRegister(RegisterRange.INPUT_REGISTER, 17, DataType.FOUR_BYTE_INT_UNSIGNED,
                    new Long(-123456789));
            processImage.setRegister(RegisterRange.INPUT_REGISTER, 19, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED, new Long(
                    -123456789));
            processImage.setRegister(RegisterRange.INPUT_REGISTER, 21, DataType.FOUR_BYTE_FLOAT_SWAPPED, new Float(
                    1968.1968));
            processImage.setRegister(RegisterRange.INPUT_REGISTER, 23, DataType.EIGHT_BYTE_INT_UNSIGNED, new Long(
                    -123456789));
            processImage.setRegister(RegisterRange.INPUT_REGISTER, 27, DataType.EIGHT_BYTE_INT_UNSIGNED_SWAPPED, new Long(
                    -123456789));
            processImage.setRegister(RegisterRange.INPUT_REGISTER, 31, DataType.EIGHT_BYTE_FLOAT_SWAPPED, new Double(
                    1968.1968));
    
            processImage.setRegister(RegisterRange.HOLDING_REGISTER, 50, DataType.EIGHT_BYTE_INT_UNSIGNED, 0);
            processImage.setExceptionStatus((byte) 151);
    
            // Add an image listener.
            processImage.addListener(new BasicProcessImageListener());
    
            return processImage;
        }
    }
    
    

    But when I run the code I can see the next error:

    com.serotonin.modbus4j.exception.ModbusInitException: java.net.BindException: Permiso denegado
    at com.serotonin.modbus4j.ip.tcp.TcpSlave.start(TcpSlave.java:57)
    at com.ramonahl.test.ListenerTest$1.run(ListenerTest.java:48)
    at java.lang.Thread.run(Thread.java:744)
    Caused by: java.net.BindException: Permiso denegado
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
    at java.net.ServerSocket.bind(ServerSocket.java:376)
    at java.net.ServerSocket.<init>(ServerSocket.java:237)
    at java.net.ServerSocket.<init>(ServerSocket.java:128)
    at com.serotonin.modbus4j.ip.tcp.TcpSlave.start(TcpSlave.java:47)
    ... 2 more

    Do you know How Can I solve this error?

    Thanks in advance.

    posted in Modbus4J general discussion read more
  • ramonhl

    I am developing an Android application to read/write Modbus TCP variables in some PLC.
    In this moment I read/write variables using the function ReadHoldingRegisters/WriteHoldingRegisters.

    master.init()--> ReadHoldingRegisters or WriteHoldingRegisters --> master.destroy();

    My question is:

    If I want read the registers every second, What is the best way to do it? make 1 sec timer and read every second?
    Can I use other modbus4j function to do this?

    Thanks, best regards.

    posted in Modbus4J general discussion read more
  • ramonhl

    I am using modbus4j in Android application. Before I tested it in java, and works fine. But in Android I have problems with the master.init(), it does not work. In the manifest I add permissions for Internet and Access network state. I have a code more or less like this:

    // Perform action on click
                // Read IP from layout***
                EditText edittext_IP = (EditText) findViewById(R.id.editText1);
                TextView MWReaded = (TextView) findViewById(R.id.textView4);
                // **********************
    
                //
                String slaveIP;
                slaveIP = edittext_IP.getText().toString();
    
                ModbusFactory factory = new ModbusFactory();
                IpParameters params = new IpParameters();
                params.setHost(slaveIP);
                params.setPort(502);
                params.setEncapsulated(false);
                ModbusMaster master = factory.createTcpMaster(params, true);
                master.setTimeout(500);
                master.setRetries(2);
    
                try {
                    master.init();
                } catch (ModbusInitException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    Toast.makeText(getApplication(),
                            "Error: " + e.getMessage(), 10).show();
                }
                ModbusLocator locator = new ModbusLocator(1,
                        RegisterRange.HOLDING_REGISTER, 0,
                        DataType.TWO_BYTE_INT_UNSIGNED);
    
                Object xx = null;
                try {
                    xx = master.getValue(locator);
                } catch (ModbusTransportException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ErrorResponseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    
                int Register = 0;
    
                if (xx != null){
                Register = Integer.parseInt(xx.toString());
                } else{
                    Register = 6969;
                }
    
                MWReaded.setText(String.valueOf(Register));
                TextView txttest_n = (TextView) findViewById(R.id.textView5);
                txttest_n.setText("n=" + n);
                n = n + 1;
    
            }
        });
    
    

    But the master is never initialized. I can see a exception. "android.os.NetworkOnMainThreadException"
    **
    Do you know how can I solve this problem?**

    posted in Modbus4J general discussion read more
  • ramonhl

    The problem is solved.
    When we create the master we can see a paramer keepalive in the constructor.

    ModbusMaster master = modbusFactory.createTcpMaster(ipParameters, keepalive);

    I was keepalive=false. If keepalive = false then every time that the client (master) read of the server (slave) the socket is open------close.

    If keepalive = true then the master close the socket at the end of all the readings. But I do not know how the keepalive works exactly, is it parametrizable...

    Do you know How the keepalive works exactly? And Where Can I find Modbus4j documentation?

    Best regards.

    posted in Modbus4J general discussion read more
  • ramonhl

    Hello.
    When I run the next code I can see that the master.getValue(el), send the message to the server to close the socket.
    In the attached whireshark picture you can see it. In the whireshark picture the 192.168.2.101 is the controller (modbus tcp server) and the 192.168.2.69 is my computer.
    In this moment I have problems reading values every 500ms from one controller because every time that I read the master.getValue close the socket.

    Do you know How can we close the socket only at the end of the readings?

    Thanks.

    
     NumericLocator el = new NumericLocator(255, RegisterRange.HOLDING_REGISTER, 0, DataType.TWO_BYTE_INT_UNSIGNED);
            NumericLocator fjk = new NumericLocator(255, RegisterRange.HOLDING_REGISTER, 1, DataType.TWO_BYTE_INT_UNSIGNED);
    
            for (int i = 0; i < 1113; i++) {
                try {
                    System.out.println("el: " + master.getValue(el));
                    System.out.println("fjk: " + master.getValue(fjk));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
    

    Attachment: download link

    posted in Modbus4J general discussion read more
  • ramonhl

    Hello.
    I am testing the ListeterTest2.java and works fine.

    public class ListenerTest2Mon1 {
        static Random random = new Random();
        static float ir1Value = -100;
    
        public static void main(String[] args) throws Exception {
            ModbusFactory modbusFactory = new ModbusFactory();
            final ModbusSlaveSet listener = modbusFactory.createTcpSlave(false);
            listener.addProcessImage(getModscanProcessImage(127));       
    
            // When the "listener" is started it will use the current thread to run. So, if an exception is not thrown
            // (and we hope it won't be), the method call will not return. Therefore, we start the listener in a separate
            // thread so that we can use this thread to modify the values.
            new Thread(new Runnable() {
                public void run() {
                    try {
                        listener.start();
                    }
                    catch (ModbusInitException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
            while (true) {
                updateProcessImage1((BasicProcessImage) listener.getProcessImage(127));
               
                synchronized (listener) {
                    listener.wait(100);
                }
            }
        }
    
        static void updateProcessImage1(BasicProcessImage processImage) {
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 0, DataType.TWO_BYTE_INT_UNSIGNED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 2, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 10, DataType.TWO_BYTE_INT_UNSIGNED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 12, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 20, DataType.TWO_BYTE_INT_UNSIGNED,
                    random.nextInt(10000));
            processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 22, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED,
                    random.nextInt(10000));
        }
     
            static BasicProcessImage getModscanProcessImage(int slaveId) {
            BasicProcessImage processImage = new BasicProcessImage(slaveId);
            processImage.setAllowInvalidAddress(true);
            processImage.setInvalidAddressValue(Short.MIN_VALUE);
            processImage.setExceptionStatus((byte) 151);
    
            return processImage;
        }
    }
    

    But when I try to insert this code in my java program I have problems with the threads.
    I do:

    • Change the code of the listener test and create a new class.
    • In java I have a jframe with two buttons, start server, stop server.
    • In the jframe I create a new instance of my listener class.
    • In the start button I start using my class the listener.start().
    • The start button freezes, if I debug in the listener.start() the code stops.

    Do you have some example with listener in jframe or similar?

    Thanks in advance.

    Best regards.

    posted in Modbus4J general discussion read more
  • ramonhl

    Problem solved.
    In the pom.xml file I can see the libraries that we need.
    I can find these libraries in ~/.m2/repository and in modbus4j-maven-local.
    I added these libraries *.jar, in my project and all works fine.

    posted in Modbus4J general discussion read more