Java使用S7协议连接西门子PLC1200、1500

Java使用S7协议连接西门子PLC1200、1500

1.引入s7包

使用
https://github.com/s7connector/s7connector

		<!-- https://mvnrepository.com/artifact/com.github.s7connector/s7connector -->
		<dependency>
			<groupId>com.github.s7connector</groupId>
			<artifactId>s7connector</artifactId>
			<version>2.1</version>
		</dependency>

2.测试代码(可参考使用)

package 你的包路径;

import com.github.s7connector.api.DaveArea;
import com.github.s7connector.api.S7Connector;
import com.github.s7connector.api.S7Serializer;
import com.github.s7connector.api.factory.S7ConnectorFactory;
import com.github.s7connector.api.factory.S7SerializerFactory;
import junit.framework.TestCase;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.parameters.P;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;

/**
 * 测试PLC通信,使用s7 connectorl,支持西门子plc1200,1500。其他PLC平台请参考使用
 * xiaohelong2005@126.com(咨询技术问题可邮件沟通) 湖南一秒智能科技有限公司 湖南长沙
 * 更新于20221209
 */
public class s7connectorTest extends TestCase {
    public S7Connector initConnect(){
        //PLC地址
        String ipAddress = "192.168.1.50";
        //默认端口
        int port = 102;
        int rack=0;
        int slot=1;
        int timeout=10000;
        S7Connector s7connector=
                S7ConnectorFactory
                        .buildTCPConnector()
                        .withHost(ipAddress)
                        .withPort(port) //optional
                        .withRack(rack) //optional
                        .withSlot(slot) //optional
                        .withTimeout(timeout) //连接超时时间
                .build();
        S7Serializer s7Serializer2L = S7SerializerFactory.buildSerializer(s7connector);
        return s7connector;

    }

    /**
     * 读取PLC中的整型数据
     *
     **/
    public void testReadPlcIntData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:数据长度
        //第四个参数:偏移量
        byte[] getBytes = s7Connector.read(DaveArea.DB, 150, 2, 0);

        Integer intData = new BigInteger(getBytes).intValue();
        System.out.println("getIntData:"+intData);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 向PLC中写短整型(2字节,对应PLC INT类型)数据
     *
     **/
    public void testWritePlcShortIntData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:偏移量
        //第四个参数:写入的数据 二进制数组byte[]
        short data=15;
        byte[] bytes = ByteBuffer.allocate(2).putShort(data).array();
        System.out.println("bytes length:"+bytes.length);
        s7Connector.write(DaveArea.DB,150, 0,bytes);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 向PLC中写整型(4字节,对应PLC DINT类型)数据
     *
     **/
    public void testWritePlcIntData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:偏移量
        //第四个参数:写入的数据 二进制数组byte[]
        int data=15;
        byte[] bytes = ByteBuffer.allocate(4).putInt(data).array();
        System.out.println("bytes length:"+bytes.length);
        s7Connector.write(DaveArea.DB,6, 0,bytes);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 向PLC中读字符串
      约定协议: 对于字符串,第一个字节是总长度值,此值包括标志位,第二个字节是有效数据位,紧跟有效数据字节数。
     **/
    public void testReadPlcStrData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:数据长度
        //第四个参数:偏移量
        byte[] getBytes = s7Connector.read(DaveArea.DB, 150, 10, 20);
        String retString="";
        if(getBytes!=null&&getBytes.length<3) {
            retString= new String(getBytes,StandardCharsets.US_ASCII);
        }else if(getBytes!=null)
        {
            int charCount=Integer.valueOf(getBytes[1]);//第一个字节是总长度,第二个字节是有效字节数,获取有效字节数
            StringBuilder stringBuilder=new StringBuilder(charCount);
            for(int i=0;i<charCount;i++){
                stringBuilder.append((char)getBytes[i+2]);
            }
            retString=stringBuilder.toString();

        }

        System.out.println("getStringData:"+retString);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 向PLC中写字符串
     约定协议: 对于字符串,第一个字节是总长度值,此值包括标志位,第二个字节是有效数据位,紧跟有效数据字节数。
     **/
    public void testWritePlcStrData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:偏移量
        //第四个参数:写入的数据 二进制数组byte[]  ,总长度为10的话,有效数据只能是10-8,第一位代表总长,第二位,代表有效数据字节
        String str = "59";
        int writeStrLength=10;//地址块大小
        byte[] writeBytes=new byte[writeStrLength];
        writeBytes[0]=(byte)writeStrLength;//写入本字符串块总宽度
        str=str.trim();//清除掉两边的空串
        int availableEffectCharLength=0;//有效字符数控制
        if(str.length()>writeStrLength-2)
        {//>writeStrLength-2 截断到最大有效数据位
            availableEffectCharLength=writeStrLength-2;

        }else{//<=writeStrLength-2
            availableEffectCharLength=str.length();
        }
        writeBytes[1]=(byte)availableEffectCharLength;//写入有效字节数
        byte[] strBytes=str.getBytes(StandardCharsets.US_ASCII);
        for(int i=0;i<availableEffectCharLength;i++){
            writeBytes[i+2]=strBytes[i];
        }
        s7Connector.write(DaveArea.DB,150, 20,writeBytes);
        System.out.println("write str:"+(new String(writeBytes)));
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 读取PLC中的浮点型float(real 4字节)数据
     * java float : plc Real 4 字节
     * java double : plc LReal 8 字节
     **/
    public void testReadPlcRealData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:数据长度
        //第四个参数:偏移量
        //byte [] bytes = ByteBuffer.allocate(8).putDouble(1729.1729).array();
        //byte [] bytes = { 64, -101, 4, -79, 12, -78, -107, -22 };
        //System.out.println();

        byte[] getBytes = s7Connector.read(DaveArea.DB, 150, 4, 64);
        Float getValue = ByteBuffer.wrap(getBytes).getFloat();
        System.out.println("getFloatData:"+getValue);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 读取PLC中的浮点型Double(8字节)数据
     * java float : plc Real 4 字节
     * java double : plc LReal 8 字节
     **/
    public void testReadPlcLRealData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:数据长度
        //第四个参数:偏移量
        //byte [] bytes = ByteBuffer.allocate(8).putDouble(1729.1729).array();
        //byte [] bytes = { 64, -101, 4, -79, 12, -78, -107, -22 };
        //System.out.println();

        byte[] getBytes = s7Connector.read(DaveArea.DB, 6, 8, 4);
        Double getValue = ByteBuffer.wrap(getBytes).getDouble();
        System.out.println("getDoubleData:"+getValue);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 写入PLC中的浮点型数据
     * java float : plc Real 4 字节
     * java double : plc LReal 8 字节
     **/
    public void testWritePlcRealData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:偏移量
        //第四个参数:写入的数据 二进制数组byte[]
        float data=new Float(5.54);
        byte[] bytes = ByteBuffer.allocate(4).putFloat(data).array();
        System.out.println("bytes length:"+bytes.length);
        s7Connector.write(DaveArea.DB,150, 64,bytes);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 写入PLC中的浮点型LREAL(java中是double)数据
     * java float : plc Real 4 字节
     * java double : plc LReal 8 字节
     **/
    public void testWritePlcLRealData() {

        S7Connector s7Connector = initConnect();
        //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数:DB块地址,若plc中是DB1000,则填1000
        //第三个参数:偏移量
        //第四个参数:写入的数据 二进制数组byte[]
        float data=new Float(15.5);
        byte[] bytes = ByteBuffer.allocate(8).putDouble(data).array();
        System.out.println("bytes length:"+bytes.length);
        s7Connector.write(DaveArea.DB,6, 4,bytes);
        try {
            s7Connector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值