Question

I came across with a curious situation when using jamod to write to modbus. Following read code works perfectly:

public static void main(String[] args) throws Exception {
   InetAddress address = InetAddress.getByName("host.somewhere");
   TCPMasterConnection connection = new TCPMasterConnection(address);
   connection.setPort(502);
   connection.connect();
   ReadMultipleRegistersRequest request = new ReadMultipleRegistersRequest(0, 1);
   ReadMultipleRegistersResponse response = (ReadMultipleRegistersResponse)
       executeTransaction(connection, request);
}

private static ModbusResponse executeTransaction(TCPMasterConnection connection,
         ModbusRequest request) 
         throws ModbusIOException, ModbusSlaveException, ModbusException {
   ModbusTCPTransaction transaction = new ModbusTCPTransaction(connection);
   transaction.setRequest(request);
   transaction.execute();
   return transaction.getResponse();
}

But trying to write similar manner fails (Jamod tries 3 times, each times encounters SocketTimeoutException and finally throws ModbusException).

public static void main(String[] args) throws Exception {
    final InetAddress address = InetAddress.getByName("host.somewhere");
    final TCPMasterConnection connection = new TCPMasterConnection(address);
    connection.setPort(502);
    connection.connect();
    Register reg = new SimpleRegister(0);
    WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest(0,
        new Register[]{reg});
    executeTransaction(connection, request);
}

Yes, I know that I am using multi-register versions of the request-objects, but device I'm working with only supports function codes 3 and 16.

I also wrote raw-socket tester to write registers, and as far as I can see it works correctly. But it would be nice to use jamod in both situations.

Does anyone have anyone experience using jamod and would that one be kind enough to tell what I'm doing wrong? This happens with both 1.1 and 1.2rc1 versions of jamod. Or is this possibly some vendor-specific situation?

Was it helpful?

Solution

At the end I wrote my own modbus implementation. I only needed to support 2 different function codes, so implementation was simple.

Although I later found another open source modbus library for java. I someone else comes across the same problem using modbus4j might help.

OTHER TIPS

Modbus requests have unit id = 0 by default. So any other id must be set to request, e.g.:

WriteCoilRequest writeCoilRequest = new WriteCoilRequest(ref, bool);
writeCoilRequest.setUnitID(unitid);

Wasted a few hours trying to solve the same problem you described in the question.

My method which i wrote based on your question works!

try {
            ModbusTCPTransaction trans = null; // the transaction

            String refe = "0";// HEX Address
            int ref = Integer.parseInt(refe, 16);// Hex to int
            // int count = 1; // the number Address to read

            ReadMultipleRegistersRequest ainReq = new ReadMultipleRegistersRequest(
                    ref, count);
            ReadMultipleRegistersResponse ainRes = new ReadMultipleRegistersResponse();

            // 3. Start Transaction
            trans = new ModbusTCPTransaction(con);
            trans.setRetries(5);
            trans.setReconnecting(true);
            trans.setRequest(ainReq);

            int k = 0;
            do {
                trans.execute();
                ainRes = (ReadMultipleRegistersResponse) trans.getResponse();
                Register reg = new SimpleRegister(ertekInt);
                WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest(0,
                        new Register[]{reg});
                System.out.println("Állított AOUT:  " + request.getRegisterValue(k));
                lista.add(createPlanet("AOUT",
                        "" + k + "    " + request.getRegisterValue(k)));
                k++;
            } while (k < count);
} catch (ModbusIOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ModbusSlaveException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ModbusException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

I had a similar problem, I was trying to write a value in a register that was defined in the "device job" as a coil register. So I used:

WriteCoilRequest coil_req = new WriteCoilRequest(registerReference,value2write)

and that solved the problem. Maybe this help.

Bye!

I have encountered this problem on Android.

Because this task can take some significant time as it waits for a response from an external device, the solution I found was to execute writing and reading in another thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top