`
sunxboy
  • 浏览: 2871112 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Java应用程序的MODBUS通讯

 
阅读更多

实验目的

JAVA应用程序通过MODBUS协议RTU模式读写设备

 

实验器材

西门子 s7-200 226cn PLC 的CPU一台;s7-200 编程电缆一条,这条电缆亦充当MODBUS的串行口上的连接线。编程电缆是USB接口的,由于此编程电缆的驱动程序安装后即模拟了一个虚拟的串行口COM3,因此可以借助此电缆充当实际的物理连接线路

 

开发环境

Jdk1.6 update 25; STEP 7-MicroWIN 4.0;西门子S7-200的MODBUS库

 

实验目标

读PLC的输入过程映像寄存器;写PLC的V存储区

 

JAVA应用程序第三方开发包下载页面 http://sourceforge.net/projects/modbus4j/files/modbus4j/

 

Java串行口编程开发包 RXTXcomm.jar

 

环境搭建

PLC充当从站,占用通讯口port0;JAVA应用程序充当主站,发起读写的请求并等待PLC的响应。示例程序里写十六进制数值31(即二进制 00110001)到保持寄存器上,

PLC的Q1显示的结果是:

Q1.0 亮

Q1.1 灭

Q1.2 灭

Q1.3 灭

Q1.4 亮

Q1.5 亮

Q1.6 灭

Q1.7 灭

 

PLC从站的编程目标:MODBUS协议上的保持寄存器里的一个字节输出到Q,以便通过PLC上的指示灯观察。

 

PLC上的梯形图



 

说明:

IB0上的值决定是否启用MODBUS

通讯波特率9600

从站地址是5

I和Q的最大访问个数是128

模拟量输入最大访问个数是32

保持寄存器可访问1000个字

VB1上的字节输出到Q1.0 ... Q1.7

 

 

 

JAVA应用程序

import com.serotonin.io.serial.*;

import com.serotonin.modbus4j.*;

import com.serotonin.modbus4j.exception.*;

import com.serotonin.modbus4j.msg.*;

import java.util.*;

final class HardneedlTest {

    //MODBUS网络上从站地址

    private final static int SLAVE_ADDRESS=5;

 

    //串行口波特率

    private final static int BAUD_RATE = 9600;

    

    public static void main(String[] args) throws Exception {

        SerialParameters serialParameters = new SerialParameters();

 

        //设定MODBUS通讯的串行口

        serialParameters.setCommPortId("COM3");

 

        //设定成无奇偶校验

        serialParameters.setParity(0);

 

        //设定成数据位是8位

        serialParameters.setDataBits(8);

 

        //设定为1个停止位

        serialParameters.setStopBits(1);

 

        serialParameters.setPortOwnerName("Numb nuts");

 

        //串行口上的波特率

        serialParameters.setBaudRate(BAUD_RATE);

 

        ModbusFactory modbusFactory = new ModbusFactory();

        ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);

        try {

            master.init();

            readDiscreteInputTest(master,SLAVE_ADDRESS,0,8);

            writeRegistersTest(master,SLAVE_ADDRESS, 0, new short[]{0x31,0xb,0xc,0xd,0xe,0x9, 0x8, 0x7, 0x6} );

            readHoldingRegistersTest(master,SLAVE_ADDRESS,0,8);

        }

        finally {

            master.destroy();

        }

    }

 

    /**

     * 读开关量型的输入信号

     * @param master 主站

     * @param slaveId 从站地址

     * @param start 起始偏移量

     * @param len 待读的开关量的个数

     */

    private static void readDiscreteInputTest(ModbusMaster master, int slaveId, int start, int len) {

        try {

            ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, start, len);

            ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);

 

            if (response.isException())

                System.out.println("Exception response: message=" + response.getExceptionMessage());

            else

                System.out.println(Arrays.toString(response.getBooleanData()));

        }

        catch (ModbusTransportException e) {

            e.printStackTrace();

        }

    }

 

    /**

     * 读保持寄存器上的内容

     * @param master 主站

     * @param slaveId 从站地址

     * @param start 起始地址的偏移量

     * @param len 待读寄存器的个数

     */

    private static void readHoldingRegistersTest(ModbusMaster master, int slaveId, int start, int len) {

        try {

            ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, start, len);

            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);

 

            if (response.isException())

                System.out.println("Exception response: message=" + response.getExceptionMessage());

            else

                System.out.println(Arrays.toString(response.getShortData()));

        }

        catch (ModbusTransportException e) {

            e.printStackTrace();

        }

    }

 

    /**

     * 批量写数据到保持寄存器

     * @param master 主站

     * @param slaveId 从站地址

     * @param start 起始地址的偏移量

     * @param values 待写数据

     */

    public static void writeRegistersTest(ModbusMaster master, int slaveId, int start, short[] values) {

        try {

            WriteRegistersRequest request = new WriteRegistersRequest(slaveId, start, values);

            WriteRegistersResponse response = (WriteRegistersResponse) master.send(request);

 

            if (response.isException())

                System.out.println("Exception response: message=" + response.getExceptionMessage());

            else

                System.out.println("Success");

        }

        catch (ModbusTransportException e) {

            e.printStackTrace();

        }

    }

}

分享到:
评论
5 楼 abababudei 2016-05-06  
请教一下,这个您是怎么解决的:
/dev/ttyS2
entering RXTXPort:testRead
RXTX Warning:  Removing stale lock file. /data/local/tmp/LCK..ttyS2
Unable to remove stale lock file: /data/local/tmp/LCK..ttyS2
leaving RXTXPort:testRead no lock
...
com.serotonin.io.serial.SerialPortException: gnu.io.NoSuchPortException
com.serotonin.modbus4j.exception.ModbusInitException: com.serotonin.io.serial.SerialPortException: gnu.io.NoSuchPortException
com.serotonin.modbus4j.serial.SerialMaster.init(SerialMaster.java:31)
at com.serotonin.modbus4j.serial.rtu.RtuMaster.init(RtuMaster.java:23)
at com.example.modbus.SerialUtils.init(SerialUtils.java:44)
...
当android板块插上USB调试线就重启APK就可以正常读取这个串口
总共出现了这三种情况:
RXTX Error:  Unable to remove stale lock file: /data/local/tmp/LCK..ttyS2
RXTX fhs_lock() Error: creating lock file: /data/local/tmp/LCK..ttyS2: File exists
RXTX Warning:  Removing stale lock file. /data/local/tmp/LCK..ttyS2
4 楼 sunxboy 2014-11-15  
u011033959 写道
我想请教一下,我打算用该代码实现与ModbusSlave模拟器之间的通信,运行出现下面错误:
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
Exception in thread "main" java.lang.NullPointerException
at modbus1.HardneedlTest.readDiscreteInputTest(HardneedlTest.java:50)
at modbus1.HardneedlTest.main(HardneedlTest.java:31)
我该如何解决?


你这是modbus serial 通讯。
首先,你的rxtx 包正确的放到 jdk 路径去了么 ?
其次,能不能将通讯部分的代码贴上来,这样方便找问题,你这空指针异常很常见,看不出什么问题
3 楼 u011033959 2014-11-01  
我想请教一下,我打算用该代码实现与ModbusSlave模拟器之间的通信,运行出现下面错误:
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
Exception in thread "main" java.lang.NullPointerException
at modbus1.HardneedlTest.readDiscreteInputTest(HardneedlTest.java:50)
at modbus1.HardneedlTest.main(HardneedlTest.java:31)
我该如何解决?
2 楼 sunxboy 2013-10-24  
类似的错误我遇到时,你可以尝试从以下几个方面着手:
1.设备的死机导致的通信故障
使用Modbus仿真工具可以无视这个问题

2.构造request时,设置的count大小不合理。具体大小根据实际情况调整。
值过小时也会报类似问题。

3.多线程环境下,多个线程同时通讯时,同步没有处理好,也会报类似问题。
1 楼 chenqiang_99 2013-10-21  
我想请教一下 你有没遇见这个问题
com.serotonin.modbus4j.exception.ModbusTransportException: com.serotonin.messaging.TimeoutException: request=com.serotonin.modbus4j.serial.rtu.RtuMessageRequest@6abf2d5e
at com.serotonin.modbus4j.serial.rtu.RtuMaster.send(RtuMaster.java:57)
at com.serotonin.modbus.readHoldingRegistersTest(modbus.java:64)
at com.serotonin.modbus.main(modbus.java:38)

相关推荐

    java实现MODBUS通讯

    ### 使用Java实现MODBUS通讯的关键知识点 #### MODBUS协议简介 MODBUS协议是MODICON公司为其控制器设计的一种工业通信协议,被广泛应用于自动化控制领域,得到了包括SIEMENS、GE、Honeywell在内的多家厂商的支持。...

    基于Java的Modbus通讯

    在IT行业中,Modbus是一种广泛使用的通信...通过理解Modbus协议和使用Java库,我们可以创建能够与各种Modbus设备交互的应用程序。对于开发工业自动化系统或集成现有设备的IT专业人士来说,这是一个非常有价值的技能。

    java与modbus通讯交互

    以下是一个简单的Java程序,使用`modbus4j`库实现与Modbus设备的TCP连接,读取设备传感器数据的步骤: 1. 引入依赖库: ```java import org.modbus4j.*; import org.modbus4j.transport.*; import org.modbus4j.ip....

    使用JAVA实现MODBUS协议通信

    本文总结了使用JAVA语言实现MODBUS协议通信的技术,涵盖了MODBUS协议的概述、JAVA语言的特点、MODBUS协议的实现、通信程序的设计等方面。 MODBUS协议是由MODICON公司为其控制器设计的一种工业控制系统通信协议,...

    基于JAVA实现的Modbus通讯模块在温测系统中的应用.pdf

    根据给定文件信息,本文将详细阐述“基于JAVA实现的Modbus通讯模块在温测系统中的应用”所涉及的关键知识点。 首先,“Modbus通讯模块”是一个在工业自动化领域中常用到的通信协议实现方式。Modbus协议是由Modicon...

    java 通过modbus rtu协议,tcp 协议 通讯源码

    Java编程语言在工业自动化和设备通信领域中广泛应用于实现Modbus通信协议,这是一种标准化的通信协议,用于设备间的数据交换。本项目提供了基于Modbus RTU(远程终端单元)和TCP(传输控制协议)的通信源码,适用于...

    基于java的modbus TCP通信

    Modbus 协议是一项应用层报文传输协议,它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信,包括 ASCII、RTU、TCP 三种报文类型。 Modbus TCP 数据帧由 MBAP 和 PDU 两部分组成。MBAP 是报文头,长度为...

    modbus rtu通讯

    Modbus RTU通讯是一种广泛应用的工业通信协议,它允许设备之间进行数据交换,尤其是在自动化系统中。这个协议基于串行连接,使用RTU(Remote Terminal Unit)数据格式,以实现简单、高效的数据传输。 在Modbus RTU...

    modbus通讯测试程序

    Modbus通讯测试程序是用于验证和调试基于Modbus通信协议的设备或系统的重要工具。Modbus是一种广泛应用的工业通信协议,最初由Modicon公司(现为Schneider Electric的一部分)开发,现已成为工业自动化领域的标准...

    modbus的读写java实现

    ### Modbus的读写Java实现 #### 一、概述 Modbus是一种广泛应用于电子控制器之间进行数据交换的通信协议标准,常用于工业自动化系统中。它支持多种物理层传输模式,如RS-232、RS-485以及TCP/IP网络等。本文将详细...

    JAVA写的利用ModbusTCP协议控制现场设备

    3. **Java实现**: 在这个项目中,开发者使用Java编程语言实现了ModbusTCP协议的客户端部分,允许程序通过TCP连接与支持Modbus协议的设备进行交互。Java的选择是因为它具有跨平台性、丰富的库支持以及强大的网络编程...

    modbus-rtu解析Java相关所需资源

    这些模拟器可以模拟Modbus从站,使你能在不实际连接设备的情况下测试你的Java程序。 8. **多线程考虑**:在并发环境中,可能需要使用多线程来处理多个Modbus连接。确保同步和线程安全,避免数据竞争和其他并发问题...

    基于JAVA实现的Modbus通讯模块在温测系统中的应用.zip

    标题中的“基于JAVA实现的Modbus通讯模块在温测系统中的应用”揭示了这个主题主要涉及两个关键领域:Java编程语言和Modbus通信协议在温度测量系统中的应用。以下是这两个核心概念的详细解释: 1. **Java编程语言**...

    java与plc通讯示例代码

    Modbus4J是一个Java库,它允许Java应用程序通过Modbus与各种设备进行交互,包括PLC。 Modbus是一种串行通信协议,最早由Schneider Electric开发,现在已经成为工业电子设备之间通信的事实标准。它基于主从架构,...

    JAVA程序与PLC通信——学习使用

    本篇将详细探讨"JAVA程序与PLC通信——学习使用"这一主题,包括如何使用Java实现与西门子PLC的串口通信,以及如何收发数据。 首先,我们要理解Java语言的优势。Java作为一种跨平台的编程语言,其强大的网络支持和...

    JAVA usb串口通讯

    通过学习和掌握这些知识,开发者可以构建出能够连接和控制各种串口设备的Java应用程序,从而在工业自动化、远程监控等场景下发挥重要作用。同时,随着物联网的发展,Java USB串口通讯的应用范围也将进一步扩大。

    java、钉钉、微信小程序、APP采集modbus协义的PLC数据

    这个例子是java采集modbus协义数据, 可以实现数据同步图表显示,并且可以写入数据, 以上全开源,一看就知道,请放心下载,已经使用在生产上 实现发布webservice、resful接口提供给第三方使用 有了数据后,自己...

Global site tag (gtag.js) - Google Analytics