【问题标题】:Modbus TCP in Java / AndroidJava / Android 中的 Modbus TCP
【发布时间】:2015-04-14 21:36:56
【问题描述】:

我正在研究 Java 中的 modbus TCP 实现。到目前为止,我已经尝试了 3 个不同的库 modbus4j、jamod 和 j2mod。我可以使用 linux modpoll 工具成功访问我的从设备:http://www.modbusdriver.com/modpoll.html

michael@michael-G75VW:~/Documents/modbus-test-tool/linux$ ./modpoll -a255 -r1 -1        192.168.1.101
modpoll 3.4 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2013 proconX Pty Ltd
Visit http://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: MODBUS/TCP
Slave configuration...: address = 255, start reference = 1, count = 1
Communication.........: 192.168.1.101, port 502, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave...
[1]: 256

这会导致我设备上的屏障上升,这很棒。但是,在 Java 实现中工作我无法重现这一点。我尝试了许多不同的步骤,但都失败了。在 J2mod/jamod 中,我在使用“255”时不断收到无效的 slaveId 错误,这是我在上述命令中使用的单元 ID。如果我使用其他任何东西,我会收到一个 CRC failed 错误。在 mod4j 中,我收到各种错误,包括错误代码 = 4。这是我最新的 J2mod 代码,它返回 CRC 错误(如果不是 255)或无效的 slaveId。我知道 slaveId 主要用于串行通信,但我的设备在使用其他应用程序时仅响应 Unit ID 255。

Integer value = Integer.decode(val).intValue();
    Integer unitID = Integer.decode(uid).intValue();
    Integer length = Integer.decode(len).intValue();
    Integer ref = Integer.decode(reference).intValue();
    SimpleRegister MyReg = new SimpleRegister(value);
    try {
        InetAddress address;
        address = InetAddress.getByName(addr);
        //2. Open the connection
        TCPMasterConnection con = new TCPMasterConnection(address);
        con.setPort(port);
        con.connect();
        //3. Prepare the requestWrite
        WriteSingleRegisterRequest WriteReq = new WriteSingleRegisterRequest(ref,MyReg);
        WriteReq.setDataLength(length);
        WriteReq.setUnitID(unitID);
        //4. Prepare the transaction
        ModbusTCPTransaction trans = new ModbusTCPTransaction(con);
        trans.setRequest(WriteReq);  
        trans.setRetries(0);
        trans.execute();
        Log.d(TAG, "Complete: " +trans.toString());
        return trans.getResponse().getHexMessage();
    } catch (UnknownHostException e) {
        Log.d(TAG, "UnknownHostException: " + e.getMessage());
        return e.getMessage();
    } catch (Exception e) {
        Log.d(TAG,"Exception: " + e.toString());
        return e.getMessage();
    }

我的 modbus 接口手册可以在这里找到: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCsQFjAA&url=http%3A%2F%2Fwww.ac-magnetic.com%2Fgermany%2Fsites%2Fdefault%2Ffiles%2F58150001EN_00_Technical%2520Maunal%2520EM01.pdf&ei=Z1dxUv7qF4a9yAGpooHYBQ&usg=AFQjCNGGZnBx_A0fFjuW3qqgWjhS_ek-0w&bvm=bv.55617003,d.aWc

【问题讨论】:

  • ID 255 通常不是广播ID吗?您可以尝试将奴隶重新寻址为其他内容,例如 1 吗?实际上,我从未见过有人使用 255 作为 Modbus 从地址。不知道这是否会有所帮助,但您的库中可能有些内容不喜欢“255”。
  • 不,单元 0 是广播地址,但 Modbus/TCP PLC 除外,它通常使用单元 0 进行所有通信。唯一的(一般...)例外情况是当 PLC 通过网桥连接时,网桥会在 TCP/IP 连接端和其他传输端之间编组 PDU。

标签: java tcp modbus


【解决方案1】:

我无法确切说明为什么会发生这种情况。我可以告诉你,jamod 和 j2mod(j2mod 是 jamod 的一个已修复错误的分支)都只是将你设置为单元号的任何内容复制到 TCP 数据包的第 7 个字节。然后由 PLC 来响应发送的数据包。

对于 j2mod,从 JVM 命令行将系统属性 com.ghgande.modbus.debug 设置为“true”将启用调试消息。这将允许您查看应该告诉您发生了什么的数据包转储。

您确实做了一个非常有趣的评论,那就是您看到了 CRC 错误。你知道 Modbus/TCP 根本不使用 CRC 吗?

【讨论】:

    猜你喜欢
    • 2019-11-27
    • 2020-12-01
    • 2015-04-07
    • 2014-06-07
    • 2017-10-31
    • 2016-09-06
    • 2020-06-10
    • 2019-05-14
    • 2022-08-16
    相关资源
    最近更新 更多