前言

大家好,我是wacky。上一篇我们聊了工控的"实时"——为什么工控的实时不是"快"而是"确定"。那么理解实时性之后,下一步就是理解PLC的扫描周期,因为扫描周期是PLC实时性的具体实现机制。

很多做上位机的.NET开发者觉得扫描周期是PLC工程师的事,跟自己没关系。这是一个认知误区。你的上位机通过Modbus或OPC UA读PLC数据,什么时候读、读多快、读到的是不是最新值——这些全跟扫描周期有关。不理解扫描周期,你的通信代码就是在"盲读"。

PLC的三步循环

PLC的工作方式可以用三个字概括:读、算、写。它不像PC上的程序那样有各种线程、事件、中断,它就是老老实实地循环执行这三步:

第一步,输入采样。PLC扫描所有输入端口的状态——传感器通没通、按钮按没按、温度是多少。这些状态被读取到一个叫"输入映像寄存器"的内存区域里。这一步是"快照"——在整个扫描周期内,输入映像寄存器的值不会变,即使物理输入变了,也要等下一个周期才更新。

第二步,程序执行。PLC按照你写的控制逻辑(梯形图、ST、FBD等),从上到下、从左到右逐行执行。执行过程中,它读的是输入映像寄存器的值(不是实时物理输入),计算结果写到"输出映像寄存器"里。注意,程序执行阶段不直接驱动物理输出——它只是把结果放到输出映像寄存器里。

第三步,输出刷新。程序执行完毕后,PLC把输出映像寄存器的值一次性写到物理输出端口——继电器闭合、电机启动、阀门打开。

这三步走完,就是一个完整的扫描周期。然后立刻回到第一步,开始下一轮。周而复始,永不停止。

扫描周期到底有多长

这是最常被问到的问题。答案是:取决于PLC型号和程序复杂度。

小型PLC(比如汇川H1U/H2U、三菱FX系列),简单逻辑控制程序的扫描周期通常在1-10毫秒。中大型PLC(比如汇川EVO系列、西门子S7-1500),处理能力更强但程序也更大,扫描周期通常在几毫秒到几十毫秒。如果程序里有大循环、浮点运算、通信任务,扫描周期可能拉长到几十甚至上百毫秒。

这里有一个关键点:扫描周期不是固定的。同一个PLC,程序越复杂,扫描周期越长。加了一段循环、加了一个PID运算、加了一个通信任务,扫描周期就变长了。所以工控项目调试时,"监控扫描周期"是常规操作。在汇川iFA Evolution软件平台里,可以直接查看当前扫描周期,如果你发现扫描周期突然变长,通常意味着程序有问题:可能是某段逻辑被频繁触发,也可能是通信任务阻塞了主循环。

扫描周期为什么影响上位机

现在说回重点——扫描周期跟.NET上位机开发者有什么关系。

关系在通信层。你的上位机通过Modbus或OPC UA读PLC数据,本质上读的是PLC内存里的值。但PLC的内存值什么时候更新?在扫描周期的"输入采样"阶段更新输入,在"程序执行"阶段更新中间变量,在"输出刷新"阶段更新输出。

这意味着:如果你在PLC刚做完输入采样之后去读数据,读到的是最新值。如果你在PLC正在执行程序的时候去读,读到的可能是上一个周期的旧值。

对于大多数应用来说,这可能无所谓,差几毫秒的数据延迟,温度还是那个温度,压力还是那个压力。但对于高速场景,比如运动控制、高速采集等等,几毫秒的延迟就可能导致数据不准。

更关键的问题是轮询频率。上一篇提到过:如果你的轮询频率高于PLC扫描频率,你读到的数据就会有重复。这是因为PLC还没更新你就来读了,读到的是上一次的值,这就导致了你会困惑"为什么数据没变化"。

Modbus和OPC UA在扫描周期下的差异

Modbus是主从轮询模式,你的上位机主动发请求,PLC被动响应。你什么时候读、读什么地址,完全由上位机控制。这种方式的好处是简单可控,坏处是你必须自己处理"什么时候读"的问题。如果你100毫秒读一次,而PLC扫描周期是20毫秒,那你在5个扫描周期里只取了1个快照,中间4个周期的数据丢了。如果你10毫秒读一次,而PLC扫描周期是20毫秒,那就有一半的请求读到的是重复值。

OPC UA有订阅模式,可以不用轮询,PLC在数据变化时主动通知你。但"数据变化"的检测仍然受扫描周期限制,PLC在每次扫描周期的程序执行阶段才会更新变量值,OPC UA服务端检测到值变化后才会推送通知。所以即使用了OPC UA订阅,你收到的数据更新频率最快也只等于PLC扫描频率,不可能更快。

这就是为什么上一篇说"轮询周期建议≥2倍PLC扫描周期",这不是为了省带宽,是因为比扫描频率更快地读数据没有意义。

一个实战场景:温度采集的采样率选择

把前面的概念落到一个具体场景。假设你在做一个反应釜温度监控系统:

PLC侧:汇川EVO系列PLC,扫描周期约10毫秒。温度传感器通过模拟量模块接入PLC,PLC每个扫描周期(10ms)读一次温度值,放到寄存器D100里。

上位机侧:你的.NET程序需要读取D100的温度值,在界面上画一条实时曲线。

问题来了:你该多久读一次?

方案A:每10毫秒读一次(等于扫描周期)。理论上你能拿到每一次扫描的温度值。但实际操作中,Modbus TCP的请求-响应往返时间通常在5-20毫秒,你很难稳定地做到10毫秒一次的读取。而且这么高的频率会占用大量网络带宽和CPU。

方案B:每100毫秒读一次(10倍扫描周期)。每秒10个数据点,对于温度这种变化缓慢的物理量完全够用。温度不会在100毫秒内剧烈跳变,如果有,说明你的传感器或控制系统有问题,不是采样率的问题。

方案C:每1000毫秒读一次(100倍扫描周期)。每秒1个点,曲线会明显不流畅。对于操作员监控来说勉强够用,但如果要做趋势分析或报警判断,1秒的延迟可能太大了。

正确答案是方案B。温度是慢变量,100毫秒采样率既能画出流畅曲线,又不会浪费资源。但如果是振动监测:每秒几千次的频率变化,100毫秒采样率就完全不够了,那种场景需要PLC侧做高速采集,上位机批量读取。

扫描周期与上位机架构设计

理解了扫描周期,你就能在上位机架构设计时做出正确的决策:

通信层:轮询频率匹配被测物理量的变化速率,而不是盲目追求高频。温度100ms,压力100ms,流量200ms,开关量50ms。不同的量用不同的频率,不要一个定时器全部100ms扫一遍。

数据层:时序数据库的写入频率应该等于通信层的读取频率。你100ms读一次温度,InfluxDB就100ms写一个点。不要在数据层做降采样,把原始数据存下来,查询时再聚合。

展示层:界面刷新频率不需要等于通信频率。你100ms读一次温度,但界面500ms刷新一次就够了。人眼是分辨不出100ms和500ms的区别,但CPU能分辨出5倍的开销差异。

这三个频率的解耦:通信频率、存储频率、刷新频率,是工控上位机性能优化的关键。很多新手把三者绑在一起,读一次就写一次就刷一次,结果界面卡、数据库爆、CPU高。分开之后,系统就丝滑了。

后记

扫描周期是PLC的灵魂:它决定了PLC的实时性、确定性、和响应能力。对上位机开发者来说,理解扫描周期不是为了去写PLC程序,而是为了在通信、存储、展示三个层面做出正确的频率决策。

你们在上位机开发过程中有没有遇到上述这些坑?可以在评论区聊一聊。

有读者朋友留言说想了解一下下位机和固件相关的基础概念,所以我们下一篇就从这些内容开始入手,敬请期待!

本文首发于我的公众号【wacky的碎碎念】,欢迎关注追更!

qrcode_for_gh_7c93e745425f_258

 


原文地址: https://www.cveoy.top/t/topic/qHiO 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录