初识上位机(下):C#读写PLC数据块数据

大家好,我是Edison。

作为一个工业自动化领域的程序员,不懂点PLC和上位机,貌似有点说不过去。这里我用两篇小文带你快速进入上位机开发领域。后续,我会考虑再出一个系列文章一起玩工控上位机。

上一篇:搭建PLC模拟仿真环境

复习一下

在上一篇中,我们通过PLCSIM Advanced软件创建了一个虚拟的西门子S7-1500 PLC如下所示:

然后,我们创建了一个博途的自动化项目,和我们的虚拟PLC进行了组态。在编译完成后,我们创建的数据块中的数据字段就得到了偏移量,如下图所示,0,2,4, 260就是所谓的偏移量,会在后面用到。

创建Windows Form项目

这里开始我们就开始使用C#创建一个Windows Form项目,然后通过S7NetPlus库来连接PLC,并读取和写入数据块中的数据,这是一个典型的上位机数据采集的场景。这里我们创建一个.NET Framework 4.8的Windows Form项目,并拖控件完成一个如下图所示的窗体应用界面:

这个窗体提供了连接和断开PLC,以及读取 和 写入 文本框中的数据,接下来我们就来实现这几个功能。

实现PLC的连接与断开

要实现S7 PLC的连接和操作,目前已经有很多较为成熟的组件了,我们这里使用S7NetPlus组件,直接通过NuGet安装最新版本即可。

然后编写Connect按钮的Click事件如下:

private static Plc s7Instance;public MainForm()
{InitializeComponent();
}private void btnConnect_Click(object sender, System.EventArgs e)
{if (btnConnect.Text == "Connect"){if (s7Instance == null)s7Instance = new Plc(CpuType.S71500, txtPlcIPAddress.Text.Trim(), 0, 1);s7Instance.Open();btnConnect.Text = "Disconnect";}else{s7Instance.Close();btnConnect.Text = "Connect";txtBool01.Clear();txtInt01.Clear();txtStr01.Clear();txtStr02.Clear();}
}

实现PLC数据块的读取

由于我们在博途项目中设置的数据块是DB01,且只有4个字段,所以这里我们编写ReadData按钮的Click事件如下,它通过指定参数读取到指定类型的数据并绑定到文本框的Text中。 

private void btnReadData_Click(object sender, System.EventArgs e)
{if (s7Instance == null || !s7Instance.IsConnected){MessageBox.Show("Your PLC is not connected now!", "Error", MessageBoxButtons.OK);return;}// boolvar boolData = (bool)s7Instance.Read(DataType.DataBlock, 1, 0, VarType.Bit, 1);txtBool01.Text = boolData ? "1" : "0";// intvar intData = (short)s7Instance.Read(DataType.DataBlock, 1, 2, VarType.Int, 1);txtInt01.Text = intData.ToString();// stringvar count = (byte)s7Instance.Read(DataType.DataBlock, 1, 4 + 1, VarType.Byte, 1); // +1表示读取偏移值的长度var str01Data = Encoding.Default.GetString(s7Instance.ReadBytes(DataType.DataBlock, 1, 4 + 2, count)); // +2表示读取偏移值(跳过)的字符txtStr01.Text = str01Data;// wstringvar str02Data = (string)s7Instance.Read(DataType.DataBlock, 1, 260, VarType.S7WString, 254);txtStr02.Text = str02Data;
}

要点解读:

(1)针对bool和int类型,我们可以直接通过Read方法快速读取到,但需要告诉PLC准确的读写位置和数据类型,主要是偏移量一定要给正确。

Read方法的参数分别为数据块类型,数据块,偏移量,读取类型,读取长度

(2)针对string和wstring类型,就稍微麻烦一些了:针对string,需要先获取string值的所占长度。再拿到具体byte值。转换为utf8格式的ascci码,具体代码中有体现。

+1 表示获取到长度

+2 表示获取到跳过偏移长度的字符

特别注意:string类型只能存储ascci码,需要注意,不能存储中文

针对wstring,稍微简单点,但是需要注意的是获取的字符需要为254个,因为符号占用了4个字节。

实现PLC数据块的写入

和读取一样,通过Write方法即可轻松实现写入,但针对string和wstring仍然是复杂一些,这里我封装了一个S7DataWriter的静态类,提供了两个方法来获取要写入的bytes,因为它无法直接接收C#程序中的string类型。

public static class S7DataWriter
{/// <summary>/// 获取西门子PLC字符串数组--String类型/// </summary>public static byte[] GetPlcStringByteArray(string str){byte[] value = Encoding.Default.GetBytes(str);byte[] head = new byte[2];head[0] = Convert.ToByte(254);head[1] = Convert.ToByte(str.Length);value = head.Concat(value).ToArray();return value;}/// <summary>/// 获取西门子PLC字符串数组--WString类型/// </summary>public static byte[] GetPlcWStringByteArray(string str){byte[] value = Encoding.BigEndianUnicode.GetBytes(str);byte[] head = BitConverter.GetBytes((short)508);byte[] length = BitConverter.GetBytes((short)str.Length);Array.Reverse(head);Array.Reverse(length);head = head.Concat(length).ToArray();value = head.Concat(value).ToArray();return value;}
}

然后,我们就可以编写Write Data按钮的Click事件了:

private void btnWriteData_Click(object sender, System.EventArgs e)
{if (s7Instance == null || !s7Instance.IsConnected){MessageBox.Show("Your PLC is not connected now!", "Error", MessageBoxButtons.OK);return;}// boolvar boolValue = txtBool01.Text.Trim() == "1" ? true : false;s7Instance.Write(DataType.DataBlock, 1, 0, boolValue);// intvar intValue = Convert.ToInt16(txtInt01.Text);s7Instance.Write(DataType.DataBlock, 1, 2, intValue);// strings7Instance.Write(DataType.DataBlock, 1, 4, S7DataWriter.GetPlcStringByteArray(txtStr01.Text.Trim()));// wstrings7Instance.Write(DataType.DataBlock, 1, 260, S7DataWriter.GetPlcWStringByteArray(txtStr02.Text.Trim()));MessageBox.Show("Write data successfully!", "Info", MessageBoxButtons.OK);
}

效果演示

和读取一样,通过Write方法即可轻松实现写入,但针对string和wstring仍然是复杂一些,这里我封装了一个S7DataWriter的静态类,提供了两个方法来获取要写入的bytes,因为它无法直接接收C#程序中的string类型。

(1)读取数据

(2)写入数据

小结

本文通过使用C#开发了一个简单的WindowsForm窗体程序,实现了S7 PLC的连接、数据读取和写入。虽然只是一个简单的Demo,但是从中可以看见上位机的基本思想,就是对PLC的数据采集和监控。当然,实现这个目的,不止S7协议一条路,我们还可以通过ModBus、OPC UA等协议,这些就留到后面的专题吧,如果你感兴趣的话,就保持关注哦!

源码

GitHub:https://github.com/Coder-EdisonZhou/PLC-Connectors

 

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

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

相关文章

Markdown Editor 好用的工具

必要要记录一下,下次好找到。 Office Viewer(Markdown Editor) 好用的工具。 很适合我的。

linux开发和部署lazarus中间件

linux开发和部署lazarus中间件linux开发和部署lazarus中间件 1)linux开发的编译中间件2)linux部署中间件 本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/18197098

dotnet 设置 X11 建立窗口之间的父子关系

在 X11 里面有和 Win32 类似的窗口之间的关系机制,如 Owner-Owned 关系,以及 Parent-Child 关系。本文将告诉大家如何进行设置以及其行为本文将大量使用到 new bing 提供的回答内容,感谢 new bing 人工智能提供的内容 Owner-Owned 关系在这种关系中,一个窗口可以被另一个窗…

学习 Avalonia 框架笔记 设置 X11 窗口从最小化状态还原为正常状态

本文记录在 dotnet 里面如何设置 X11 窗口从最小化状态还原为正常状态本文属于学习 Avalonia 框架系列笔记,更多请参阅 博客导航 核心设置方法如下 /// <summary> /// 代码从 Avalonia 抄的 https://github.com/AvaloniaUI/Avalonia/blob/5e323b8fb1e2ca36550ca6fe678e4…

[转帖]全网最硬核 JVM 内存解析 - 4.Java 堆内存大小的确认

https://cloud.tencent.com/developer/article/2277323 个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判。如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 issue,谢谢支持~…

[转帖]System Performance 读书笔记 - 操作系统(1)

https://cloud.tencent.com/developer/article/1927381 本系列是针对 Systems Performance: Enterprise and the Cloud, 2nd Edition (2020) 书籍的读书笔记,加入了一些个人理解以及拓展,并且针对一些难以理解的地方提供了一些额外的参考内核(Kernel) 经典模型中,内核在操…

读人工智能时代与人类未来笔记05_现代人工智能

读人工智能时代与人类未来笔记05_现代人工智能1. 图灵 1.1. 1950年,数学家和逻辑学家艾伦图灵的论文《计算机与智能》中,图灵建议把机器智能的问题完全搁置 1.2. 图灵认为,重要的不是智能的机制,而是智能的表现 1.2.1. 因为其他生命的内在体验仍然是不可知的,所以我们衡量…

[转帖]为什么我建议需要定期重建数据量大但是性能关键的表

https://cloud.tencent.com/developer/article/1999970 个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判。如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 issue,谢谢支持~…

尽微好物:从0到10亿+的抖音电商的TOP1“联盟团长”,如何使用NineData实现上云下云

杭州尽微供应链是抖⾳平台⽉均带货10E的TOP1“联盟团⻓”&#xff0c;是字节跳动⼀级代理商&#xff0c;巨量千川指定服务商&#xff0c;拥有商品库9万&#xff0c;是⾏业领先的电商供应链平台&#xff0c;达⼈陪跑机构。 杭州尽微供应链以天猫、京东抖音电商业务为依托&#x…

论文解读:Self-Promoted Supervision for Few-Shot Transformer

文章汇总 存在的问题 在没有归纳偏差的情况下&#xff0c;vit通常在只有少数标记训练数据可用的few-shot学习机制下学习低质量令牌依赖关系&#xff0c;这在很大程度上导致了上述性能下降。 动机 cnn的归纳偏置并不天生就适用于vit&#xff0c;也不能很好地增强和加速vit中…

Signal 即将成为JavaScript的一部分

什么是响应性&#xff1f; 在过去的几年中&#xff0c;响应性成为了所有现代前端框架以及React库的核心。 对于不熟悉前端开发的人来说&#xff0c;起初这可能是一个令人困惑的概念&#xff0c;因为它改变了常规的、自上而下的、从调用者到被调用者的顺序工作流。 在响应性范…

最近很火的粘土滤镜被玩坏了,教你用AI绘画SD免费无限制使用,附教程!

大家好&#xff0c;我是阿威。 最近在小红书上&#xff0c;“粘土特效”、“粘土滤镜”异常爆火&#xff0c;被网友玩出了花。 原来&#xff0c;一款海外修图工具——Remini&#xff08;类似妙鸭相机&#xff09;上线AI滤镜功能&#xff0c;其中就包括粘土滤镜&#xff0c;非常…