博途PLC跨小时统计:T#5S定时采样与R_TRIG上升沿检测如何选

发布时间:2026/10/14 16:01:21
博途PLC跨小时统计:T#5S定时采样与R_TRIG上升沿检测如何选 做跨小时统计最怕的不是逻辑写错而是整点那一秒的数据对不上。前两天群里又有人问统计触发用T#5S这种定时器和用R_TRIG上升沿检测到底哪种稳这个问题我一看就懂因为我在博途里把两种写法都实际跑过当时为了给某产线做每小时产量报表前前后后折腾了一周。今天把这两种方案的原理、代码、边界处理方式、还有踩过的坑一次性说清楚。如果你也在做跨小时统计或者正在纠结T#5S和R_TRIG怎么选这篇可以直接当参考。1. 先把跨小时统计这件事拆透1.1 跨小时统计到底在统计什么跨小时统计在工控现场太常见了每台设备每个小时的产量、能耗、运行时间到整点自动归档上一小时的数据进报表当前小时从零重新累计。听起来简单真正做起来你会发现整点切割这件事远比想象中麻烦。难点主要集中在三个地方。第一PLC程序是循环扫描执行的读到的系统时间总是滞后于真实时间你永远没法像单片机中断那样在00:00:00.000这个精确时刻执行一段代码。第二统计源分两种一种是仪表累计值比如电表电量、流量计累计量、编码器累计位置另一种是离散脉冲比如光电开关出来的工件计数脉冲。这两种源的统计逻辑完全不同硬套容易出事。第三跨小时有时候还会顺带跨天、跨月半夜0点那一下如果逻辑没写全报表日期就会串。所以跨小时统计的核心任务其实就是一句话在时间边界附近把数据切得干净、切得准既不重复也不丢失。1.2 T#5S方案和R_TRIG方案分别是什么思路T#5S方案是“周期轮询统计”的思路。程序里放一个定时器每隔5秒触发一次统计块每次触发时读一次仪表累计值和上一次的差值累加到当前小时里。这种做法的关键点在于你不是在“数脉冲”而是在“算增量”只要你两次读取之间不丢累计值这个月的总增量就是对的。R_TRIG方案是“边沿触发统计”的思路。R_TRIG是上升沿检测指令当输入信号从0变成1的那一个扫描周期输出一个扫描周期的脉冲。它一般用在两个地方一个是检测离散计数信号光电开关来一个工件上升沿加一另一个是检测时间边界比如当前小时值从19变成20的那一瞬间产生一个“整点到了”的脉冲然后执行归档和清零。很多人把这两个方案对立起来总想着二选一。我实际用下来发现真正常用的跨小时统计往往是两者配合而不是互相替代。但要说清楚为什么得先把它们的稳定性来源分析明白。2. 稳定性到底差在哪轮询误差与边沿丢失2.1 T#5S定时采样的稳定性分析T#5S定时器放在循环扫描里本身是很稳的。博途里的TON、TP这类定时器时间分辨率足够应付5秒这种级别的延时就算主程序扫描周期有波动定时误差顶多几十毫秒对跨小时统计来说根本不算事。真正的影响发生在整点前后的采样点上。举个例子上一小时是19点到20点你每隔5秒读一次电表累计值19:59:58读了一次下一次读到20:00:03。问题来了——20:00:00之后这3秒的用电量实际上已经属于20点这个小时但在你的差分计算里它会被算到19点上。反过来如果你在发现跨小时时把当前小时清零那么20点这个小时就会少掉这3秒的累计。也就是说T#5S方案在“数据连续性”上非常稳因为仪表累计值不会因为你扫描慢就丢但在“边界归属精度”上理论误差最大约等于一个采样周期。采样间隔越大误差越大。5秒的间隔最坏情况下报表会差5秒的产量。对大多数产量统计来说5秒的误差完全能接受但如果你要跟财务对账、按秒结算这个粗糙度就有点说不过去了。另外一个容易被忽略的坑是T#5S定时器如果写在OB1里触发间隔会受程序扫描周期影响。比如某个扫描周期特别长定时器块来不及在整点前后及时执行实际触发点会往后拖。要解决这个问题最好把统计逻辑放到循环中断组织块里由CPU定时调度而不是挂在OB1这种满地都是程序的主循环里。2.2 R_TRIG上升沿检测的局限性R_TRIG看着简单其实它有一个非常硬性的前提被检测信号的上升沿持续时间必须大于PLC的扫描周期。如果信号来了又走在一个扫描周期内就消失R_TRIG根本看不见这个脉冲就丢了。举一个真实的例子。某设备的光电计数信号工件以每分钟2000个的速度通过脉冲宽度大约15毫秒。如果PLC扫描周期是50毫秒这个信号可能在上一次扫描刚结束后到来还没到下一次扫描就已经消失了R_TRIG完全捕捉不到。这种情况不是程序写得不好而是机制就不匹配。高速计数必须要用硬件计数通道或者用支持高数频率的计数模块用普通扫描程序硬数脉冲谁写谁翻车。但是如果你用R_TRIG来检测“时间字段变化”这个边沿情况完全不一样。程序每个扫描周期读一次系统时间提取当前小时值当小时值从19变成20这个变化本身就是一个上升沿而且这个“信号”的持续时间至少是一个小时——远大于扫描周期R_TRIG一定能捕捉到。这种情况下R_TRIG的边界精度取决于扫描周期通常几十毫秒比T#5S的5秒误差高了好几个数量级。所以R_TRIG稳不稳不看指令本身看检测对象检测低速离散脉冲只要脉宽够稳检测时间边界非常稳检测高速脉冲必须配合硬件否则必丢。2.3 两种机制的核心对比表对比项T#5S定时采样R_TRIG边沿检测触发方式周期性时间触发信号上升沿触发数据连续性强不丢累计增量弱脉冲过窄会丢边沿边界切割精度差最大误差约一个采样周期高误差约一个扫描周期适用数据源仪表累计值、电表、流量累计低速离散脉冲、时间边界、状态切换高速脉冲场景可用配合累计值差分不可直接用会丢信号对扫描周期的敏感度中等定时器触发会随扫描抖动高直接决定边沿是否丢失跨小时报表准确性足够一般统计但不精确到秒边界精准适合整点锁存这张表基本还原了我实测下来的结论如果指标只有一个“稳”字必须分场景谈。统计连续累计值T#5S稳切割时间边界R_TRIG稳。3. 博途里的两种具体实现方案3.1 方案一用T#5S周期差分做跨小时统计这个方案适合统计电表电量、流量计累计值、编码器位置这类连续累计量。先设计一个功能块输入是仪表累计值输出是上一小时完成量、当前小时累计量、跨小时脉冲。核心代码逻辑如下// 自复位定时器产生5秒周期的触发脉冲 #cycleTimer(IN : NOT #cycleTimer.Q, PT : T#5S); IF #cycleTimer.Q THEN // 读取当前时间提取小时 #curHour : #getCurrentHour(); // 判断是否跨小时 IF #curHour #lastHour THEN // 没跨小时正常差分累加 #curHourQty : #curHourQty (#meterTotal - #lastTotal); ELSE // 跨小时先把最后一次差分并入上一小时再归档再清零 #lastHourQty : #curHourQty (#meterTotal - #lastTotal); #curHourQty : 0.0; #lastHour : #curHour; #newHourPulse : TRUE; END_IF; // 不管跨没跨都要把本次累计值存下来供下一次差分 #lastTotal : #meterTotal; END_IF;代码里有几个细节必须注意。第一跨小时分支里我把最后一次差分并入了上一小时理由是在T#5S采样间隔里你无法精确区分整点前后的增量只能做个取舍。我的取舍原则是让“已完成小时”的数据尽量连续完整避免上一小时缺一段。代价是当前小时会少几秒增量但这个误差在下一轮差分开始后会自动补齐趋势对报表影响很小。第二#curHour : #getCurrentHour()不是博途自带的系统函数你需要自己封装一个读时间块返回当前小时值。不同CPU支持的时间读取方式不一样有读本地时间的有读系统时间的直接查你所用PLC的指令手册统一封装成一个小功能块后面调用就方便了。第三#lastTotal和#lastHour这两个变量必须用保持性存储。否则PLC断电重启#lastTotal清零而仪表累计值还是几千上万程序第一次差分就会产生一个巨大的假增量报表当场爆表。另外如果你追求更稳定的周期触发建议把这段统计逻辑放到循环中断组织块里直接设置5秒调用一次连T#5S定时器都可以省掉CPU调度比你自己写TON要可靠得多。OB1里的定时器会受到主程序扫描波动影响循环中断则基本不受影响。3.2 方案二用R_TRIG检测时间边界做整点锁存这个方案适合需要精确整点归档的场景。它的核心思想不是靠5秒一次的轮询去碰运气而是让程序在整点之后的第一个扫描周期立刻感知到小时值发生了变化。先看检测时间边界的代码// 读取当前小时 #curHour : #getCurrentHour(); // 判断小时值是否和上次不同这个布尔量本身就是“小时变化”信号 #hourChanged : (#curHour #lastHour); // 用R_TRIG捕捉上升沿输出一个扫描周期的脉冲 #hourEdge(CLK : #hourChanged, Q #newHourPulse); // 更新小时基准供下个周期比较 #lastHour : #curHour; // 整点到了归档当前小时清零重新累计 IF #newHourPulse THEN #lastHourQty : #curHourQty; #curHourQty : 0.0; END_IF;这里要强调一个容易写错的地方一定要先比较、再更新#lastHour。如果把#lastHour : #curHour放在比较之前那#hourChanged永远都是FALSER_TRIG永远不会触发整点归档永远不发生。我见过不少新手写这种逻辑时栽在这个顺序上。如果纯靠R_TRIG来做跨小时归档那么上一小时的数据是在整点后第一个扫描周期被锁存的。假设扫描周期50毫秒误差最多50毫秒比T#5S方案最大5秒的误差小得多。对于需要和MES系统对账、按整点精确切分的场景这个精度才够看。R_TRIG还有另一个用途统计低速的离散工件计数。比如一个光电开关每个工件遮挡一次产生一个脉冲只要脉宽远大于扫描周期就可以直接用R_TRIG累加#partEdge(CLK : #partSensor, Q #partPulse); IF #partPulse THEN #curHourQty : #curHourQty 1; END_IF;这段代码很简单但使用前提非常明确信号脉宽必须足够宽。如果你不确定现场信号的脉宽最稳妥的办法是用示波器或者PLC的在线监控看一下信号持续时间再对比扫描周期。脉宽只有扫描周期的几倍就非常危险这种场景我建议直接走硬件高速计数通道。3.3 关键参数设置和边界细节采样周期选T#5S也好选T#1S也好不是越小越好。采样周期太小CPU每分钟要执行更多次读取和差分DB块读写频繁反而增加故障点。对大多数连续累计值统计5秒完全够用。真到了需要秒级精度的场合应该用R_TRIG的时间边界检测而不是拼命缩短T#5S。跨天、跨月的处理也要提前想好。每小时统计本身只判断小时值变化就够了但如果报表需要按日期存档最好把日期一起纳入判断。我常用的办法是构造一个“时间键值”#timeKey : #month * 10000 #day * 100 #hour; #timeChanged : (#timeKey #lastTimeKey);这样月份、日期、小时任何一个变化都会触发跨小时归档。比单独比较小时变量更稳妥也能顺带处理跨天和跨月。还有一点读取时间和读取累计值必须在同一个扫描周期内完成。如果你在OB1里读时间在某个中断里读累计值整点那一瞬间很可能出现“时间已经切到20点但累计值还没刷新”的情况归档数据就会错位。统计逻辑里尽量把读时间、读累计值、差分、归档这几步放在同一个功能块里按顺序执行一致性才有保障。4. 实测中遇到过的坑和排查思路4.1 整点附近“多一段、少一段”的经典问题用T#5S方案做跨小时统计最典型的现象是整点报表的数值和人工抄表对不上不是多了一点就是少了一点。根本原因就是前面说的边界归属误差。我当时在一个产线上遇到过19点到20点的产量报表比人工记录多了十几件。查了半天发现就是20:00:00到20:00:03之间的增量被算进了19点。后来我把统计逻辑改成R_TRIG整点锁存报表数字就基本能和人工抄表对上了。排查这类问题不要急着改逻辑先在PLC里加两个监控变量一个是“上次采样时间”一个是“本次采样时间”。看整点前后的采样时间戳就能直观确认那部分增量到底被归到了哪个小时。4.2 高速脉冲丢边沿的排查如果你用R_TRIG统计高速脉冲发现计数比实际少第一时间不要怀疑R_TRIG指令坏了而是算一下信号脉宽和扫描周期的关系。我当时排过一个问题设备实际生产了2000件PLC只统计到1500件。查下来光电信号的脉宽大约20毫秒而OB1的扫描周期被一段通信程序拖到了80毫秒信号在两次扫描之间就消失了。解决方法是绕开普通扫描把计数信号接到支持高速计数的硬件通道上让CPU硬件去数脉冲PLC程序只负责周期读取累计值。读取出来之后再按T#5S差分做小时统计既不会丢脉冲又能精确切小时边界。这个组合是我在高速场景下最推荐的做法。4.3 掉电重启后统计错乱的坑跨小时统计最怕凌晨断电。凌晨2点断电3点来电重启如果#lastTotal没有保持重启后第一次读取仪表累计值就是几千程序以为这一小时突然增加了几千的产量报表直接飞掉。我的处理办法分两步。第一步把#lastTotal、#lastHour、#curHourQty都设置成保持性变量断电不丢失。第二步在程序启动的第一个扫描周期做一次初始化读取当前时间把#lastHour同步为当前小时把#lastTotal同步为当前仪表累计值同时把跨小时脉冲禁用掉。这样重启后程序不会产生虚假的整点归档也不会产生虚假的增量。4.4 读时间与读累计值的时序不一致这个坑比较隐蔽。有一段时间我的统计功能块是分两步写的一个块负责读时间并判断整点另一个块负责读累计值并做差分。结果每到整点偶尔会出现归档值是0的情况。后来用在线监控跟踪了两个块的执行时间发现问题在于读时间的块在整点后先执行已经触发了归档和清零而读累计值的块还没读到整点后的新值归档时拿到的累计值还是整点前的旧值一减就出现了负数或零。解决方法是把所有统计相关操作合并到一个功能块里按“读时间 → 判断边界 → 读累计 → 差分 → 归档清零”的顺序一次性执行次序不乱数据就不会乱。4.5 我的选型建议说了这么多总结一下我实际项目里选型的判断标准按场景直接给结论场景推荐方案原因电表、流量计等仪表累计值统计T#5S周期差分连续累计值不会丢统计稳定整点报表要精确对账R_TRIG检测小时变化边界误差从秒级降到扫描周期级低速离散脉冲工件计数R_TRIG逐脉冲累加简单直接脉宽足够就不丢高速脉冲计数硬件高速计数 T#5S差分普通扫描数不过来必须硬件兜底既要求不丢数又要求整点精确T#5S差分 R_TRIG锁存组合差分保连续性边沿保边界精度我个人在实际项目里的习惯是连续累计量统计用T#5S差分整点归档判据用R_TRIG检测时间键值变化高速脉冲走硬件计数通道再用T#5S差分二次统计。这三者不是互相竞争的关系而是各管一段。T#5S的稳稳在数据连续R_TRIG的稳稳在边界敏锐。把这俩放在正确的位置上跨小时统计才能真正让人省心。最后再分享一个小技巧不管用哪种方案跨小时归档完成后最好额外输出一个5秒宽的脉冲给上位机或者MES系统作为“整点数据已更新”的通知信号。这样就算报表那边漏读了也能通过这个脉冲主动去重新拉数据能避免很多整点数据不同步的扯皮问题。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询