前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【MODBUS】j2mod 数字量输入输出DIDO示例

【MODBUS】j2mod 数字量输入输出DIDO示例

作者头像
帐篷Li-物联网布道师
发布2024-03-20 08:42:17
1010
发布2024-03-20 08:42:17
举报

一、示例介绍

该j2mod示例是一个通过Modbus协议读取输入继电器状态,并根据状态更新输出继电器状态的程序。使用时需要提供设备地址、输入继电器参考编号和输出继电器参考编号作为命令行参数。具体流程如下:

  • 设置参数:解析命令行参数,获取设备地址、输入继电器和输出继电器的参考编号。
  • 打开连接:根据设备地址和端口号,创建TCPMasterConnection对象并连接到设备。
  • 准备请求:创建读取输入继电器状态的ModbusRequest对象和写入输出继电器状态的WriteCoilRequest对象,并设置其参考编号和单元ID。
  • 准备事务:创建ModbusTCPTransaction对象,并将其与请求对象关联,设置为非重连模式。
  • 保存上次状态:声明一个用于保存输出继电器上次状态的变量。
  • 循环执行:反复执行以下步骤:读取输入继电器状态,如果状态与上次输出继电器状态不同,则更新输出继电器状态并保存新的状态。
  • 关闭连接:在程序结束时关闭与设备的连接。

注意:该程序使用了Modbus协议和TCP连接来与设备进行通信,并使用了j2mod库提供的类来处理Modbus请求和响应。

二、示例代码

代码语言:javascript
复制
package com.ghgande.j2mod.modbus.cmd;

import com.ghgande.j2mod.modbus.Modbus;
import com.ghgande.j2mod.modbus.io.ModbusTCPTransaction;
import com.ghgande.j2mod.modbus.msg.ModbusRequest;
import com.ghgande.j2mod.modbus.msg.ReadInputDiscretesRequest;
import com.ghgande.j2mod.modbus.msg.ReadInputDiscretesResponse;
import com.ghgande.j2mod.modbus.msg.WriteCoilRequest;
import com.ghgande.j2mod.modbus.net.TCPMasterConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;

/**
 * DIDOExample 类用于演示通过 Modbus 协议读取输入离散量(DI)并根据其状态更新输出离散量(DO)。
 * 需要提供设备地址、输入离散量寄存器参考号和输出离散量寄存器参考号作为命令行参数。
 */
public class DIDOExample {

    private static final Logger logger = LoggerFactory.getLogger(DIDOExample.class); // 日志记录器

    /**
     * 主函数入口。
     * @param args 命令行参数:设备地址、输入离散量寄存器参考号、输出离散量寄存器参考号。
     */
    public static void main(String[] args) {

        InetAddress addr = null; // 设备地址
        TCPMasterConnection con = null; // Modbus 主连接
        ModbusRequest di_req; // 读取输入离散量的请求
        WriteCoilRequest do_req; // 写入输出离散量的请求

        ModbusTCPTransaction di_trans; // 读取输入离散量的事务
        ModbusTCPTransaction do_trans; // 写入输出离散量的事务

        int di_ref = 0; // 输入离散量寄存器参考号
        int do_ref = 0; // 输出离散量寄存器参考号
        int port = Modbus.DEFAULT_PORT; // 端口号

        try {

            // 设置运行参数
            if (args.length < 3) {
                printUsage();
                System.exit(1);
            }
            else {
                try {
                    String astr = args[0];
                    int idx = astr.indexOf(':');
                    if (idx > 0) {
                        port = Integer.parseInt(astr.substring(idx + 1));
                        astr = astr.substring(0, idx);
                    }
                    addr = InetAddress.getByName(astr);
                    di_ref = Integer.parseInt(args[1]);
                    do_ref = Integer.parseInt(args[2]);
                }
                catch (Exception ex) {
                    ex.printStackTrace();
                    printUsage();
                    System.exit(1);
                }
            }

            // 打开连接
            con = new TCPMasterConnection(addr);
            con.setPort(port);
            con.connect();
            System.out.printf("Connected to %s:%d", addr.toString(), con.getPort());

            // 准备请求
            di_req = new ReadInputDiscretesRequest(di_ref, 1);

            do_req = new WriteCoilRequest();
            do_req.setReference(do_ref);

            di_req.setUnitID(0);
            do_req.setUnitID(0);

            // 准备事务
            di_trans = new ModbusTCPTransaction(con);
            di_trans.setRequest(di_req);
            di_trans.setReconnecting(false);
            do_trans = new ModbusTCPTransaction(con);
            do_trans.setRequest(do_req);
            do_trans.setReconnecting(false);

            // 上一状态 holders
            boolean last_out = false; // 上一输出状态
            boolean new_in; // 新输入状态

            // 循环执行事务,持续读取并更新输出状态
            do {
                di_trans.execute();
                new_in = ((ReadInputDiscretesResponse)
                        di_trans.getResponse()).getDiscreteStatus(0);

                // 只有状态改变时才写入新的输出状态
                if (new_in != last_out) {
                    do_req.setCoil(new_in);
                    do_trans.execute();
                    last_out = new_in;
                    System.out.printf("Updated coil with state from DI");
                }
            } while (true);

        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        finally {

            // 关闭连接
            if (con != null) {
                con.close();
            }

        }
    }

    /**
     * 打印用法信息。
     */
    private static void printUsage() {
        System.out.printf("\nUsage:\n    java com.ghgande.j2mod.modbus.cmd.DIDOExample <address{:<port>} [String]> <register d_in [int16]> <register d_out [int16]>");
    }
}
2.1 关键代码
代码语言:javascript
复制
// 循环执行事务,持续读取并更新输出状态
do {
    di_trans.execute();
    new_in = ((ReadInputDiscretesResponse)
            di_trans.getResponse()).getDiscreteStatus(0);

    // 只有状态改变时才写入新的输出状态
    if (new_in != last_out) {
        do_req.setCoil(new_in);
        do_trans.execute();
        last_out = new_in;
        System.out.printf("Updated coil with state from DI");
    }
} while (true);

三、代码总结

该示例实现了一个简单的命令行工具,该工具演示了如何将数字输入与数字输出绑定。

注意!!!,如果您使用Modbus协议栈向远程I/O进行写入,则很可能会在第一次写入消息后保持通信有效。这可以通过发送任何类型的消息来实现,也可以通过在给定的时间段内重复写入消息来实现。

如果超过该时间段,则设备可能会通过输出I/O模块的所有信号来做出反应。在此超时之后,设备可能需要一条重置消息。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、示例介绍
  • 二、示例代码
    • 2.1 关键代码
    • 三、代码总结
    相关产品与服务
    命令行工具
    腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档