我用PYQT5做的第一个实用的上位机项目(六)
将之前的画面和代码用复制粘贴的方法复制四份,就完成了整个主画面和主程序的基本构建。
下面的工作是关于PLC和通信。
上位机项目,其与PLC通信的模式很多都是这样的:在没有操作和设置的平常显示界面,按照预定周期从PLC读取当前页面需要刷新的部件的数据字节,并对字节进行解码和刷新。当有了设置和改变的动作,需要改写PLC的内部数据时,把需要改写的地址和数据发送给PLC。
查阅了很多资料,关于上位机与PLC通信这块,大多数都是针对西门子的,并且使用了Snap7。使用Snap7确实可以使问题简化,但是如果PLC不是西门子品牌就无能为力了。即使是西门子PLC,还要对PLC的内部寄存器地址、指针、语句编程这些知识进行深入学习才能灵活应用。像我这样的以搞控制为主的,PLC和上位机编程都只是简单用用的人,就感觉很吃力。一句题外话,玩了三十年工控,到目前为止PLC程序也做过上千个了,大多数时候都还是梯形图和直接地址访问,每每看到那些大公司的专业PLC编程工程师熟练地使用间接寻址和语句编程,都觉得很汗颜。所以,这里采用了通用的tcp ip的socket通信模式,自定义报文,直接地址读写,好处是提高了通用性、降低了技术难度,坏处是PLC端需要额外编写一些通信程序,不过PLC的程序全部都是直接地址访问,用不到考虑指针和寄存器地址映射之类的,编程也可以用梯形图,属于简单劳动。
既然是自定义报文,每个人完全可以根据PLC的品牌型号以及自己的习惯来约定报文的内容。我这里的范例,上位机发送到PLC的报文采用固定长度,每个报文长度12个字节,前6个字节是功能码,后面4个字节是数据内容,最后2个字节与第一第二个字节内容相同,作为结束符用来断帧和校验,防止TCP数据粘连。
1、对PLC的例行的周期查询,报文第1、2字节为字符“A0”,第3字符是画面编号,第4、5是对应的周期,第6是周期时间的单位,7-10字节用字符“0”填充,11、12与第1、2字节相同为字符“A0”。例如:报文A0101S0000A0,其含义是编号1的画面一秒周期的查询。至于本次需要查询哪些部件的变量,这些变量的类型和字节长度都是提前规划好并在PLC端写好了对应的子程序,当PLC端收到报文并且报文头6字节与字符串“A0101S”比对成功,报文的第11、12字节与字符串“A0”比对成功,就执行相应的子程序把上位机需要的地址的内容复制到PLC的通信发送缓冲区打包并发送至上位机,上位机收到返回的数据后,按照提前规划的变量的类型和字节长度解码并刷新显示界面。
总之,所有的需要查询的内容都是已知和提前规划的,PLC端只需要比对收到的报文字符串前6个字节和第11、12 字节,调用对应的子程序将需要的地址的数据复制到送缓冲区打包发送。
举例:画面2,每10秒钟需要读取PLC的MW10、VD100、QB0这几个变量,那么每隔10秒钟,发送报文字符串“A0210S0000A0”到PLC,PLC收到报文,前6个字节与“A0210S”比对成功,第11、12字节与字符串“A0”比对成功,执行对应的子程序将MW10、VD100、QB0这几个变量的值写入发送缓冲区打包并发送至上位机。上位机收到返回数据,按照提前规划的“整数、实数、字节”(即MW10、VD100、QB0这几个变量的类型)的顺序解码数据并分配刷新各个部件。由于采用了约定自定义报文的方式,PLC端对所有地址的操作都是直接的地址访问,用不着考虑寄存器实际地址和指针,不同的PLC,上位机的报文也是通用的(唯一需要考虑大小端编码)。
另,各个周期的查询内容是长周期包含短周期,例如10秒周期的查询包含了1秒周期的查询内容。
2、对PLC的写操作,由于本例项目很小,需要写的数据并不多,所以也采用了约定报文的方式,如果数据量较大,这种方式就不太方便,必须用到指针了。话又说回来,之所以费劲巴交地自己写代码,就是因为项目小,利润低,没法用正版scada,如果是数据很多的大项目,有足够的利润支撑就直接用正版wincc、组态王了,那功能又强大,使用又简便。至于盗版嘛,看您高不高兴了,不在讨论范围内。
言归正传,本例中,对PLC的写操作,第1、2字节为字符“B0”,第3、4字节为事件编号,例如可以将“启动/停止缓凝剂“事件定义为01事件,5、6字节用字符0填充,7、8、9、10字节为数据内容,这里的数据内容之所以用了4个字节是因为有可能传输的最长数据格式是浮点数,长度为4个字节。对于长度小于4个字节的数据类型,靠前的字节为有效数据,后面的用b'\x00'填充。第11、12字节为字符“B0”,与第1、2字节相同,作为结束符用来断帧和校验,防止TCP数据粘连。
当PLC收到报文后,并且第1、2字节和第11、12字节与字符”B0“比对成功,就读取第3、4字节的事件编号,执行相应编号的子程序,执行约定的操作。
举例:上位机发送报文b'B001\x00\x00\x01\x00\x00\x00B0',这个报文的开头和结尾为B0,表示要对PLC写操作,事件编号为第3、4字节01,5、6字节无意义,第7字节为数据位b'\x01',将其约定为”启动缓凝剂“,在PLC程序里,实现该事件的的方法是将Q0.0置位,编写并执行该子程序(或网络)即可。
至此,通信报文的基本规划就完成了,还可以加入一些别的约定报文,例如报警、故障什么的,看个人需要了。总结一下,本例采用了基于tcp ip协议的socket通信(这个叫法貌似不是很专业,管他呢,我也不是专业的程序员,能用就好),PLC作为服务器,上位机作为客户端。所有的通信均由上位机发起,上位机的程序中有系统定时器,周期地查询PLC中的数据,PLC根据收到的报文内容做出响应,并根据约定代码的不同执行不同的子程序或网络,对PLC内部数据进行读写和发送。在任何时候,上位机发给PLC的报文都是固定长度的,报文的首2和末2字节内容相同,作为事件定义和断帧校验。tcp通信是基于”流“的,就没有严格意义上的”帧“,tcp通信的最大隐患就是数据帧长度的不确定性,很容易造成接收缓冲区数据排序混乱,这也是我之前做过的很多PLC通信项目遇到过的问题,固定PLC接收通信数据的长度并把通信报文中加入断帧和校验字符,就可以很好地解决这个问题。
下面的工作就是编写实际的程序了。
相关文章:

我用PYQT5做的第一个实用的上位机项目(六)
将之前的画面和代码用复制粘贴的方法复制四份,就完成了整个主画面和主程序的基本构建。 下面的工作是关于PLC和通信。 上位机项目,其与PLC通信的模式很多都是这样的:在没有操作和设置的平常显示界面,按照预定周期从PLC读取当前页…...

【高级语言程序设计】python函数式编程(一)
基础知识 Python函数式编程的主要内容包括以下几个方面: (1)函数作为一等公民:在函数式编程中,函数被视为一等公民,可以像其他数据类型一样被传递、赋值以及作为返回值。 (2)不可变数据:函数式编程鼓励使用不可变数据…...

使用python查找指定文件夹下所有xml文件中带有指定字符的xml文件
文件夹目录如下(需要递归删除文件夹下的.DS_Store文件): labels文件夹下面是xml文件: import os import os.pathpath "name/labels" files os.listdir(path) # 得到文件夹下所有文件名称 s []for xmlFile in files:…...
flutter实现透明appbar(一)
前言 在项目中如何实现透明的appbar,方式一: 使用stack和positioned定位功能把appbar定位到页面的最上面, 实现 实现 Widget build(BuildContext context) {return Scaffold(body: Stack(children: [_homePage(), _appBar()],),);}_appbar…...

(四)正点原子STM32MP135移植——u-boot移植
一、概述 u-boot概述就不概述了,u-boot、kernel、dtb三件套,dddd 经过国庆艰苦奋战,已经成功把所有功能移植好了 二、编译官方代码 进入u-boot的目录 2.1 解压源码、打补丁 /* 解压源码 */ tar xf u-boot-stm32mp-v2022.10-stm32mp-r1-r0.…...

[计算机入门] 应用软件(办公类)
3.19 应用软件(办公类) 3.19.1 Microsoft office办公软件套件 Microsoft Office 是一套广泛使用的办公软件套件,由Microsoft公司开发和发布。它包含了多个应用程序,用于处理各种办公任务。以下是Office常见的几个应用程序: Microsoft Word…...

基于安卓android微信小程序音乐播放器
运行环境 小程序前端框架:uniapp 小程序运行软件:微信开发者 后端技术:javaSsm(SpringSpringMVCMyBatis)vue.js 后端开发环境:idea/eclipse 数据库:mysql 项目介绍 音乐播放器小程序的设计主要是对系统所要实现的功能进行详细考虑,确定所要…...
Java的指针、引用与C++的指针、引用的对比
笔者前两天在参加菜鸟面试的时候被面试官问到了这个问题,由于只在本科程序设计课上学过C,已经好久没有开发实际项目,所以对C相关的指针以及引用的记忆较为模糊,在此进行一定的知识汇总与梳理。 我们以面试中出现的问题为例来进行整…...

串级/级联控制知识点整理
串级控制系统是改善控制质量的有效方法之一,在过程控制中得到了广泛的应用。所谓串级控制,就是采用两个控制器串联工作,外环控制器的输出作为内环控制器的设定值,由内环控制器的输出去操纵控制阀,从而对外环被控量具有…...

数据产品读书笔记——认识数据产品经理
🌻大家可能听说的更多是产品经理这个角色,对数据产品经理可能或多或少了解一些,但又不能准确的描述数据产品经理的主要职能和与其他产品的不同,因此通过读一些书来对数据产品经理有一个准确且全面的认知。 目录 1. 数据的产品分类…...

从 0 到 1 ,手把手教你编写《消息队列》项目(Java实现) —— 创建虚拟机
文章目录 一、虚拟机二、关于消息的API发布消息直接交换机 DIRECT 转发规则扇出交换机 FANOUT 转发规则主题交换机 TOPIC 转发规则匹配规则Router类 订阅消息消费者队列如何给订阅的消费者发送消息自动发送消息至订阅者 应答消息 三、代码编写 一、虚拟机 接下来要创建虚拟机,…...
GIT版本控制--前言
欢迎来到《GIT版本控制》专栏!在当今软件开发和协作的世界中,版本控制是不可或缺的工具之一。无论您是一名初学者,一位经验丰富的开发者,还是一个项目团队的成员,都有可能会受益于对GIT的深入了解。 GIT是一个强大的分…...
由于 MAC 地址的问题,导致网络不通的原因和分析
由于 MAC 地址的问题,导致网络不通的原因和分析 将现象及原因分析发给大家,供大家参考,以后有类似问题时有个解决问题的参考开发板网络不通,也抓不到包,折腾了好久,将电脑和开发板用网线直连,结…...
游戏开发中的设计模式
单例模式 实例化单一对象,懒加载 //单例模式 class GameManagerSingleton {private constructor(){}private static instance:GameManagerSingleton;public static Instance(){if(!GameManagerSingleton.instance){this.instance new GameManagerSingleton();}re…...

React核心原理与实际开发
学习目标 React是啥? 官方定义:将前端请求获取到的数据渲染为HTML视图的JavaScript库。 一、React入门 1、React项目创建 直接创建react,使用初始化会创建package.json npm init -y再安装 2、React基本使用 使用纯JS创建ReactDOM&#…...

Springboot+vue的企业OA管理系统(有报告),Javaee项目,springboot vue前后端分离项目。
演示视频: Springbootvue的企业OA管理系统(有报告),Javaee项目,springboot vue前后端分离项目。 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的企业OA管理系统,采用M(m…...

3、字符设备驱动框架和开发步骤
一、Linux内核对文件的分类 Linux的文件种类 1、-:普通文件2、d:目录文件3、p:管道文件4、s:本地socket文件5、l:链接文件6、c:字符设备7、b:块设备 Linux内核按驱动程序实现模型框架的不同&…...

[MySQL]基础篇
文章目录 1. MySQL基本使用1.1 MySQL的启动和登录1.1.1 MySQL的启动1.1.2 MySQL的客户端连接 1.2 数据模型 2. SQL2.1 SQL类型2.1.1 数值类型2.1.2 字符串类型2.1.3 日期类型 2.2 DDL2.2.1 数据库操作2.2.2 表操作 - 查询2.2.3 表操作 - 创建表2.2.4 表操作 - 修改 2.3 DML2.3.…...
Meta Semantic Template for Evaluation of Large Language Models
本文是LLM系列文章,针对《Meta Semantic Template for Evaluation of Large Language Models》的翻译。 大型语言模型评估的元语义模板 摘要1 引言2 相关工作3 方法4 实验5 结论 摘要 大型语言模型(llm)是否真正理解语言的语义,或者只是记住训练数据?…...

Git相关知识(1)
目录 1.初识Git 1.基础知识 2.centos中下载 2.基本操作 1.创建本地仓库 2.配置本地仓库 3.版本库、工作区、暂存区 4.添加文件 5.add和commit对git文件的作用 6.修改文件 7.版本回退 8.撤销修改 9.删除文件 3.分支操作 1.HEAD与分支 2.创建分支 3.删除分支 …...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...