前言
最近一段时间到一个工厂跟人去学习调试 PLC 设备,其中有个场景就是手拿遥控器人工进行库位标定并写入数据库。这个工作本身可以通过边拿电脑边去标定库位但是不太安全也不太方便,因为在工厂里面你的头顶上面还随时都有一个起重机在工作,库位之间的间隙也比较小。这个时候我就产生了一个想法就是通过手机来进行库位标定,这篇文章就是来说明如何让手机通过局域网与 PLC 进行通信的方案。
前提
- PLC 具有 S7 通讯能力
- PLC、手机、上位机在同一网段
方案设计
PLC 和 手机共同连接上位机的网络,那么两者就可以通过各自的协议来进行通信,本质上都是通过 TCP/IP 的方式。
软件
- TIA Portal V16:博图软件
- S7-PLCSIM V16:仿真器
- S7-PLCSIM Advanced V3.0:仿真高级配置
- WinPcap:https://www.winpcap.org/install/default.htm
视频教程
因为我不太熟悉博图软件,所以找了一个相关视频看了看,确实解决了我遇到的一些问题。如果有遇到什么问题可以在评论区提问,看见了就会回答。
如果你连接不上 PLC,可以尝试把电脑的 WIFI 连接关掉,采用以太网 IP 地址进行配置。
PLC 代码
当 “DB_S7”.bool01 为 FALSE 时,程序段 2 中移位器 MOVE 将 100 赋值给 “DB_S7”.int01;
当 “DB_S7”.bool01 为 TRUE 时,程序段 1 中移位器 MOVE 将 10 赋值给 “DB_S7”.int01。
%DB1.DBX0.0 为 “DB_S7”.bool01 变量的地址区,在 Java 中 % 不用加就可以访问和修改 “DB_S7”.bool01 的值。
%DB1.DBW2 为 “DB_S7”.int01 变量的地址区,在 Java 中 % 不用加就可以访问和修改 “DB_S7”.int01 的值。
服务器代码
依赖项
pom.xml
<dependency>
<groupId>com.github.dathlin</groupId>
<artifactId>HslCommunication</artifactId>
<version>3.1.1</version>
</dependency>
默认情况 “DB_S7”.bool01 为 FALSE,即程序段2会将 100 赋值给 “DB_S7”.int01,因此当访问http://192.168.2.153:8000/plcConnect 时 “DB_S7”.int01 的值为 100;当访问 http://192.168.2.153:8000/plcConnect10 时 “DB_S7”.int01 的值修改为 10,这是因为程序段1会将 10 赋值给 “DB_S7”.int01。之后访问 plcConnect 接口 “DB_S7”.int01 的值为 10,当然你可以在服务器添加逻辑代码来处理各种情况还是蛮好玩的。
读取
@GetMapping("plcConnect")
public String plcConnect(){
// SiemensPLCS.S1500 代表 PLC 的型号
// "169.254.7.208" 代表 PLC 的 IP 地址
SiemensS7Net siemensTcpNet = new SiemensS7Net(
SiemensPLCS.S1500,
"169.254.7.208");
// siemensTcpNet.Read() 方法是向 PLC 读取指定地址区的变量值
// "DB1.DBW2" 代表变量的地址区
OperateResultExOne<byte[]> read = siemensTcpNet.Read("DB1.DBW2", (short) 8);
String result = null;
if (read.IsSuccess) {
byte[] content = read.Content;
short no = siemensTcpNet.getByteTransform().TransInt16(content, 2);
result = "content: \t" + Arrays.toString(content) + "\nno:\t" + no;
}
siemensTcpNet.ConnectClose();
return result;
}
写入
@GetMapping("plcConnect10")
public String plcConnect10(){
// SiemensPLCS.S1500 代表 PLC 的型号
// "169.254.7.208" 代表 PLC 的 IP 地址
SiemensS7Net siemensTcpNet = new SiemensS7Net(
SiemensPLCS.S1500,
"169.254.7.208");
// siemensTcpNet.Write 方法是向 PLC 修改指定地址区的变量值
// "DB1.DBX0.0" 代表变量的地址区
OperateResult read = siemensTcpNet.Write("DB1.DBX0.0", true);
String result = null;
if (read.IsSuccess) {
String content = read.Message;
result = "content: \t" + content;
}
siemensTcpNet.ConnectClose();
return result;
}