java 使用 Jamod 写入 modbus

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1840913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 18:13:12  来源:igfitidea点击:

Writing to modbus with Jamod

javamodbus

提问by Ahe

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

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

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

但是尝试写类似的方式失败了(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);
}

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.

是的,我知道我使用的是请求对象的多寄存器版本,但我使用的设备仅支持功能代码 3 和 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.

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

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?

有没有人有使用 jamod 的经验,那个人会不会告诉我我做错了什么?这发生在 1.1 和 1.2rc1 版本的 jamod 上。或者这可能是某些特定于供应商的情况?

采纳答案by Ahe

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

最后我写了我自己的 modbus 实现。我只需要支持2种不同的功能代码,所以实现很简单。

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

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

回答by DH28

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

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

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

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

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

回答by David

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

回答by jomazz

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!

再见!

回答by Nestor Palomeque

I have encountered this problem on Android.

我在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.

由于此任务在等待来自外部设备的响应时可能需要花费大量时间,因此我找到的解决方案是在另一个线程中执行写入和读取。