一:PLC设置
plc右键属性中需要设置以下几个点
1:web服务器中的----常规这两个选项勾选上
2: 防护与安全 选择 连接机制 勾选 允许来自远程对象的PUT/GET通信访问
3:设置一下PLC的IP地址(不用设置也行,知道IP就行)
4:创建 java读写的db数据块,设置编号,等会要用,不想改代码就,编号设置为5
5:选择数据库右键选择属性,去掉优化快速访问
6:创建一些输入输出变量,等会读取和写入
7:将输出赋值初始值
8:编译装载到PLC上面
二:IDEA搭建
IDEA软件下好之后,需要自己搞一个maven用作自己的仓库,存放各种依赖(不然就手动下载jar包导入进去)
1:新建项目,搭建项目的一些基础依赖就不展示了,只需要在pom.xml中添加一下这个依赖就行
<dependency>
<groupId>com.github.s7connector</groupId>
<artifactId>s7connector</artifactId>
<version>2.1</version>
</dependency>
2:只需要在src下面的main里面的java下面创建一个plc的包就行,我这个是用练手的项目连接PLC的,不需要和我一样
3:连接class类
public class S7ConnectorPLC {
public S7Connector initConnect(String ipAddress) {
//默认端口
// 创建与PLC的链接
S7Connector connector = S7ConnectorFactory.buildTCPConnector()
.withHost(ipAddress)
.withRack(0) // 架机号 可选,建议选择,可能会报错
.withSlot(1) // 插槽号 可选,建议选择,可能会报错
.build();
return connector;
}
}
读取class,之前创建的DB块的编号在这里面用上,区块编号
public class ReadPLC {
//Int类型的封装类 用来转义
private static IntegerConverter intCon = new IntegerConverter();
//String...
private static StringConverter strCon = new StringConverter();
//Boolean...
private static BitConverter boolCon = new BitConverter();
//real实数浮点...
private static RealConverter realCon = new RealConverter();
//获取到的数据存储
public boolean in_bool = false;//bool
public Integer in_int = null;//int
public String in_String = "";//string
public double in_real = 0.0;//real
public void Cyclic_read(S7Connector connector) {
byte[] PlcData = null;
//读取bool型
PlcData = connector.read(DaveArea.DB, // 选择数据区块
5, // 区块编号
1, // 数据值长度 boolean长度1
0); // 开始位置偏移量
Boolean extract_bool = boolCon.extract(new Boolean(false).getClass(), PlcData, 0, 0);//接收转换的数值
in_bool = extract_bool;//赋值给全局变量
// 读取整型
PlcData = connector.read(DaveArea.DB, // 选择数据区块
5, // 区块编号
2, // 数据值长度 int长度2
2); // 开始位置 偏移量
Integer extract_int = intCon.extract(new Integer(0).getClass(), PlcData, 0, 0);
in_int = extract_int;
// 读取字符串型
PlcData = connector.read(DaveArea.DB, // 选择数据区块
5, // 区块编号
16, // 数据值长度 String最小3 随值长度增加
4); // 开始位置偏移量
String extract_string = strCon.extract(new String().getClass(), PlcData, 0, 0);
in_String = extract_string;
// 读取小数型
PlcData = connector.read(DaveArea.DB, // 选择数据区块
5, // 区块编号
4, // 数据值长度 double长度4
260); //偏移量
Double num1 = realCon.extract(new Double(0).getClass(), PlcData, 0, 0);
/* BigDecimal bd1 = new BigDecimal(num1);
System.out.println("转换real浮点= " + bd1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString());*/
in_real = num1;
try {
connector.close();//关闭链接
} catch (IOException e) {
e.printStackTrace();
}
}
}
写入class
public class Java_To_write {
//@Test
public void Java_To_write(S7Connector connector) {
byte[] bytes = null;
boolean out_boolen = true;
// bytes = S7Type.BOOL;
// connector.write(DaveArea.DB, 5, 264, bytes);
// 向plc中写int整型数据
// 向PLC中写短整型(2字节,对应PLC INT类型)数据
//第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
//第二个参数:DB块地址,若plc中是DB1000,则填1000
//第三个参数:偏移量
//第四个参数:写入的数据 二进制数组byte[]
short out_int = 15;
bytes = ByteBuffer.allocate(2).putShort(out_int).array();
connector.write(DaveArea.DB, 5, 266, bytes);
// 向PLC中写整型(4字节,对应PLC DINT类型)数据
int data=15;
bytes = ByteBuffer.allocate(4).putInt(data).array();
connector.write(DaveArea.DB,5, 528,bytes);
// 写入字符串
//第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
//第二个参数:DB块地址,若plc中是DB1000,则填1000
//第三个参数:偏移量
//第四个参数:写入的数据 二进制数组byte[] ,总长度为10的话,有效数据只能是10-8,第一位代表总长,第二位,代表有效数据字节
String out_string = "helloPlc";
int writeStrLength = 10;//地址块大小
byte[] writeBytes = new byte[writeStrLength];
writeBytes[0] = (byte) writeStrLength;//写入本字符串块总宽度
out_string = out_string.trim();//清除掉两边的空串
int availableEffectCharLength = 0;//有效字符数控制
if (out_string.length() > writeStrLength - 2) {//>writeStrLength-2 截断到最大有效数据位
availableEffectCharLength = writeStrLength - 2;
} else {//<=writeStrLength-2
availableEffectCharLength = out_string.length();
}
writeBytes[1] = (byte) availableEffectCharLength;//写入有效字节数
byte[] strBytes = out_string.getBytes(StandardCharsets.US_ASCII);
for (int i = 0; i < availableEffectCharLength; i++) {
writeBytes[i + 2] = strBytes[i];
}
connector.write(DaveArea.DB, 5, 268, writeBytes);
/**
* 写入PLC中的浮点型数据
* java float : plc Real 4 字节
* java double : plc LReal 8 字节
**/
//第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
//第二个参数:DB块地址,若plc中是DB1000,则填1000
//第三个参数:偏移量
//第四个参数:写入的数据 二进制数组byte[]
float out_real=new Float(5.54);
bytes = ByteBuffer.allocate(4).putFloat(out_real).array();
connector.write(DaveArea.DB,5, 524,bytes);
/**
* 写入PLC中的浮点型LREAL(java中是double)数据
* java float : plc Real 4 字节
* java double : plc LReal 8 字节
**/
//第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
//第二个参数:DB块地址,若plc中是DB1000,则填1000
//第三个参数:偏移量
//第四个参数:写入的数据 二进制数组byte[]
float out_Lreal=new Float(15.56);
bytes = ByteBuffer.allocate(8).putDouble(out_Lreal).array();
connector.write(DaveArea.DB,5, 532,bytes);
try {
connector.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试class,PLC的IP地址不要忘记改成自己的,上面注释代码是测试读取的,想测试读取将注释取消掉,下面三行注释。
public class domain {
public static void main(String[] args) throws InterruptedException {
ReadPLC readPLC = new ReadPLC();//创建读取plc数据对象
/* while (true) {
S7Connector connector = initConnect();//初始化
readPLC.Cyclic_read(connector);//读取
System.out.println("=============读取plc信息==============");
System.out.println(readPLC.in_bool);
System.out.println(readPLC.in_int);
System.out.println(readPLC.in_String);
System.out.println(readPLC.in_real);
System.out.println("=============读取plc信息==============");
Thread.sleep(1000);//stop 0.5s
}*/
Java_To_write plcwrite = new Java_To_write();
S7Connector connector = initConnect();//初始化
plcwrite.Java_To_write(connector);
}
public static S7Connector initConnect() {
S7ConnectorPLC s7ConnectorPLC = new S7ConnectorPLC();
S7Connector connector = s7ConnectorPLC.initConnect("192.168.0.101");//plc地址
return connector;
}
}
在测试类中右键运行
额外:启动项目部署,在浏览器中显示,在controller控制层中将数据传到前台页面中
写入一样的,定义一个输入框,限制类型,通过表单什么的将数据传到后台,根据类型去调用
Java_To_write里面的函数,将数据传到PLC
注意:本次连接使用的PLC型号是1214c,全部都是实物,没有任何仿真模拟。
本文参考地址java读写西门子1500plc数据块 - 知乎 (zhihu.com),没有实物的可以看看这篇