S7-1200,S7-1500上下行数据处理

  • 仿真环境
  • 安装TIA Portal
  • 创建仿真项目
  • 创建PLC设备
  • 配置网络信息
  • 放开PLC,PUT/GET权限
  • 设定程序块用来模拟取值
  • 启动仿真
  • 解压缩NetToPLCsim
  • JAVA操作S7
  • S7链接工具类
  • JAVA读取DB块


仿真环境

首先用到的软件有以下几个

安装TIA Portal

这个没什么特殊的一路下一步就行 (哦,有同事反应找个博图不好卸载。。建议虚拟机里装)

创建仿真项目

java如何和PLC设备对接 java程序连接plc_java


双击打开这个软件,创建新的项目

java如何和PLC设备对接 java程序连接plc_数据_02

java如何和PLC设备对接 java程序连接plc_java如何和PLC设备对接_03

创建PLC设备

java如何和PLC设备对接 java程序连接plc_java_04


添加新设备

java如何和PLC设备对接 java程序连接plc_java如何和PLC设备对接_05


按照自己需要的创建不同型号的PLC

java如何和PLC设备对接 java程序连接plc_物联网_06


java如何和PLC设备对接 java程序连接plc_java如何和PLC设备对接_07


点击添加。

配置网络信息

双击WLAN口,配置设备的网络信息

java如何和PLC设备对接 java程序连接plc_S7_08


java如何和PLC设备对接 java程序连接plc_物联网_09


配置后如下图所示

java如何和PLC设备对接 java程序连接plc_S7_10

放开PLC,PUT/GET权限

右键PLC设备,点击属性

java如何和PLC设备对接 java程序连接plc_java_11


在允许远程对象PUT/GET访问打上勾

java如何和PLC设备对接 java程序连接plc_物联网_12

设定程序块用来模拟取值

java如何和PLC设备对接 java程序连接plc_S7_13


java如何和PLC设备对接 java程序连接plc_物联网_14


编号可以自动,也可以手动指定,这里跟后面程序访问时参数设定有关。

生成数据块之后右键点击数据块属性,在属性中设置关闭优化块访问

java如何和PLC设备对接 java程序连接plc_物联网_15

java如何和PLC设备对接 java程序连接plc_java_16


点击确定完成设置添加项目完成数据块的设置

java如何和PLC设备对接 java程序连接plc_S7_17


这里解释一下数据库名称

DBD0代表着偏移量0,数据类型时DInt,

DBW4代表着偏移量4,数据类型时Int

启动仿真

java如何和PLC设备对接 java程序连接plc_物联网_18


java如何和PLC设备对接 java程序连接plc_S7_19


java如何和PLC设备对接 java程序连接plc_S7_20


java如何和PLC设备对接 java程序连接plc_数据_21


java如何和PLC设备对接 java程序连接plc_物联网_22


出现下面界面就算成功了,千万不要点击完成

java如何和PLC设备对接 java程序连接plc_S7_23

解压缩NetToPLCsim

首先博图自带的仿真只是供开发时使用博图自己的调试程序调用的,java的链接工具是连不上的。所以需要NetToPLCsim。解压缩NetToPLCsim,这个运行时一定要使用管理员,他需要杀掉博图自带的102端口服务,然后替换成自己的,不使用管理员打开无法杀掉对应程序。

java如何和PLC设备对接 java程序连接plc_物联网_24

java如何和PLC设备对接 java程序连接plc_S7_25


java如何和PLC设备对接 java程序连接plc_java_26


主机地址不用手输,可以选择,选择自己的网卡IP

java如何和PLC设备对接 java程序连接plc_物联网_27


PLC仿真的IP,第一次打开可能无法访问到,会提示下面的错误

java如何和PLC设备对接 java程序连接plc_java如何和PLC设备对接_28


这个时候需要在仿真程序的小画面上模拟开机

先点击电源键

java如何和PLC设备对接 java程序连接plc_java如何和PLC设备对接_29


java如何和PLC设备对接 java程序连接plc_java如何和PLC设备对接_30


然后再点击电源键,这个时候就不再是未组态的PLC了,点击RUN启动PLC仿真的电源

java如何和PLC设备对接 java程序连接plc_物联网_31


一阵闪烁后会变为绿色

java如何和PLC设备对接 java程序连接plc_数据_32


这个时候再选择就会有候选地址了

java如何和PLC设备对接 java程序连接plc_java_33


按照程序提示,设置插槽号和架机号,S7-1200/1500得设置成0/1

java如何和PLC设备对接 java程序连接plc_物联网_34


点击OK完成添加,成功后如下图所示

java如何和PLC设备对接 java程序连接plc_物联网_35


点击Start Server开启服务,就可以通过JAVA程序访问S7仿真了。

JAVA操作S7

S7链接工具类

使用S7Connector

<dependency>
            <groupId>com.github.s7connector</groupId>
            <artifactId>s7connector</artifactId>
            <version>2.1</version>
        </dependency>

JAVA读取DB块

以读取我上面间的DBD0为例

S7Connector connector =
                S7ConnectorFactory
                    .buildTCPConnector()
                    .withPort(102) // 端口号,默认是102
                    .withHost("你主机的IP") 
                    .withRack(0) //架机号
                    .withSlot(1) //插槽号
                    .build();

byte[] plcData = connector.read(
            DaveArea.DB, //选择区块
            200, // 区块编号,比如我上面建的是200
            4,  // 长度,跟你区块中建的变量有关
            0);   // 开始位置,跟你区块中建的变量有关

S7Serializable converter = new LongConverter();
Long data = converter.extract(Long.class, plcData, 0, 0);
System.out.println(data);

执行结果如下

java如何和PLC设备对接 java程序连接plc_java_36


你可以在仿真里修改一下初始值尝试一下。这里附赠一下写的工具类

public class PlcUtils {

    private static Map<Class, S7Serializable> s7SerializableMap = new HashMap<>();

    static {
        s7SerializableMap.put(Integer.class, new IntegerConverter());
        s7SerializableMap.put(Long.class, new LongConverter());
        s7SerializableMap.put(Float.class, new RealConverter());
    }

    /**
     * PLC 数据读取
     * @param <T> targetClass 转换类型
     * @param connector PLC链接
     * @param db DB区块
     * @param length 数据长度
     * @param offset 数据开始位置
     * @return PLC数据
     */
    public static <T> T read(Class<T> targetClass, S7Connector connector, Integer db, Integer length, Integer offset) {

        byte[] plcData = connector.read(
            DaveArea.DB, //选择区块
            db, // 区块编号
            length,  //长度
            offset);   //开始位置

        if (targetClass == String.class) {
            return (T) new String(plcData);
        }
        S7Serializable converter = s7SerializableMap.get(targetClass);
        return converter.extract(targetClass, plcData, 0, 0);
    }

    /**
     * 数据写入
     *
     * @param value 写入数据
     * @param connector PLC链接
     * @param db DB区块
     * @param length 长度
     * @param offset 数据开始位置
     */
    public static void write(Object value, S7Connector connector, Integer db, Integer length, Integer offset) {

        S7Serializable converter = s7SerializableMap.get(value.getClass());
        byte[] buffer = new byte[length];
        converter.insert(value, buffer, 0, 0, length);
        connector.write(DaveArea.DB, db, offset, buffer);
    }
}