Warm tip: This article is reproduced from serverfault.com, please click

java-带有 Spring Boot 项目的 Modbus 脉冲线圈

(java - Modbus Pulse Coils with Spring Boot project)

发布于 2021-02-16 18:21:40

必须在Maven构建的Spring Boot项目使用Modbus 协议实现对Digital IO 的调用

它应该是在身体上有一定持续时间的脉冲呼叫(如 5 秒等)

这是规范中的一个片段:

在此处输入图片说明

以及更多关于响应和错误的信息:

在此处输入图片说明

似乎在这个调用应用程序应该表现得像一个主人。在这种情况下,Web Relay 应该像奴隶一样。

我认为采用一些库来与 Modbus 集成比从零开始编写要好得多。

哪种方法更适合在 Spring Boot 中采用此功能?

这里是Web Relay 手册


更新:

凯文赫伦的尝试答案

这是代码部分:

@Override
public void callDigitalIO(String ipAddress, String relay) {
    log.debug("call Digital IO by MODBUS");
    checkNotEmpty(ipAddress, relay);

    ModbusTcpMasterConfig config = new ModbusTcpMasterConfig.Builder(ipAddress).build();
    ModbusTcpMaster master = new ModbusTcpMaster(config);
    master.connect();

    ByteBuf buffer = Unpooled.buffer();
    buffer.writeInt(0x00003F00);
    buffer.writeInt(0x000040A0);

    int relayNum = Integer.parseInt(relay);
    WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest(
            relayNum,
            0x02 * relayNum,
            buffer
    );

    log.debug("MODBUS_REQUEST: {}", request);

    master.sendRequest(request, 0xFF)
            .whenCompleteAsync((response, ex) -> {
                if (response != null) {
                    log.info("MODBUS_RESPONSE: {}", response);
                } else {
                    log.error("EXECUTION_FAILED: {}", ex.getMessage(), ex);
                }
            });

    master.disconnect();
}

用真实设备尝试了下面的代码片段,输出如下:

2021-02-25 22-07-03.955 [carpark-ex-4] DEBUG c.s.s.dio.ModbusDigitalIoServiceImpl - MODBUS_REQUEST: WriteMultipleRegistersRequest(UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 8, cap: 256))
2021-02-25 22-07-03.970 [ForkJoinPool.commonPool-worker-5] ERROR c.s.s.dio.ModbusDigitalIoServiceImpl - EXECUTION_FAILED: not connected
java.lang.Exception: not connected
    at com.digitalpetri.netty.fsm.ChannelFsmFactory.lambda$null$2(ChannelFsmFactory.java:115)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    at java.base/java.lang.Thread.run(Thread.java:832)

只有当我这样做时:

master.sendRequest(request, 0xFF).get()

它开始工作了。

Questioner
catch23
Viewed
0
Kevin Herron 2021-03-05 08:56:37

使用支持 WriteMultipleRegisters 函数的现有库应该很容易完成。

试试https://github.com/digitalpetri/modbus


如何根据文档截图构建 WriteMultipleRegisters 请求的示例:

class Scratch {

  public static void main(String[] args) throws ExecutionException, InterruptedException {
    ModbusTcpMasterConfig config = new ModbusTcpMasterConfig.Builder("ip_or_hostname").build();
    ModbusTcpMaster master = new ModbusTcpMaster(config);

    master.connect().get();

    ByteBuf buffer = Unpooled.buffer();
    buffer.writeInt(0x00003F00);
    buffer.writeInt(0x000040A0);

    WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest(
        0x16,
        0x04,
        buffer
    );

    master.sendRequest(request, 0xFF).get();
  }

}