JAVA与西门子S7 PLC通信,方式一:S7connector

背景

        在公司项目中,需要用到和PLC进行通讯,经过搜索后查询到使用JAVA与PLC通信两种方式,测试后达到正常读写的目的,于是记录下学习过程。

环境

Spring+SpringMVC+MybatisPlus  / SpringBoot

PLC: 西门子 S7-1500/S7-1200(1214C)

PLC设置

 第一步: 使用  TIA Portal 创建DB数据块,设置地址为:12 (地址可设置为1-59999 任意一个数字);

 第二步:在DB块中插入新行,此处设置了8个Bool类型,1个Byte、3个String(参考)

        首次添加时不会显示“偏移量”,需要右键数据块,选择属性,在‘常规-属性’中,取消‘优化的块访问’后将程序下载到设备后即可以看到偏移量。

 正在准备设备模拟文章中...

JAVA使用S7Connector读写数据

读取/写入单个数据

第一步: 在pom中增加依赖:添加s7Connector依赖。

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

        当前项目中需要和PLC通信实现读取PLC地址中的数据、向PLC地址中写入数据,所以下面通过三个方法来实现 连接-读取-写入 这三个目标。
第二步: 初始化PLC链接

/*** 初始化PLC连接*/public S7Connector initConnect(){//PLC地址String ipAddress = "192.168.1.2";//默认端口String port = "102";S7Connector s7Connector =  S7ConnectorFactory.buildTCPConnector().withHost(ipAddress).withPort(port).withTimeout(10000) //连接超时时间.withRack(0) .withSlot(1) .build();S7Serializer  s7Serializer2L = S7SerializerFactory.buildSerializer(s7Connector);return s7Connector;}

第三步:读取PLC地址中的数据

         PLC中待读取的数据地址为DB1000,偏移量为2,数据类型word (2位的16进制数据);

         (稍后补充PLC截图)

        读取PLC中数据很简单,调用s7connect.read 即可,但是需要根据PLC中存储的数据类型将二进制数组解析为Java数据类型;

/**
* 读取PLC中的数据,字符串类型
*
**/
public void readPlcData() {S7Connector s7Connector = initConnect(); //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB//第二个参数:DB地址,若plc中是DB1000,则填1000   //第三个参数:数据长度, <=plc中两个偏移量的间隔,当前偏移量为1000,下一个地址偏移量为1100,则长度可填 0-1000;//第三个参数:偏移量byte[] barcodeByte = s7Connector.read(DaveArea.DB, 1000, 2, 0);//由于当前PLC地址中保存的数据类型是字符串类型,所以直接将byte[] 转成string即可;String barcode = new String(barcodeByte);System.out.println(barcode);try {s7Connector.close();} catch (IOException e) {e.printStackTrace();}}

读取PLC 中word类型的数据如下:

/**
* 读取PLC中的数据
*
**/
public void readPlcData() {S7Connector s7Connector = initConnect(); //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB//第二个参数:DB地址,若plc中是DB1000,则填1000   //第三个参数:数据长度, <=plc中两个偏移量的间隔,当前偏移量为1000,下一个地址偏移量为1100,则长度可填 0-1000;//第四个参数:偏移量byte[] barcodeByte = s7Connector.read(DaveArea.DB, 1000, 2, 0);//由于当前PLC地址中保存的数据类型是字符串类型,所以直接将byte[] 转成string即可;String barcode =byteToHex(barcodeByte);System.out.println(barcode);try {s7Connector.close();} catch (IOException e) {e.printStackTrace();}}/*** byte数组转hex* @param bytes* @return*/public static String byteToHex(byte[] bytes){String strHex = "";StringBuilder sb = new StringBuilder("");for (int n = 0; n < bytes.length; n++) {strHex = Integer.toHexString(bytes[n] & 0xFF);sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示,位数不够,高位补0}return sb.toString().trim();}

第四步:向PLC地址中写入数据

 写入数据与读取数据类似,调用write方法即可;但是注意写数据时数据类型需要转成二进制数组;

/**
* 向PLC中写数据
*
**/
public void writePlcData() {S7Connector s7Connector = initConnect(); //第一个参数:DaveArea.DB 表示读取PLC的地址区域为DB//第二个参数:DB地址,若plc中是DB1000,则填1000   //第三个参数:偏移量//第四个参数:写入的数据 二进制数组byte[],由于plc中地址的数据类型是word,所以写入的数据必须是4位的16进制数据connector2L.write(DaveArea.DB,1000, 4,hexStringToBytes("0001"));try {s7Connector.close();} catch (IOException e) {e.printStackTrace();}}/*** 将16进制字符串转成二进制数组* @param hexString* @return*/public static byte[] hexStringToBytes(String hexString) {if (hexString == null || hexString.equals("")) {return null;}hexString = hexString.toUpperCase();int length = hexString.length() / 2;char[] hexChars = hexString.toCharArray();byte[] d = new byte[length];for (int i = 0; i < length; i++) {int pos = i * 2;d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));}return d;}

        以上方式为读取/写入数据块单个偏移量的数据,下面的方式为批量读取/写入数据块数据。

批量读取/写入数据        

与单个读取/写入数据相同,第一步也是需要创建连接,然后再进行读取/写入:

第一步:创建连接

/*** 初始化PLC连接*/public S7Connector initConnect(){//PLC地址String ipAddress = "192.168.1.2";//默认端口String port = "102";S7Connector s7Connector =  S7ConnectorFactory.buildTCPConnector().withHost(ipAddress).withPort(port).withTimeout(10000) //连接超时时间.withRack(0) .withSlot(1) .build();S7Serializer  s7Serializer2L = S7SerializerFactory.buildSerializer(s7Connector);return s7Connector;}

第二步:根据数据块以及偏移量创建对象


import com.github.s7connector.api.annotation.S7Variable;
import com.github.s7connector.impl.utils.S7Type;
import lombok.Data;@Data
public class PLCData {/*** type是这个点位在PLC中设置的类型,源码会解析其长度;* byteOffset对应PLC偏移量中的整数部分;* bitOffset指偏移量的小数部分,bitOffset指第几个bit.* byteOffset和bitOffset 也可理解为返回的byte[]中第byteOffset到bitOffset*/@S7Variable(type= S7Type.BOOL,byteOffset = 0,bitOffset = 0)public Boolean data10;//bool型的值不要用private@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 1)public Boolean data11;@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 2)public Boolean data12;@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 3)public Boolean data13;@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 4)public Boolean data14;@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 5)public Boolean data15;@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 6)public Boolean data16;@S7Variable(type=S7Type.BOOL,byteOffset = 0,bitOffset = 7)public Boolean data17;@S7Variable(type=S7Type.BYTE,byteOffset = 1,bitOffset = 0)public Byte dataB1;@S7Variable(type=S7Type.STRING,byteOffset = 2,bitOffset = 0)public String dataS1;@S7Variable(type=S7Type.STRING,byteOffset = 258,bitOffset = 40)public String dataS2;@S7Variable(type=S7Type.STRING,byteOffset = 514,bitOffset = 40)public String dataS3;@S7Variable(type=S7Type.STRING,byteOffset = 770)public String dataS4;}

第三步:读取数据

       通过dispense 即可读取在对象中设置的所有数据(根据偏移量自动填充到对象的属性中。)

//参数1:根据偏移量和数据类型创建的对象
//参数2:DB数据块地址
//参数3:数据偏移量-返回的byte向后延几位
PlcDb plcDb = S7ConnectUti.getS7Serializer().dispense(PlcDb.class,12,0);

第四步:写入数据

/**
* address: DB数据块地址
* offset: 偏移量
* plcDb :  根据DB块的偏移量和数据类型创建的对象-需要修改的数据对应的属性需要赋值
*/public static void writeBooleanPlcData(Integer address,Integer offset,PlcDb plcDb) {getS7Serializer().store(plcDb,address, offset);}//示例
PlcDb plcDbWrite = new PlcDb();
plcDbWrite.setData10(true);
S7ConnectUti.writeBooleanPlcData(12,0,plcDbWrite);

源码地址:

PLCConnectDemo: JAVA连接PLC,S7connect、OPCUA(Milo)

方法在utils下面的   S7ConnectUti 中。

问题记录:

1. 提示错误:Result: the CPU does not support reading a bit block of length<>1

检查查询的实体类中字段是否为public,若为private则会出现错误。

2. 提示错误: the desired address is beyond limit for this PLC

JAVA数据类型和PLC中的数据类型不匹配,我的错误为PLC中类型为Array[0..9] of char,不能使用String直接接收,需要使用上文中【读取PLC地址中的数据】单独读取并进行解析。

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/27757.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汇川PLC和PLC之间ModebusTCP通讯

目录 一、AM402做主站和H3U通讯 1、Modebus主站中组态配置 2、读从站寄存器配置 3、写从站寄存器配置 4、程序中使用对从站读写操作的寄存器值 &#xff08;1&#xff09;I/O映射中地址关联 &#xff08;2&#xff09;创建自定义全局变量 &#xff08;3&#xff09;程序…

倍福TwinCAT3上位机与PLC通信测试(ADS通信) 包含C#和C++代码

倍福TwinCAT3上位机与PLC通信测试(ADS通信) 包含C#和C代码 倍福TwinCAT3上位机与PLC通信测试(ADS通信) 包含C#和C代码 本次测试需要环境&#xff1a; VS2013&#xff0c;TwinCAT3&#xff08;本人版本TC31-Full-Setup.3.1.4018.16&#xff09; 代码&#xff1a;C#代码&…

C#使用S7netPlus与PLC通讯(超简单)

前言 刚接到手一个项目&#xff0c;是开发一款程序&#xff0c;要和PLC有数据交互&#xff0c;如上图&#xff0c;设备发生故障后&#xff0c;PLC会发电报&#xff0c;我们收到电报后把故障显示出来&#xff0c;同时点击解除故障&#xff0c;也会给PLC发送相对应的电报。查了蛮…

C#与西门子PLC通信上位机程序

1.该程可以实现c#与西门子全系列plc(200smart&#xff0c;300&#xff0c;400&#xff0c;1200&#xff0c;1500)的以太网s7通讯&#xff0c;通讯传输快稳定。 2.该程序采用.dll动态链接库方式&#xff0c;是最近几年才出来的一种与西门子plc通讯的方式&#xff0c;本人经过几个…

C#中使用S7.net与西门子PLC通讯

最近因为工作的原因用到了西门子PLC&#xff0c;在使用过程中一直在思考上位机和PLC的通讯问题&#xff0c;后来上网查了一下&#xff0c;找到了一个专门针对S7开发的一个.net库–《S7netPlus》&#xff0c;PLC通讯方法比较多&#xff0c;所以也是在不断地学习中&#xff0c;以…

C#调用PCHMI与西门子PLC连接通讯

文章目录 一、PCHMI环境配置二、PCHMI连接S7&#xff08;PLC&#xff09;三、标签与按钮的使用总结 一、PCHMI环境配置 创建一个新项目 打开项目属性&#xff0c;更改输出路径为"bin\binexe"下 工具箱新建个选择卡&#xff0c;我们命名为PCHMI 鼠标右键【选择项】…

第三方调试助手的与S7-1200 PLC的通信

1、概述 西门子S7-1200 PLC支持多种协议通过以太网通讯方式&#xff0c;如OPC、TCP、S7、MODBUS-TCP等。TCP方式相比其它协议&#xff0c;具有更多的灵活性&#xff0c;更快的数据响应等优点&#xff0c; 需要PLC与电脑还有其他设备进行TCP通讯&#xff0c;使用TCP调试助手与…

TIA 博图 使用 S7通讯 Put Get 对两台PLC进行通讯

1.打开设备组态-属性-找到防护与安全&#xff1a; 把允许来自远程的PUT/GET 通讯访问✔&#xff0c;两台PLC都是这样&#xff0c;把组态下载进去。 2.设备与网络中&#xff0c;用端口1把两台设备连在一起&#xff1a; 两台设备需要在同一个网段里面 3.在PLC3新建一个DB块&#…

文心一言 VS 讯飞星火 VS chatgpt (23)-- 算法导论4.2 5题

五、V.Pan 发现一种方法&#xff0c;可以用 132 464 次乘法操作完成 68 x 68 的矩阵相乘&#xff0c;发现另一种方法&#xff0c;可以用 143 640 次乘法操作完成 70 x 70 的矩阵相乘&#xff0c;还发现一种方法&#xff0c;可以用155 424次乘法操作完成 72 x 72 的矩阵相乘。当…

【Python爬虫项目实战二】Chatgpt还原验证算法-解密某宝伪知网数据接口

目录 🐱背景🐱工具🐱分析流程🐔登陆分析🐔检索分析🐔模拟HTML代码请求🐔 解析HTML🐔 再次分析🐟分析js算法🐟 拿下furl🐟拿下sfname🐟拿下sfname🐔 构造请求🐔再次瓶颈🐔分析cookie🐟 成功演示🐱总结

[云炬python3玩转机器学习]6-2模拟梯度下降法

模拟梯度下降法 In [1]: import numpy as np import matplotlib.pyplot as plt import datetime;print (Run by CYJ,,datetime.datetime.now()) In [2]: plot_x np.linspace(-1., 6., 141) plot_xOut[2]: array([-1. , -0.95, -0.9 , -0.85, -0.8 , -0.75, -0.7 , -0.65…

OneFlow源码解析:静态图与运行时

作者&#xff5c;郑建华 更新&#xff5c;许啸宇、张文骁、成诚 OneFlow静态图的训练效率远高于动态图&#xff08;eager模式&#xff09;。本文试图通过一个简单例子&#xff0c;结合v0.8.0版本的代码&#xff0c;解读一下静态图和运行时的实现机制。 在开始之前&#xff0c;建…

infer源码阅读之yolo.cu

目录 yolo.cu注意事项一、2023/3/30更新前言1.宏定义2.Norm3.后处理3.1 affine_project3.2 decode3.2.1 decode_common3.2.2 decode_v8 3.3 nms3.4 invoker 4.预处理5.decode_mask6.AffineMatrix7.InferImpl7.1 adjust_memory7.2 preprocess7.3 load7.4 forwards 8.其它9.拓展之…

【爬虫实例】从B站和某论文网站分析python爬虫的一般编写思路———To someone

问题背景 好久没写爬虫了&#xff0c;前两天友人来问我python能不能爬论文&#xff0c;能不能告诉她爬虫的基本运行原理是什么&#xff0c;跑起来是什么样子。 我一看&#xff0c;论文爬取——爬虫最实用的场景之一&#xff0c;这不拿捏&#xff1f; 于是便尝试现场演示一番。…

【Metaverse系列一】元宇宙的奥秘

你有没有想过逃离闷热的会议室&#xff0c;瞬间移动到马尔代夫的沙滩上开会&#xff1f;开完会&#xff0c;纵身跳入大海和美人鱼捉迷藏。然后一个鲤鱼打挺直冲云霄&#xff0c;进入天宫一号开展科学研究&#xff0c;发现微重力环境下韭菜的长势喜人&#xff0c;而且在特定光照…

科大讯飞版ChatGPT测评:很好很强大

大家好&#xff0c;我是黄海广。 今天我体验到了科大讯飞版本的ChatGPT&#xff0c;这个产品凭借其强大的功能和出色的性能&#xff0c;超出了我对国产大模型的预期。 一、产品简介 这个模型全名叫讯飞星火认知大模型&#xff0c;官方是这么解释这个产品的&#xff1a; “科大讯…

七大语言模型PK,ChatGPT内容基线测评稳居第一

随着ChatGPT的爆火与流行&#xff0c;大型语言模型&#xff08;LLM&#xff09;与生成式人工智能&#xff08;AIGC&#xff09;不断跃入大众视野&#xff0c;随之也带来了许多内容风险隐患。 近日&#xff0c;知道创宇内容安全专家对互联网上流行的7款大型语言模型进行了全面和…

ChatGPT风靡全球,我们应该为未来感到担心吗?

近期&#xff0c;关于ChatGPT的话题再次引爆全网&#xff0c;不少用户加入到“玩疯了”的阵营中……有赞叹不已的、有表示惊奇的、有展示BUG的&#xff0c;但总体来说&#xff0c;ChatGPT的整体社交评价还是非常向好的。 微软CEO纳德拉就坦言&#xff0c;ChatGPT服务的风靡&…

库克考虑卸任苹果CEO,谁会是下一任接班人?

作者 | Carol 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 十年前&#xff0c;8 月 24 日那天&#xff0c;史蒂夫乔布斯宣布辞去苹果 CEO 一职&#xff0c;正式任命蒂姆库克成为苹果的新掌门人。如今&#xff0c;恰逢库克上任苹果 CEO 十周年。在今年4月份&…

历史上的今天:乔布斯辞去苹果CEO一职;Windows 95 发布

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2022 年 8 月 24 日&#xff0c;14 年前的今天&#xff0c;北京奥运会闭幕式举办&#xff0c;宣告圆满结束&#xff0c;为所有国人打上了一针强心剂。而在科技历史上&am…