steveohara / j2mod

Enhanced Modbus library implemented in the Java programming language
Apache License 2.0
275 stars 110 forks source link

Cannot read from Serial Port #1

Closed transparentink closed 8 years ago

transparentink commented 8 years ago

I'm not sure if this is problem related to the recent switch to jSerialComm, something missing in the documentation, or just something locally on my machine.

No matter what I seem to try I end up with:

DEBUG com.ghgande.j2mod.modbus.io.ModbusASCIITransport: Cannot read from serial port

I have tried two different implementations of Modbus Master with the same result. (The examples are below.) In both examples, I end up at ModbusSerialTransport in readAsciiByte() where the call to readBytes from the commPort returns 0. I believe this means that the readBytes call is timing out without reading anything. I have tried increasing the timeout with no luck.

Normally, I would say this is an issue where the slave is not replying. The slave seems to receive the message perfectly fine, and replies. I have also used independent Modbus Master programs to test the communications with the slave is all working.

I'm hoping someone can point at an obvious problem in my code, or point me in a new direction.

private static void testModbusSerialASCIIConnection() {
        try {
            SerialParameters params = new SerialParameters();
            params.setPortName("COM1");
            params.setBaudRate(9600);
            params.setDatabits(8);
            params.setParity(SerialPort.NO_PARITY);
            params.setStopbits(SerialPort.ONE_STOP_BIT);
            params.setEncoding(Modbus.SERIAL_ENCODING_ASCII);
            params.setFlowControlIn(SerialPort.FLOW_CONTROL_DISABLED);
            params.setFlowControlOut(SerialPort.FLOW_CONTROL_DISABLED);
            params.setEcho(false);

            SerialConnection con = new SerialConnection(params);
            con.open();

            ReadCoilsRequest req = new ReadCoilsRequest(1, 40);
            req.setUnitID(20);

            ModbusSerialTransaction trans = new ModbusSerialTransaction(con);
            trans.setRequest(req);

            trans.execute();

            ReadCoilsResponse res = (ReadCoilsResponse) trans.getResponse();

            System.out.println("Digital Inputs Status=" + res.getCoils());

            con.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

And

private static void testModbusSerialASCIIConnection2() {
        try{

        SerialParameters params = new SerialParameters();
        params.setPortName("COM1");
        params.setBaudRate(9600);
        params.setDatabits(8);
        params.setParity(SerialPort.NO_PARITY);
        params.setStopbits(SerialPort.ONE_STOP_BIT);
        params.setEncoding(Modbus.SERIAL_ENCODING_ASCII);
        params.setFlowControlIn(SerialPort.FLOW_CONTROL_DISABLED);
        params.setFlowControlOut(SerialPort.FLOW_CONTROL_DISABLED);
        params.setEcho(false);

        ModbusSerialMaster master = new ModbusSerialMaster(params);
        master.connect();

        //master.setTimeout(10000);

        System.out.println(master.readCoils(20, 1, 8));

        master.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
transparentink commented 8 years ago

I'm not positive, but I may have found part of the problem. I'm no longer certain that the message is being sent correctly.

My log shows the following:

2016-04-14 16:28:37,876 [main] DEBUG com.ghgande.j2mod.modbus.io.ModbusSerialTransport: Wrote FRAME_START 2016-04-14 16:28:41,662 [main] DEBUG com.ghgande.j2mod.modbus.io.ModbusSerialTransport: Wrote byte 20=[49, 52] 2016-04-14 16:28:41,662 [main] DEBUG com.ghgande.j2mod.modbus.io.ModbusASCIITransport: Writing: 14 01 00 01 00 08 2016-04-14 16:28:41,663 [main] DEBUG com.ghgande.j2mod.modbus.io.ModbusSerialTransport: Wrote byte -30=[69, 50] 2016-04-14 16:28:41,664 [main] DEBUG com.ghgande.j2mod.modbus.io.ModbusSerialTransport: Wrote FRAME_END 2016-04-14 16:28:44,866 [main] DEBUG com.ghgande.j2mod.modbus.io.ModbusASCIITransport: Cannot read from serial port

I believe that only the first byte of the buffer is being sent when the call to writeAsciiBytes() is made. This is because when the first value is passed to the writeAsciiByte method the value 20 is converted and results in 2 bytes that are written to the buffer. When that value 2 is returned, the writeAsciiBytes() method stops writing any more bytes.

steveohara commented 8 years ago

You are probably right - as I mentioned in the release notes, the only transport that hasn't been tested is serial ASCII. I've got several RTU slaves to test against but nothing ASCII and despite my requests, nobody has come forward to help out in this regard. Are you happy to do some testing and submit a pull request? If not, I'll take a look at writeAsciiByte and see if there is something obvious and build a snapshot.

transparentink commented 8 years ago

I forked the code and am making progress on the ASCII side. It can now read and write under some circumstances. I've noticed that changing the BitVector size seems to trim bits off the wrong end for some reason. Still more work needed. I will send a pull request when it is working.