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

2023-11-18

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();
        }
    }
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java使用S7协议连接西门子PLC1200、1500 的相关文章

  • Jackson JSON + Java 泛型

    我正在尝试将以下 JSON 反序列化 映射到List
  • Android:如何暂停和恢复可运行线程?

    我正在使用 postDelayed 可运行线程 当我按下按钮时 我需要暂停并恢复该线程 请任何人帮助我 这是我的主题 protected void animation music6 music4 postDelayed new Runnab
  • 连接外部 Accumulo 实例和 java

    我正在尝试使用 Accumulo 连接到虚拟机 问题是 我无法将其连接到 Java 中 我可以看到 Apache 抛出的网页 但我无法让它与代码一起工作 我认为这是缺乏知识的问题而不是真正的问题 但我找不到这方面的文档 所有示例都使用 lo
  • Kafka - 如何同时使用过滤器和过滤器?

    我有一个 Kafka 流 它从一个主题获取数据 并且需要将该信息过滤到两个不同的主题 KStream
  • 使用 Exec Maven 插件分叉 Java,而不使用“exec”目标

    来自文档 https www mojohaus org exec maven plugin exec exec在单独的进程中执行程序和Java程序 exec java在同一虚拟机中执行 Java 程序 我想 fork 一个 java 程序
  • 我们可以有条件地声明 spring bean 吗?

    有没有一种方法可以有条件地声明 Spring bean 例如
  • 有人用过 ServiceLoader 和 Guice 一起使用吗?

    我一直想通过我们的应用程序 构建系统进行更大规模的尝试 但更高的优先级不断将其推到次要地位 这似乎是加载 Guice 模块的好方法 并且避免了关于 硬编码配置 的常见抱怨 单个配置属性很少会自行更改 但您几乎总是会有一组配置文件 通常用于不
  • 为什么用scala写的代码比用java写的慢6倍?

    我不确定我在编写 scala 代码时是否犯了一些错误 问题是 The four adjacent digits in the 1000 digit number that have the greatest product are 9 9
  • 如何使用 Java 引用释放 Java Unsafe 内存?

    Java Unsafe 类允许您按如下方式为对象分配内存 但是使用此方法在完成后如何释放分配的内存 因为它不提供内存地址 Field f Unsafe class getDeclaredField theUnsafe Internal re
  • Java AES 256 加密

    我有下面的 java 代码来加密使用 64 个字符密钥的字符串 我的问题是这会是 AES 256 加密吗 String keyString C0BAE23DF8B51807B3E17D21925FADF273A70181E1D81B8EDE
  • 如何更改 Swagger-ui URL 前缀?

    我正在使用 Springfox Swagger2 和 Spring boot 1 5 9 我可以通过此链接访问 swagger UI http localhost 8090 swagger ui html http localhost 80
  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • 即使禁用安全性,OAuth 令牌 API 也无法在 Elastic Search 中工作

    我是 Elastic search 新手 使用 Elastic search 版本 7 7 1 我想通过以下方式生成 OAuth 令牌弹性搜索文档 https www elastic co guide en elasticsearch re
  • 我所有的 java 应用程序现在都会抛出 java.awt.headlessException

    所以几天前我有几个工作Java应用程序使用Swing图书馆 JFrame尤其 他们都工作得很好 现在他们都抛出了这个异常 java awt headlessexception 我不知道是什么改变了也许我的Java版本不小心更新了 谢谢你尽你
  • Android ScrollView,检查当前是否滚动

    有没有办法检查标准 ScrollView 当前是否正在滚动 方向是向上还是向下并不重要 我只需要检查它当前是否正在滚动 ScrollView当前形式不提供用于检测滚动事件的回调 有两种解决方法可用 1 Use a ListView并实施On
  • Selenium 单击在 Internet Explorer 11 上不起作用

    我尝试在 Internet Explorer 上单击 selenium 但它不起作用 我努力了element click moveToElement element click build perform javascript没事了 事实上
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • Spring 作为 JNDI 提供者?

    我想使用 Spring 作为 JNDI 提供程序 这意味着我想在 Spring 上下文中配置一个 bean 可以通过 JNDI 访问该 bean 这看起来像这样
  • 在会话即将到期之前调用方法

    我的网络应用程序有登录的用户 有一个超时 在会话过期之前 我想执行一个方法来清理一些锁 我已经实现了sessionListener但一旦我到达public void sessionDestroyed HttpSessionEvent eve
  • 关闭扫描仪是否会影响性能

    我正在解决一个竞争问题 在问题中 我正在使用扫描仪获取用户输入 这是 2 个代码段 一个关闭扫描器 一个不关闭扫描器 关闭扫描仪 import java util Scanner public class JImSelection publ

随机推荐

  • 理解 __declspec(dllexport)和__declspec(dllimport)

    这段时间要把tinyxml从静态库弄成动态库 要用到 declspec dllexport 和 declspec dllimport 来导出dll和lib文件 终于弄明白了export和import的作用 下面从使用的角度来说明一下他们的功
  • 2020北京邮电大学计算机学院复试经验分享

    初试组内第4 复试组内第1 综合第2 已成功上岸 最近大家问我复试的比较多 趁还热乎 在这里给大家分享一下吧 仅供参考 然后初试经验贴在这里 不要因为初试成绩不好就放弃复试或者不认真对待 复试是干嘛的就是用来翻盘的 都坚持了一年了 也不差这
  • C# 获取计算机信息

    文章目录 一 本机信息 1 本机名 2 获得本机MAC地址 3 获得计算机名 4 显示器分辨率 5 主显示器分辨率 6 系统路径 二 操作系统信息 1 操作系统类型 2 获得操作系统位数 3 获得操作系统版本 三 处理器信息 1 处理器个数
  • Sublime Text3设置文本的自动换行

    1 点击Preferences Settings 然后出现以下页面 2 点击保存即可 如果想要修改其他属性 可以直接在Default里面找就可以
  • Java正则表达式验证电话号码

    在注册会员时 经常需要输入电话号码 电话号码是指手机号码或者固定电话 如果输入的内容不合法 则会向用户输出提示 本实例模拟实现电话号码的验证功能 接收用户在控制台输入的电话号码 然后进行判断 并将结果输出 在这里使用 Java正则表达式 一
  • linux改变文件所属用户和组

    1 改变文件所属用户 chown 用户名 文件名 2 改变文件所属组 chgrp 用户名 文件名
  • 狂神说-Mybatis笔记(总)

    环境 JDK1 8 MySQL 8 0 23 maven 3 6 1 IDEA2020 3 框架 需要配置文件 官方中文文档 https mybatis org mybatis 3 zh index html 一 简介 1 什么是Mybat
  • 通俗易懂权限管理模块设计-Java

    最近一直在做CMS系统 发现一些内容其实都是重复出现的 例如权限管理模块 权限管理模块就是为了管理用户是否有权利访问某个权限 如果不能则拒绝访问 其实Java中已经有很成熟的权限管理框架 例如 Shiro Spring Security等
  • 怎么让人物脚贴地 模型_Unity利用FinalIK实现角色脚掌贴着地面行走工具

    using System Collections Generic using UnityEditor using UnityEngine public class FootBones public GameObject Bone1 publ
  • 设计原则学习之里氏替换原则

    以下内容均来自抖音号 it楠老师教java 的设计模式课程 1 原理概述 子类对象 objectofsubtype derivedclass 能够替换程序 program 中父类对象 objectofbase parentclass 出现的
  • C语言程序的undefined,c语言中undefined reference to ""怎么解决

    2 gcc c test c gcc c main c 得到两个 o 文件 一个是 main o 一个是 test o 然后我们链接 o 得到可执行程序 3 gcc o main main o这时 你会发现 报错了 4 main o In
  • python安装pandas失败问题

    开始使用pip install pandas报错 后来将pip语句更换为 pip default time 100 install pandas 成功安装pandas
  • 朋友拿下字节27K的offer,实名羡慕了....

    最近有朋友去字节面试 面试前后进行了20天左右 包含4轮电话面试 1轮笔试 1轮主管视频面试 1轮hr视频面试 据他所说 80 的人都会栽在第一轮面试 要不是他面试前做足准备 估计都坚持不完后面几轮面试 其实 第一轮的电话面试除了一些常规的
  • IBM也下场LLM了,自对齐、高效率的单峰驼Dromedary来了

    近期IBM Research发布了dromedary 并指出这个模型通过一种称为自对齐 SELF ALIGN 的新方法 结合了原则驱动 principle driven 的推理和LLM的生成能力 用于AI代理的自我对齐 使人类的监督最少化
  • 链式调用demo

    所谓链式调用就是调用完一个函数后还能再继续调用其它函数 这样大大减少了代码量 尤其是项目比较大的时候 逻辑集中清晰明了 且易于查看和修改 react hooks处理hooks原理用到了链式调用 fiber memorizedStaste h
  • 费马小定理题

    费马小定理 假如p是质数 且gcd a p 1 那么 A题HDU 4704 首先是挡板法 隔板法 然后用即可 高中数学范围不多叙述 然后得到答案是 这题读入数据大 就算快速幂也肯定TLE 所以用费马小定理 把数据规模降到int 范围内 时间
  • Re: Programming in C with Bluetooth Sockets

    Re Programming in C with Bluetooth Sockets This is the function run by the bluetooth device that will recieve the data c
  • 若依框架注册功能

    后台 逻辑峰的博客 CSDN博客 若依框架登录注册 前台
  • 响应式开发

    响应式开发是指一个网站能够兼容多个终端 不同屏幕分辨率的终端上网页展示方式是不一样的 实现原理 根据用户的行为以及设备的不同 实现页面的不同展示效果 具体的开发过程 1 设置视口标签 width 视口的宽度 device width 设备的
  • Java使用S7协议连接西门子PLC1200、1500

    Java使用S7协议连接西门子PLC1200 1500 1 引入s7包 2 测试代码 可参考使用 1 引入s7包 使用 https github com s7connector s7connector