IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Java实现Modbus/TCP客户端与modsim通信 -> 正文阅读

[网络协议]Java实现Modbus/TCP客户端与modsim通信

目录

Modbus/TCP简介

使用Java GUI实现的过程


程序实现演示

modsim下载地址:

官网http://www.win-tech.com/html/demos.htm百度网盘(提取码:0x18)http://xn--https-bl8js66z7n7i//pan.baidu.com/s/1W0gS5kOm-X3Fdy7iYQg0cg%20%20%E6%8F%90%E5%8F%96%E7%A0%81%EF%BC%9A

Modbus/TCP简介

????????Modbus/TCP是Modbus的TCP网络协议,TCP网络端口号为502。Modbus/TCP在原有ModBus协议前增加了6个字节的协议头,同时取消了Modbus协议的CRC16校验和。其帧格式如下?

Modbus/TCP协议帧格式
事务标识符协议标识符Modbus信文长度从站地址功能码数据
2字节2字节2字节1字节1字节0-248字节

使用Java GUI实现的过程

? ? ? ? 这里使用JLibMosbus(JLibModbus下载地址)实现,JLibModbus是Modbus的一个实现,该库包含了ModBus/TCP协议的接口和类等,编写通信程序时可以直接调用。另外该库还封装了流行的通信库(如jSerialComm、RXTXcomm等),编写Modbus串口通信(RTU)时也可使用该库。

? ? ? ? 编写Modbus/TCP通信程序的基本步骤如下:(1)设置TCP参数(使用TcpParameters),可以是本机(127.0.0.1),也可以时远端机,将参数配置为远端机的IP即可;(2)设置TCP端口号为默认端口号(502);(3)创建主机,即Modbus协议中提到的主站,与从站实现通信;(4)建立连接,进行数据的读写。

GUI实现

? ? ? ? 使用swing组件(JButton,JLabel,JTextFiled)来创建界面,创建好的界面如下图:

?实现部分代码:

        //按钮
        JButton[] btn = new JButton[4];
        btn[0] = new JButton("连接");
        btn[1] = new JButton("断开");
        btn[2] = new JButton("采集数据");
        btn[3] = new JButton("更改数据");
        btn[0].setBounds(150, 30, 100, 30);
        btn[1].setBounds(350, 30, 100, 30);
        btn[2].setBounds(130, 190, 120, 30);
        btn[3].setBounds(130, 300, 120, 30);

        //静态标签
        JLabel[] jl = new JLabel[6];
        jl[0] = new JLabel("寄存器地址:");
        jl[0].setBounds(100, 145, 100, 30);
        jl[1] = new JLabel("更改寄存器的地址:");
        jl[1].setBounds(50, 255, 160, 30);
        jl[2] = new JLabel("采集到的数据:");
        jl[2].setBounds(270, 190, 120, 30);
        jl[3] = new JLabel("更改后的值为:");
        jl[3].setBounds(270, 300, 120, 30);
        jl[4] = new JLabel("连接状态:");
        jl[4].setBounds(200, 100, 80, 30);
        jl[5] = new JLabel("未连接");
        jl[5].setForeground(Color.RED);
        Font f = new Font("宋体",Font.ITALIC,16);
        jl[5].setFont(f);
        jl[5].setBounds(280, 100, 100, 30);

        //编辑框
        JTextField[] jtf = new JTextField[4];
        jtf[0] = new JTextField("**");
        jtf[1] = new JTextField("**");
        jtf[2] = new JTextField("**");
        jtf[3] = new JTextField("**");
        jtf[0].setBounds(200, 150, 80, 20);//寄存器地址
        jtf[1].setBounds(390, 195, 80, 20);//采集到的数据
        jtf[2].setBounds(200, 260, 80, 20);//更改寄存器的地址
        jtf[3].setBounds(390, 305, 80, 20);//更改后的值

        JFrame jf = new JFrame();
        jf.setTitle("ModbusTCP_Test");
        jf.setLocation(200, 100);
        jf.setSize(600, 400);
        jf.getContentPane().setBackground(Color.PINK);
        jf.setLayout(null);
        jf.setVisible(true);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        Font f1 = new Font("宋体",Font.BOLD,16);
        for (JButton jButton : btn) {
            jf.add(jButton);
            jButton.setFont(f1);
        }
        for (JTextField jTextField : jtf) {
            jf.add(jTextField);
            jTextField.setFont(f1);
        }
        for (int i=0;i< jl.length;i++) {
            jf.add(jl[i]);
            if (i!=5){
                jl[i].setFont(f1);
            }
        }

通信部分实现

? ? ? ? 该部分主要就是给各个按钮添加监听事件(这里使用lambda表达式),当按钮点击时,通过一定的逻辑原理对modSim进行数据的读写操作。

代码实现:

        //设置TCP参数
        TcpParameters tcpParameters = new TcpParameters();
        InetAddress ipAddress = InetAddress.getByName("127.0.0.1");
        tcpParameters.setHost(ipAddress);
        //设置连接和端口
        tcpParameters.setKeepAlive(true);
        tcpParameters.setPort(Modbus.TCP_PORT);//使用TCP默认端口502
        // 创建主机
        ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
        Modbus.setAutoIncrementTransactionId(true);
        //初始化为未连接
        master.disconnect();
        int slaveId = 1;//设置从机地址默认为1

        btn[0].addActionListener(a -> {
            if (a.getActionCommand().equals("连接")) {
                if (!master.isConnected()) {
                    try {
                        master.connect();//开启连接
                        jl[5].setText("已连接");
                        jl[5].setForeground(Color.BLUE);
                        JOptionPane.showMessageDialog(null,
                                "连接成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        btn[1].addActionListener(a -> {
            if (a.getActionCommand().equals("断开")) {
                try {
                    master.disconnect();
                    jl[5].setText("未连接");
                    jl[5].setForeground(Color.RED);
                    JOptionPane.showMessageDialog(null,
                            "断开连接成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        btn[2].addActionListener(a -> {
            if (a.getActionCommand().equals("采集数据") && master.isConnected()) {
                //获取编辑框中的数据
                String readAddress = jtf[0].getText();
                int r_address = Integer.parseInt(readAddress);//寄存器读取开始地址,转换为int型
                int quantity = 1;//读取的寄存器数量
                try {
                    //读取对应从机的数据,readInputRegisters
                    int[] registerValues = master.readHoldingRegisters(slaveId, r_address-1, quantity);
                    //显示在指定组件
                    for (int value : registerValues) {
                        jtf[1].setText(String.valueOf(value));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                JOptionPane.showMessageDialog(null, "数据采集成功!",
                        "提示", JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(null, "请先进行连接!",
                        "提示", JOptionPane.ERROR_MESSAGE);
            }
        });

        btn[3].addActionListener(a -> {
            if (a.getActionCommand().equals("更改数据") && master.isConnected()) {
                String writeAddress = String.valueOf(jtf[2].getText());
                int w_address = Integer.parseInt(writeAddress);
                int w_data = Integer.parseInt(jtf[3].getText());
                try {
                    master.writeSingleRegister(slaveId, w_address-1, w_data);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                JOptionPane.showMessageDialog(null, "请先进行连接!",
                        "提示", JOptionPane.ERROR_MESSAGE);
            }
        });

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 23:19:41  更:2022-07-04 23:19:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 20:27:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计