4

我在使用 jamod 写入 modbus 时遇到了一个奇怪的情况。以下阅读代码完美运行:

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();
}

但是尝试以类似的方式编写失败(Jamod 尝试了 3 次,每次都遇到 SocketTimeoutException,最后抛出 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);
}

是的,我知道我正在使用请求对象的多寄存器版本,但我正在使用的设备仅支持功能代码 3 和 16。

我还编写了原始套接字测试器来编写寄存器,据我所知,它可以正常工作。但是在这两种情况下都使用 jamod 会很好。

有没有人有使用 jamod 的经验,那个人会好心地告诉我我做错了什么吗?1.1 和 1.2rc1 版本的 jamod 都会出现这种情况。或者这可能是一些特定于供应商的情况?

4

5 回答 5

2

默认情况下,Modbus 请求的单元 id = 0。所以必须将任何其他 id 设置为请求,例如:

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

浪费了几个小时试图解决您在问题中描述的相同问题。

于 2017-05-16T07:46:04.827 回答
1

最后,我编写了自己的 modbus 实现。我只需要支持2个不同的功能码,实现起来很简单。

虽然后来我找到了另一个开源的 java 的 modbus 库。我其他人使用modbus4j遇到同样的问题可能会有所帮助。

于 2010-03-23T10:22:03.807 回答
0

我根据您的问题编写的方法有效!

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();
        }
于 2013-11-20T15:10:28.910 回答
0

我有一个类似的问题,我试图在“设备作业”中定义为线圈寄存器的寄存器中写入一个值。所以我用:

WriteCoilRequest coil_req = new WriteCoilRequest(registerReference,value2write)

这解决了问题。也许这有帮助。

再见!

于 2015-02-11T15:29:47.840 回答
0

我在Android上遇到过这个问题。

因为这个任务在等待来自外部设备的响应时可能需要一些很长的时间,所以我找到的解决方案是在另一个线程中执行写入和读取。

于 2017-06-19T10:53:01.260 回答