Java实现从PLC读取数据的常见主流且可行方案
这是一个非常经典且常见的工业物联网(IIoT)或自动化集成需求。
要从PLC读取数据,Java本身并不直接支持PLC的通信协议,所以你需要借助一些中间件或库来实现。
核心思路:PLC通常使用工业以太网协议(如Modbus TCP、S7协议、OPC UA等)进行通信。Java需要通过特定的库来“说”这些协议。
以下是几种主流且可行的方案,按推荐程度和应用场景排序
方案一:使用 Modbus TCP 协议(最常见、跨平台性好)
如果PLC支持Modbus TCP协议(西门子、三菱、施耐德等很多品牌都支持,或者通过扩展模块支持),这是Java接入最简单的方式。
推荐库: Jamod 或 EasyModbus
步骤示例:
1.引入依赖(以 EasyModbus 为例,Maven):
<dependency>
<groupId>de.re.easymodbus</groupId>
<artifactId>easymodbus4j</artifactId>
<version>1.2.1</version>
</dependency>2.Java 代码示例(读取保持寄存器):
import de.re.easymodbus.modbus.ModbusClient;
public class ReadPLC {
public static void main(String[] args) {
ModbusClient modbusClient = null;
try {
// 1. 创建Modbus客户端,指定PLC的IP和端口(Modbus TCP默认端口为502)
modbusClient = new ModbusClient("192.168.1.100", 502);
// 2. 建立连接
modbusClient.Connect();
// 3. 读取数据(示例:从地址0开始读取3个保持寄存器)
// 函数说明:ReadHoldingRegisters(起始地址, 数量)
int[] registers = modbusClient.ReadHoldingRegisters(0, 3);
// 4. 输出读取到的值
System.out.println("寄存器0的值: " + registers[0]);
System.out.println("寄存器1的值: " + registers[1]);
System.out.println("寄存器2的值: " + registers[2]);
// 写入数据示例(可选)
// modbusClient.WriteSingleRegister(0, 100); // 向地址0写入值100
} catch (Exception e) {
e.printStackTrace();
} finally {
// 5. 关闭连接
if (modbusClient != null && modbusClient.isConnected()) {
modbusClient.Disconnect();
}
}
}
}适用场景: PLC支持Modbus TCP,且需要快速开发、无需太复杂的配置。
方案二:使用西门子 S7 协议(针对西门子PLC)
如果你面对的是西门子S7系列(如S7-1200, S7-1500, S7-200 Smart),它们通常使用专有的S7协议。
推荐库: S7Connector 或 Moka7 (Java移植版)
步骤示例(使用 S7Connector):
1.引入依赖(Github项目,需手动导入Jar或通过Jitpack集成)。
2.代码示例:
// 以开源库 S7Connector 为例
import pl.com.s7p.s7connector.*;
public class SiemensS7Reader {
public static void main(String[] args) {
S7Connection connection = new S7Connection();
try {
// 1. 连接到PLC (IP地址, 机架号0, 插槽号1 通常用于S7-1200/1500)
// 对于S7-200,机架和插槽通常是0/0或0/1,需查阅PLC配置
connection.ConnectTo("192.168.1.10", 0, 1);
// 2. 读取DB块数据 (DB编号, 起始字节, 读取字节长度)
byte[] buffer = connection.ReadArea(S7Area.DB, 1, 0, 10); // 读取DB1,从第0字节开始,读10个字节
// 3. 解析字节数据为Java类型 (需要根据PLC数据类型手动解析)
// 例如,前4个字节是一个浮点数
float value = S7Util.getFloatAt(buffer, 0);
System.out.println("DB1.DBD0 的值为: " + value);
} catch (Exception e) {
e.printStackTrace();
} finally {
connection.Disconnect();
}
}
}适用场景: 项目特定针对西门子PLC,追求更高的执行效率和对S7协议的支持。
方案三:使用 OPC UA(现代工业标准,适合复杂系统)
OPC UA 是工业4.0的核心通信标准,它独立于厂商,安全性高,数据建模能力强。如果你需要对接多种品牌PLC,或者构建一个中大型的MES(制造执行系统),这是最佳选择。
推荐库: Eclipse Milo(纯Java实现,功能强大,官方推荐)
步骤示例(Eclipse Milo 读取节点):
1.引入依赖(Maven):
<dependency>
<groupId>org.eclipse.milo</groupId>
<artifactId>sdk-client</artifactId>
<version>0.6.8</version>
</dependency>2.代码逻辑(简化版):
- 创建OPC UA客户端。
- 配置Endpoint(服务器地址,如
opc.tcp://192.168.1.10:4840)。 - 身份验证(可能需用户名密码或证书)。
- 连接并浏览节点。
- 读取节点的值。
适用场景: 系统集成要求高、需对接多种品牌设备、强调安全性和标准化的大型项目。
方案四:通过中间件/数据库(间接读取)
如果不想处理复杂的协议,或者PLC端已经配置好了向上位机发送数据的功能:
- MQTT(消息队列):PLC端通过网关或自身功能将数据发布到MQTT Broker,Java程序通过Eclipse Paho库订阅主题接收数据。适合物联网云平台场景。
- ODBC/JDBC(数据库):某些工业PC或高端PLC支持将数据实时写入SQL Server、MySQL或Oracle。Java直接通过JDBC去查询这些表即可。注意: 这不适用于大多数小型PLC,通常配合IPC(工控机)使用。
- REST API:一些现代物联网PLC或边缘网关提供HTTP接口,Java可以用OkHttp或HttpClient直接GET数据。
总结与建议
| 你的情况 | 推荐方案 |
|---|---|
| PLC型号未知,但大概率支持Modbus | 方案一 (Modbus TCP) —— 最简单,代码量最少。 |
| 明确知道是西门子 S7-1200/1500 | 方案二 (S7协议) —— 直接与西门子对话,性能好。 |
| 对接多个品牌PLC/大型工厂项目 | 方案三 (OPC UA) —— 使用Eclipse Milo,符合未来趋势。 |
| 不想碰协议,只想拿数据 | 方案四 (MQTT) —— 通过消息队列解耦,更现代化。 |
提示: 开始编码前,务必确认以下几点,否则代码写得再好也连不上:
- PLC的IP地址是否和电脑在同一网段?
- PLC的端口是否开放?(Modbus是502,S7是102,OPC UA通常是4840)
- PLC侧是否开启了允许远程/外部读写的权限?(很多PLC默认禁止外部写入,甚至禁止GET请求)
到此这篇关于Java实现从PLC读取数据的常见主流且可行方案的文章就介绍到这了,更多相关Java PLC读取数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
MyBatis-Plus QueryWrapper及LambdaQueryWrapper的使用详解
这篇文章主要介绍了MyBatis-Plus QueryWrapper及LambdaQueryWrapper的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2022-03-03


最新评论