S7Connector jar包读写S7-1200

java使用S7Connector进行西门子设备读写点位。

S7Connector本质上是一个利用socket发送tcp报文,接受报文的过程。读写都是先发一小段读写标识的标识(参见TCPConnection的exchange方法)我需要操作数据,然后进行读取/写入。
本文中所有读写操作都在一个DB区内。
POM 坐标:

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

1、建立实体,在读写数据过程中,一个实体代表你这次要读的所有点位(原因后面解析会见到)。当然在写数据时可以使用写一个或多个点位(对应pojo中的某一个字段,比如DBX00)的方式进行写.
实体主要的作用就是用来寻址,确认读的位置和要读的块数(blocksize)

public class PlcToAgvVo {
	@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 0)//Type是这个点位的长度,对应jar包中变量blocksize,byteOffset指位偏移,bitOffset指第几个bit.
	public Boolean DBX00;//bool型的值不要用private 

	@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 1)
	public Boolean DBX01;
}

2、创建连接器 S7Connector

      类成员变量:
      private  S7Connector connector;//接口有两个实现方法:S7BaseConnection、S7TCPConnection。
      读方法中:
      this.connector = S7ConnectorFactory.buildTCPConnector().
                                          withHost(ip).//PLC设备IP
                                          withPort(Integer.parseInt(port)).//PLC设备端口
                                          withRack(0).withSlot(0).//固定
                                          withTimeout(3000).//超时时间
                                          build();//build方法返回S7TCPConnection对象。

3、创建序列化对象 S7Serializer

      S7Serializer serializer =S7SerializerFactory.buildSerializer(this.connector);

4、进行读操作:

      PlcToAgvVo plcdb1 = serializer.dispense(PlcToAgvVo.class, DB_NUM, BYTE_OFFSET);//这里dispense方法,传入实体类型,DB_NUM是设备的DB区,BYTE_OFFSET,默认设为0.
      //需要指定PLC某个DB区某个偏移量最后读取指定Blocksize。传入了实体类,底层原理使用了反射获取这个类blocksize,blocksize根据实体变量类型也就是第一步的Type确定的。
      //注意到返回一个实体,那么可以知道一次性读出实体的所有位置的数据。需要一个一个读的话,有两种方式可以考虑
            //1、一次性读出一个实体,通过get字段的方式,获取一个字段
            //2、改写dispense方法。思路就是S7Serializer实现这个接口,然后在调用S7connector的read方法时,传入,一个点位的blocksize.返回一个 byte[] buffer。这样,参考extactBytes方法,获取指定数据,
            //   获取blocksize方法可以参考BeanParser的parser方法。

5、进行写操作:

      AgvToPlcVo plcdata =new AgvToPlcVo();
      plcdata.setDBX00(true);//写一个点位
      serializer.store(plcdata,DB_NUM, BYTE_OFFSET);//使用store方法,参数的意义与读方法一致,写也是以一个实体为单位的,

注意:
1、关于把S7Connector做成连接池,初始化的时候用一个MAP去盛。会出现部分写数据失效的情况,具体原因未知(实际生产出现过)
2、使用Springcloud的定时任务去定时读的时候,会出现Connection reset by peer的情况。主要是读操作握手协议中往socket的输出流写读报文失败。需要主动调用S7Connector的close方法进行套接字的关闭操作。这也可能是连接池出现不可靠写的原因。
具体可参考 2.1、PLCinterface的read方法在0.5秒内没读到数据报的连接被重置。
2.2、TCPConnection的exchange方法在写的时候没有写成功

原文地址:https://www.cnblogs.com/jearchen/p/13741553.html