当前位置: 首页 > news >正文

记录|.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通信的实现

本文记录源自&#xff1a;B站视频 实验结果&#xff1a;跟视频做下来是没有问题的。能运行。 自己补充做了视频中未实现的读取和写入数据部分【欢迎小伙伴指正不对的地方】 目录 前言一、项目Step1. 创建项目Step2. 创建动态图片展示Step3. 创建图片型按钮Step4. 创建下拉框Ste…...

微服务实战系列之玩转Docker(二)

前言 上一篇&#xff0c;博主对Docker的背景、理念和实现路径进行了简单的阐述。作为云原生技术的核心之一&#xff0c;轻量级的容器Docker&#xff0c;受到业界追捧。因为它抛弃了笨重的OS&#xff0c;也不带Data&#xff0c;可以说&#xff0c;能够留下来的都是打仗的“精锐…...

Linux:信号的概念与产生

信号概念 信号是进程之间事件异步通知的一种方式 在Linux命令行中&#xff0c;我们可以通过ctrl c来终止一个前台运行的进程&#xff0c;其实这就是一个发送信号的行为。我们按下ctrl c是在shell进程中&#xff0c;而被终止的进程&#xff0c;是在前台运行的另外一个进程。因…...

云监控(华为) | 实训学习day2(10)

spring boot基于框架的实现 简单应用 - 用户数据显示 开发步骤 第一步&#xff1a;文件-----》新建---项目 第二步:弹出的对话框中,左侧选择maven,右侧不选任何内容. 第三步&#xff0c;选择maven后&#xff0c;下一步 第4步 &#xff1a;出现对话框中填写项目名称 第5步&…...

数据结构第35节 性能优化 算法的选择

算法的选择对于优化程序性能至关重要。不同的算法在时间复杂度、空间复杂度以及适用场景上有着明显的差异。下面我将结合具体的代码示例&#xff0c;来讲解几种常见的算法选择及其优化方法。 示例 1: 排序算法 场景描述: 假设我们需要对一个整数数组进行排序。 算法选择: …...

每天一个数据分析题(四百三十六)- 正态分布

X为服从正态分布的随机变量N(2, 9), 如果P(X>c)P(X<c), 则c的值为&#xff08;&#xff09; A. 3 B. 2 C. 9 D. 2/3 数据分析认证考试介绍&#xff1a;点击进入 题目来源于CDA模拟题库 点击此处获取答案 数据分析专项练习题库 内容涵盖Python&#xff0c;SQL&…...

跟我学C++中级篇——虚函数的性能

一、虚函数性能 一般来说&#xff0c;面向对象的设计中&#xff0c;继承和多态是其中两个非常重要的特征。从使用的过程来看&#xff0c;一般应用到继承的&#xff0c;使用多态的可能性就非常大。而多态的实现有很多种&#xff0c; 但开发者通常认为的多态&#xff08;动多态&…...

trl - 微调、对齐大模型的全栈工具

文章目录 一、关于 TRL亮点 二、安装1、Python包2、从源码安装3、存储库 三、命令行界面&#xff08;CLI&#xff09;四、如何使用1、SFTTrainer2、RewardTrainer3、PPOTrainer4、DPOTrainer 五、其它开发 & 贡献参考文献最近策略优化 PPO直接偏好优化 DPO 一、关于 TRL T…...

GuLi商城-商品服务-API-品牌管理-品牌分类关联与级联更新

先配置mybatis分页&#xff1a; 品牌管理增加模糊查询&#xff1a; 品牌管理关联分类&#xff1a; 一个品牌可以有多个分类 一个分类也可以有多个品牌 多对多的关系&#xff0c;用中间表 涉及的类&#xff1a; 方法都比较简单&#xff0c;就不贴代码了...

【linux】服务器ubuntu安装cuda11.0、cuDNN教程,简单易懂,包教包会

【linux】服务器ubuntu安装cuda11.0、cuDNN教程&#xff0c;简单易懂&#xff0c;包教包会 【创作不易&#xff0c;求点赞关注收藏】 文章目录 【linux】服务器ubuntu安装cuda11.0、cuDNN教程&#xff0c;简单易懂&#xff0c;包教包会一、版本情况介绍二、安装cuda1、到官网…...

在 Apifox 中如何高效批量添加接口请求 Body 参数?

在使用 Apifox 进行 API 设计时&#xff0c;你可能会遇到需要添加大量请求参数的情况。想象一下&#xff0c;如果一个接口需要几十甚至上百个参数&#xff0c;若要在接口的「修改文档」里一个个手动添加这些参数&#xff0c;那未免也太麻烦了&#xff0c;耗时且易出错。这时候&…...

专业PDF编辑工具:Acrobat Pro DC 2024.002.20933绿色版,提升你的工作效率!

软件介绍 Adobe Acrobat Pro DC 2024绿色便携版是一款功能强大的PDF编辑和转换软件&#xff0c;由Adobe公司推出。它是Acrobat XI系列的后续产品&#xff0c;提供了全新的用户界面和增强功能。用户可以借助这款软件将纸质文件转换为可编辑的电子文件&#xff0c;便于传输、签署…...

车载音视频App框架设计

简介 统一播放器提供媒体播放一致性的交互和视觉体验&#xff0c;减少各个媒体应用和场景独自开发的重复工作量&#xff0c;实现媒体播放链路的一致性&#xff0c;减少碎片化的Bug。本文面向应用开发者介绍如何快速接入媒体播放器。 主要功能&#xff1a; 新设计的统一播放U…...

StarRocks on AWS Graviton3,实现 50% 以上性价比提升

在数据时代&#xff0c;企业拥有前所未有的大量数据资产&#xff0c;但如何从海量数据中发掘价值成为挑战。数据分析凭借强大的分析能力&#xff0c;可从不同维度挖掘数据中蕴含的见解和规律&#xff0c;为企业战略决策提供依据。数据分析在营销、风险管控、产品优化等领域发挥…...

VUE中setup()

在Vue中&#xff0c;setup() 函数是Vue 3.0及更高版本引入的一个重要特性&#xff0c;它是Composition API的入口点。setup() 函数用于初始化组件的状态和逻辑&#xff0c;包括定义响应式数据、方法和生命周期钩子。以下是关于setup() 函数的详细解释&#xff1a; 1. 作用与特…...

【单元测试】SpringBoot

【单元测试】SpringBoot 1. 为什么单元测试很重要&#xff1f;‼️ 从前&#xff0c;有一个名叫小明的程序员&#xff0c;他非常聪明&#xff0c;但有一个致命的缺点&#xff1a;懒惰。小明的代码写得又快又好&#xff0c;但他总觉得单元测试是一件麻烦事&#xff0c;觉得代码…...

分布式搜索引擎ES-elasticsearch入门

1.分布式搜索引擎&#xff1a;luceneVS Solr VS Elasticsearch 什么是分布式搜索引擎 搜索引擎&#xff1a;数据源&#xff1a;数据库或者爬虫资源 分布式存储与搜索&#xff1a;多个节点组成的服务&#xff0c;提高扩展性(扩展成集群) 使用搜索引擎为搜索提供服务。可以从海量…...

TCP三次握手与四次挥手详解

1.什么是TCP TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的通信协议&#xff0c;属于互联网协议族&#xff08;TCP/IP&#xff09;的一部分。TCP 提供可靠的、顺序的、无差错的数据传输服务&…...

【Windows】操作系统之任务管理器(第一篇)

一、操作系统简介 Windows操作系统是由微软公司&#xff08;Microsoft&#xff09;开发的一款图形操作系统&#xff0c;它以其强大的功能和广泛的用户基础&#xff0c;成为了目前世界上用户使用最多、兼容性最强的操作系统之一。以下是关于Windows操作系统的详细介绍&#xff…...

图同构的必要条件

来源&#xff1a;离散数学...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...