记录|.NET上位机开发和PLC通信的实现
本文记录源自:B站视频
实验结果:跟视频做下来是没有问题的。能运行。
自己补充做了视频中未实现的读取和写入数据部分【欢迎小伙伴指正不对的地方】
目录
- 前言
- 一、项目
- Step1. 创建项目
- Step2. 创建动态图片展示
- Step3. 创建图片型按钮
- Step4. 创建下拉框
- Step1~4的效果展示
- Step5. 编程
- `实体类`
- `操作类`
- `Main函数`
- Step1~5的效果展示
- `Main函数`
- 最终效果:
- 二、补充内容
- 1. FlatStyle属性
- 三、读取和写入一个浮点数
- Step6. 建立图形
- Step7. 编程
- `操作类`
- `Main函数`
- Step1~7的效果展示
- 更新时间线
前言
在练习完基本的C#和.NET使用后,做下了记录|C#连接PLC通讯
现在打算跟B站视频做一个简单的C#项目。这篇文章做这个记录。
一、项目
Step1. 创建项目
- 是个Windows窗口(.NET framework)
Step2. 创建动态图片展示
- 首先,在自己项目的Debug文件位置处,去建立个images文件,用于存放图片【其中,Debug文件是指自己调试的程序;Release文件是指上线使用的程序】
- 动图需要准备一张.png和一张.gif
- 在使用PictureBox组件,将图片添加进去,将组件的属性中的SizeMode改为Zoom
Step3. 创建图片型按钮
- 目的:实现一个具有图片的按钮【本质是button控件】
- 先对button中FlatSytle属性改为Flat,之后才能使用Image属性。
据此创建出两个图片按钮: - 连接PLC按钮
- 启动设备按钮
Step4. 创建下拉框
- ComboBox组件
在里面提前设定好两个值:S71200和S71500
Step1~4的效果展示
Step5. 编程
实体类
- 创建Models文件夹,存放实体类EquipState。
- 实体类类名:EquipState
- 只存放方法名,等待实现
EquipState类:
namespace thinger.ProjectDemo
{/// <summary>/// 生产设备状态实体类/// </summary>internal class EquipState{public bool Start { get; set; }//设备启动public bool Stop { get; set; }//停止public bool Task1 { get; set; }//任务1public bool Task2 { get; set; }public bool Task3 { get; set; }public bool RunState { get; set; }//运行状态:1,正常 0 报警public ushort RunModel { get; set; }//运行模式:1,普通 2,加速 3,满载public float SiteData1 { get; set; }//位置数据1public float SiteData2 { get; set; }//位置数据2public float SiteData3 { get; set; }//位置数据3public float SpeedData1 { get; set; }//速度数据1public float SpeedData2 { get; set; }//速度数据2}
}
操作类
- 创建个Manager文件,该文件夹下面创建EquipControlManager类
- 类中的基本3个方法:ConnectPLC、ClosePLC、WriteDataToPLC
- ConnectPLC,实现对PLC的连接并返回提示。因此,返回类型位string。
EquipControlMananger类:
namespace thinger.ProjectDemo.Manager
{/// <summary>/// 设备操作类/// </summary>internal class EquipControlManager{//先对Plc对象进行声明private Plc s7NetPlc = null;/// <summary>/// 连接PLC/// </summary>/// <param name="ipAddress"></param>/// <param name="cpuType"></param>/// <returns></returns>public string ConnectPLC(string ipAddress, string cpuType){try{//CpuType是个enum,枚举类型,因此,需要对string类型进行转换CpuType currentCpuType = (CpuType)Enum.Parse(typeof(CpuType), cpuType, true);s7NetPlc = new Plc(currentCpuType, ipAddress, 0, 0);s7NetPlc.Open();return "PLC连接成功";}catch (Exception ex){return $"PLC连接失败,{ex.Message}";}}/// <summary>/// 关闭PLC/// </summary>public void ClosePLC(){s7NetPlc.Close();}/// <summary>/// 按照指定地址,写入数据【位、字节、字、双字】/// </summary>/// <param name="varAddress"></param>/// <param name="varValue"></param>/// <returns></returns>public string WriteDataToPLC(string varAddress, object varValue){lock (this){try{this.s7NetPlc.Write(varAddress, varValue);return "写入数据成功";}catch (Exception ex){return $"写入数据失败,{ex.Message}";}}}}
}
Main函数
namespace thinger.ProjectDemo
{public partial class FrmMain : Form{private EquipControlManager controlManger=new EquipControlManager();public FrmMain(){InitializeComponent();}/// <summary>/// 打开和关闭PLC/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnPLCConnect_Click(object sender, EventArgs e){//Tag记录的是之前的开关状态,只有off和on//如果之前off,那么改为onif (this.btnPLCConnect.Tag.ToString().Equals("off")){string connectManager = controlManger.ConnectPLC("192.168.0.10", this.cbbPLCType.Text);this.btnPLCConnect.Tag = "on";this.btnPLCConnect.Image = Image.FromFile("images/plcOpen.png");MessageBox.Show(connectManager);}else{controlManger.ClosePLC();this.btnPLCConnect.Tag="off";this.btnPLCConnect.Image = Image.FromFile("images/plcClose.png");}}}
}
Step1~5的效果展示
Main函数
- 添加了修改操作
/// <summary>/// 操作设备/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSwitch_Click(object sender, EventArgs e){if (this.btnPLCConnect.Tag.ToString().Equals("off")){MessageBox.Show("请先连接PLC", "操作提示");return;}//获取Tag中的地址值string[] tags = this.btnSwitch.Tag.ToString().Split('-');if (tags[0].Equals("off")){//打开冷却泵this.pictureBox1.Image = Image.FromFile("images/电机.gif");this.btnSwitch.Image = Image.FromFile("images/btnOn.png");this.btnSwitch.Tag = $"on-{tags[1]}";//修改PLC中的值controlManger.WriteDataToPLC(tags[1], true);}else{this.pictureBox1.Image = Image.FromFile("images/电机.png");this.btnSwitch.Image = Image.FromFile("images/btnOff.png");this.btnSwitch.Tag = $"off-{tags[1]}";//修改PLC中的值controlManger.WriteDataToPLC(tags[1], false);}}
最终效果:
二、补充内容
1. FlatStyle属性
- 功能:设置Windows Forms控件(如:按钮、标签等)。
- Flat:产生“平面”效果,将空间的边框移除
- Standard:默认,三维效果。
三、读取和写入一个浮点数
接着前面的Step5进行的
Step6. 建立图形
- 两个按钮+两个文本框【如下所示:红色的部分是对组件重新的取名,便于后面的编程
Step7. 编程
操作类
- 重写了一个WriteDataToPLC()方法【因为我不会用DBX0.0,DBW0,DBD0.0等用法,所以我想到直接按照 PLC.Write()的第二种重写方法,来重写】
- 一个ReadDataFromPLC()方法
public string WriteDataToPLC(int db, string varAddress, object varValue){int varAd = int.Parse(varAddress);float varVal = float.Parse(varValue.ToString());lock (this){try{s7NetPlc.Write(DataType.DataBlock, db, varAd,varVal);return "写入数据成功";}catch(Exception ex){return $"写入数据失败,{ex.Message}";}}}public string ReadDataFromPLC(int db, string varAddress){int varAd = int.Parse(varAddress);try{return s7NetPlc.Read(DataType.DataBlock, db, varAd, VarType.Real, 1).ToString();}catch(Exception ex){return $"写入数据失败,{ex.Message}";}}
Main函数
- 实现两个点击效果
private void writeDB0_Click(object sender, EventArgs e){string writeMessage = controlManger.WriteDataToPLC(1,writeDB0.Tag.ToString(),textBox_writeDB0.Text);textBox_writeDB0.Text = "";MessageBox.Show(writeMessage);}private void readDB0_Click(object sender, EventArgs e){string readMessage = controlManger.ReadDataFromPLC(1,readDB0.Tag.ToString());if (readMessage.Contains("失败")){MessageBox.Show(readMessage);return;}textBox_readDB0.Text = readMessage;}
Step1~7的效果展示
读取一个浮点:
写入一个浮点数
更新时间线
- 2024.07.15:创建文章
- 2024.07.16:补充了读取和写入一个浮点数。
相关文章:
记录|.NET上位机开发和PLC通信的实现
本文记录源自:B站视频 实验结果:跟视频做下来是没有问题的。能运行。 自己补充做了视频中未实现的读取和写入数据部分【欢迎小伙伴指正不对的地方】 目录 前言一、项目Step1. 创建项目Step2. 创建动态图片展示Step3. 创建图片型按钮Step4. 创建下拉框Ste…...
微服务实战系列之玩转Docker(二)
前言 上一篇,博主对Docker的背景、理念和实现路径进行了简单的阐述。作为云原生技术的核心之一,轻量级的容器Docker,受到业界追捧。因为它抛弃了笨重的OS,也不带Data,可以说,能够留下来的都是打仗的“精锐…...
Linux:信号的概念与产生
信号概念 信号是进程之间事件异步通知的一种方式 在Linux命令行中,我们可以通过ctrl c来终止一个前台运行的进程,其实这就是一个发送信号的行为。我们按下ctrl c是在shell进程中,而被终止的进程,是在前台运行的另外一个进程。因…...
云监控(华为) | 实训学习day2(10)
spring boot基于框架的实现 简单应用 - 用户数据显示 开发步骤 第一步:文件-----》新建---项目 第二步:弹出的对话框中,左侧选择maven,右侧不选任何内容. 第三步,选择maven后,下一步 第4步 :出现对话框中填写项目名称 第5步&…...
数据结构第35节 性能优化 算法的选择
算法的选择对于优化程序性能至关重要。不同的算法在时间复杂度、空间复杂度以及适用场景上有着明显的差异。下面我将结合具体的代码示例,来讲解几种常见的算法选择及其优化方法。 示例 1: 排序算法 场景描述: 假设我们需要对一个整数数组进行排序。 算法选择: …...
每天一个数据分析题(四百三十六)- 正态分布
X为服从正态分布的随机变量N(2, 9), 如果P(X>c)P(X<c), 则c的值为() A. 3 B. 2 C. 9 D. 2/3 数据分析认证考试介绍:点击进入 题目来源于CDA模拟题库 点击此处获取答案 数据分析专项练习题库 内容涵盖Python,SQL&…...
跟我学C++中级篇——虚函数的性能
一、虚函数性能 一般来说,面向对象的设计中,继承和多态是其中两个非常重要的特征。从使用的过程来看,一般应用到继承的,使用多态的可能性就非常大。而多态的实现有很多种, 但开发者通常认为的多态(动多态&…...
trl - 微调、对齐大模型的全栈工具
文章目录 一、关于 TRL亮点 二、安装1、Python包2、从源码安装3、存储库 三、命令行界面(CLI)四、如何使用1、SFTTrainer2、RewardTrainer3、PPOTrainer4、DPOTrainer 五、其它开发 & 贡献参考文献最近策略优化 PPO直接偏好优化 DPO 一、关于 TRL T…...
GuLi商城-商品服务-API-品牌管理-品牌分类关联与级联更新
先配置mybatis分页: 品牌管理增加模糊查询: 品牌管理关联分类: 一个品牌可以有多个分类 一个分类也可以有多个品牌 多对多的关系,用中间表 涉及的类: 方法都比较简单,就不贴代码了...
【linux】服务器ubuntu安装cuda11.0、cuDNN教程,简单易懂,包教包会
【linux】服务器ubuntu安装cuda11.0、cuDNN教程,简单易懂,包教包会 【创作不易,求点赞关注收藏】 文章目录 【linux】服务器ubuntu安装cuda11.0、cuDNN教程,简单易懂,包教包会一、版本情况介绍二、安装cuda1、到官网…...
在 Apifox 中如何高效批量添加接口请求 Body 参数?
在使用 Apifox 进行 API 设计时,你可能会遇到需要添加大量请求参数的情况。想象一下,如果一个接口需要几十甚至上百个参数,若要在接口的「修改文档」里一个个手动添加这些参数,那未免也太麻烦了,耗时且易出错。这时候&…...
专业PDF编辑工具:Acrobat Pro DC 2024.002.20933绿色版,提升你的工作效率!
软件介绍 Adobe Acrobat Pro DC 2024绿色便携版是一款功能强大的PDF编辑和转换软件,由Adobe公司推出。它是Acrobat XI系列的后续产品,提供了全新的用户界面和增强功能。用户可以借助这款软件将纸质文件转换为可编辑的电子文件,便于传输、签署…...
车载音视频App框架设计
简介 统一播放器提供媒体播放一致性的交互和视觉体验,减少各个媒体应用和场景独自开发的重复工作量,实现媒体播放链路的一致性,减少碎片化的Bug。本文面向应用开发者介绍如何快速接入媒体播放器。 主要功能: 新设计的统一播放U…...
StarRocks on AWS Graviton3,实现 50% 以上性价比提升
在数据时代,企业拥有前所未有的大量数据资产,但如何从海量数据中发掘价值成为挑战。数据分析凭借强大的分析能力,可从不同维度挖掘数据中蕴含的见解和规律,为企业战略决策提供依据。数据分析在营销、风险管控、产品优化等领域发挥…...
VUE中setup()
在Vue中,setup() 函数是Vue 3.0及更高版本引入的一个重要特性,它是Composition API的入口点。setup() 函数用于初始化组件的状态和逻辑,包括定义响应式数据、方法和生命周期钩子。以下是关于setup() 函数的详细解释: 1. 作用与特…...
【单元测试】SpringBoot
【单元测试】SpringBoot 1. 为什么单元测试很重要?‼️ 从前,有一个名叫小明的程序员,他非常聪明,但有一个致命的缺点:懒惰。小明的代码写得又快又好,但他总觉得单元测试是一件麻烦事,觉得代码…...
分布式搜索引擎ES-elasticsearch入门
1.分布式搜索引擎:luceneVS Solr VS Elasticsearch 什么是分布式搜索引擎 搜索引擎:数据源:数据库或者爬虫资源 分布式存储与搜索:多个节点组成的服务,提高扩展性(扩展成集群) 使用搜索引擎为搜索提供服务。可以从海量…...
TCP三次握手与四次挥手详解
1.什么是TCP TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,属于互联网协议族(TCP/IP)的一部分。TCP 提供可靠的、顺序的、无差错的数据传输服务&…...
【Windows】操作系统之任务管理器(第一篇)
一、操作系统简介 Windows操作系统是由微软公司(Microsoft)开发的一款图形操作系统,它以其强大的功能和广泛的用户基础,成为了目前世界上用户使用最多、兼容性最强的操作系统之一。以下是关于Windows操作系统的详细介绍ÿ…...
图同构的必要条件
来源:离散数学...
Django获取request请求中的参数
支持 post put json_str request.body # 属性获取最原始的请求体数据 json_dict json.loads(json_str)# 将原始数据转成字典格式 json_dict.get("key", "默认值") # 获取数据参考 https://blog.csdn.net/user_san/article/details/109654028...
kotlin compose 实现应用内多语言切换(不重新打开App)
1. 示例图 2.具体实现 如何实现上述示例,且不需要重新打开App ①自定义 MainApplication 实现 Application ,定义两个变量: class MainApplication : Application() { object GlobalDpData { var language: String = "" var defaultLanguage: Strin…...
记录些MySQL题集(16)
MySQL 存储过程与触发器 一、初识MySQL的存储过程 Stored Procedure存储过程是数据库系统中一个十分重要的功能,使用存储过程可以大幅度缩短大SQL的响应时间,同时也可以提高数据库编程的灵活性。 存储过程是一组为了完成特定功能的SQL语句集合&#x…...
【算法基础】Dijkstra 算法
定义: g [ i ] [ j ] g[i][j] g[i][j] 表示 v i v_i vi 到 $v_j $的边权重,如果没有连接,则 g [ i ] [ j ] ∞ g[i][j] \infty g[i][j]∞ d i s [ i ] dis[i] dis[i] 表示 v k v_k vk 到节点 v i v_i vi 的最短长度, …...
使用 Flask 3 搭建问答平台(三):注册页面模板渲染
前言 前端文件下载 链接https://pan.baidu.com/s/1Ju5hhhhy5pcUMM7VS3S5YA?pwd6666%C2%A0 知识点 1. 在路由中渲染前端页面 2. 使用 JinJa 2 模板实现前端代码复用 一、auth.py from flask import render_templatebp.route(/register, methods[GET]) def register():re…...
pycharm如何debug for循环里面的错误值
一般debug时,在for循环里面的话,需要自己一步一步点。如果循环几百次那种就比较麻烦。此时可以采用try except的方式来解决 例子如下 #ptyhon debug for循环的代码 num[1,2,3,s,4] ans0 for i in num:try:ansiexcept:print(错误) print(ans) 结果如下&a…...
解决网页中的 video 标签在移动端浏览器(如百度访问网页)视频脱离文档流播放问题
问题现象 部分浏览器视频脱离文档流,滚动时,视频是悬浮出来,在顶部播放 解决方案 添加下列属性,可解决大部分浏览器的脱离文档流的问题 <videowebkit-playsinline""playsInlinex5-playsinlinet7-video-player-t…...
.Net--CLS,CTS,CLI,BCL,FCL
1.什么是CLS? 所以.NET专门为此参考每种语言(例如C# ,VB,F#)并找出了语言间的共性,然后定义了一组规则,开发者都遵守这个规则来编码,那么代码就能被任意.NET平台支持的语言所通用。 而与其说是规则&#x…...
Stable Diffusion:质量高画风清新细节丰富的二次元大模型二次元插图
今天和大家分享一个基于Pony模型训练的二次元模型:二次元插图。关于该模型有4个不同的分支版本。 1.5版本:loar模型,推荐底模型niji-动漫二次元4.5。 xl版本:SDXL模型版本 mix版本:光影减弱,减少SDXL版本…...
数读MEME之争:以太坊获更高价值共识,抢占热点成Solana流量密码
在当前显著的加密牛市中,以太坊和Solana之间的竞争不仅在币价表现上显而易见,生态发展方面也备受关注。特别是在这轮MEME行情中,双方阵营的MEME代币呈现出不同的特点和趋势。 市场表现对比 以太坊的优势: 市场份额和认可度更高&…...
北京出名做网站的公司/东莞网站制作
1.概率图模型简介: 概率图模型是图灵奖获得者Pearl开发出来的用图来表示变量概率依赖关系的理论。概率图模型理论分为概率图模型表示理论,概率图模型推理理论和概率图模型学习理论。 概率图理论共分为三个部分,分别为概率图模型表示理论&…...
科讯cms怎么做网站地图/深圳搜索优化排名
如何快速清理 docker 资源 原文:如何快速清理 docker 资源如果经常使用 docker,你会发现 docker 占用的资源膨胀很快,其中最明显也最容易被察觉的应该是对磁盘空间的占用。本文将介绍如何快速的清理 docker 占用的系统资源,具体点说就是删除那…...
做网站加一个定位功能要多少钱/百度seo收费
备份需求和rman备份 oracle数据库的备份相关问答: 1)备份时数据库处于何种状态? 备份时数据库处于OPEN状态,这样数据库可以正常工作。 2)备份的数据备份在什么地方? 备份在本地磁盘。 3)备份的存…...
不锈钢网站建设哪家好/海外网站推广的公司
使用tomcat搭建HTTP文件下载服务器 用简单的方法实战演练搭建http服务器(Windows上) 超简单——自己搭建ftp服务器(python nodejs)...
wordpress音乐页面/如何快速推广app
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。 示例 1: 输入:nums [4,1,4,6] 输出:[1,6] 或 [6,1] 示例 2:…...
网站怎么做数据分析/搜索引擎排名2020
python 中 setattr() 函数 和 getarrr() 函数...