兩種每秒事件方法
『每秒一次』有兩種常見意思。方法 A 是事件完成後再啟動一個一秒計時器;若本次處理花 80 ms,下一次就從完成時重新算,週期會變成 1.08 秒。方法 B 是保存下一個目標時間 t_next,每次以現在時間比較;處理時間只造成單次延遲,排程仍對齊目標。兩者都可能合理,先看需求是固定間隔還是不可重疊的工作。
| 方法 | 下一次依據 | 優點 | 風險 |
|---|---|---|---|
| 完成後重算 | 完成時間+1000ms | 不會重疊 | 處理時間會累積 |
| 目標時間排程 | t_next+1000ms | 長期較準 | 延遲時要決定補做或跳過 |
| 外部週期任務 | 平台排程 | 由系統驅動 | 週期與搶占依平台 |
本篇時間數字都是案例條件。未選定 PLC 型號,因此不指定時鐘 API 或計時指令;Q06UDVCPU、GX Works2 的實作必須查對應手冊。
把掃描與處理時間分開
假設目標事件為 0、1000、2000…9000 ms,每次處理時間以 80、120、50、100 ms 循環。表中忽略掃描觀察延遲,處理時間為非阻塞工作的經過時間,不是在主掃描忙等;這些都是假設值。方法 A 在每次完成後再等 1000 ms,方法 B 仍以目標時間計算。
| 次數 | 處理(ms) | 方法A預定(ms) | 方法B目標(ms) | 方法A累積差 | 方法B策略 |
|---|---|---|---|---|---|
| 1 | 80 | 0 | 0 | 0 | 依規格對齊 |
| 2 | 120 | 1080 | 1000 | 80 | 依規格對齊 |
| 3 | 50 | 2200 | 2000 | 200 | 依規格對齊 |
| 4 | 100 | 3250 | 3000 | 250 | 依規格對齊 |
| 5 | 80 | 4350 | 4000 | 350 | 依規格對齊 |
| 6 | 120 | 5430 | 5000 | 430 | 依規格對齊 |
| 7 | 50 | 6550 | 6000 | 550 | 依規格對齊 |
| 8 | 100 | 7600 | 7000 | 600 | 依規格對齊 |
| 9 | 80 | 8700 | 8000 | 700 | 依規格對齊 |
| 10 | 120 | 9780 | 9000 | 780 | 依規格對齊 |
方法 A 的事件起始時間依 A[n+1]=A[n]+P[n]+1000 計算;前十次起始依序為 0、1080、2200、3250、4350、5430、6550、7600、8700、9780 ms,因此第十次起始為 9780 ms。方法 B 依目標時間,1 秒一次,第十次起始為 9000 ms。掃描延遲在本算例統一忽略,實際工程需另行量測。
延遲時補執行 跳過或重新對齊
| 策略 | 遇到落後 | 適用情境 | 先確認 |
|---|---|---|---|
| 補執行 | 逐個補上未完成事件 | 每筆不可漏 | 是否允許堆積 |
| 跳過 | 直接到下一目標 | 只要最新狀態 | 是否可丟失統計 |
| 重新對齊 | 下一目標=現在+1000ms | 可接受相位改變 | 是否要報延遲 |
| 禁止重疊 | 工作忙就記錄 missed | 處理不能並行 | 忙碌旗標與診斷 |
先選時間來源並查官方解析度、回捲和讀取方式。
記錄每次目標時間、實際開始、實際完成、處理時間和掃描延遲。
明確定義落後一個以上週期時補做、跳過或重新對齊。
若工作不可重疊,加入 Busy 和 missed 計數。
用相同操作序列比較第十次結果,再依平台實作測試。
通用偽碼(僅示意):Event:=FALSE; IF Now>=NextTime AND NOT Busy THEN Event:=TRUE; NextTime:=NextTime+1000ms; END_IF。若 Now 已落後很多,是否使用迴圈補做、只加一次或直接重設,必須由規格決定。
完成判定與先查哪裡
完成後應看到:事件時間戳與排程策略一致,能說明第十次為何在目標時間、晚多少或跳過哪些事件;每次處理時間和掃描延遲分開保存。失敗時先查時間來源是否單調、單位是否為 ms、NextTime 是否每次更新、處理是否重入,以及時間回捲。不要先把計時常數改小。
適用型號與限制:本文是跨平台排程概念,未指定 Q、FX、S7 或其他 PLC 的時鐘 API、週期任務或中斷語法。Q06UDVCPU 的實際時間讀取、計時精度、任務支援和掃描模型須依 Mitsubishi 手冊確認。
| 問題 | 回答 |
|---|---|
| 為什麼完成後重算會變慢? | 每次把處理時間加進下一個週期。 |
| 目標排程落後一定要補做嗎? | 不一定,需按資料完整性和不可重疊需求選策略。 |
| PLC 掃描時間算進一秒嗎? | 會影響實際觀察與觸發時點,應分開記錄。 |
| 可以用一般 TON 直接保證每秒嗎? | 不能跨平台假定精度和重啟行為,先查文件。 |
第十次觸發的完整驗收
進一步操作時,把處理時間刻意設成不同長度,逐次記錄實際開始和完成。若完成後重算,每次處理時間都會推遲下一個起點;若目標排程已落後,先決定是否補做,並限制一次最多補幾筆,避免忙碌時無限追趕。測試時間來源回捲與任務停用,確認排程不會產生巨大負延遲。若資料不能漏,保存每個未完成事件;若只要最新值,明確標記跳過的事件。
教學驗收時還要分辨排程延遲和處理延遲。目標時間是排程資料,實際開始和完成是工作資料,掃描時間是 PLC 執行資料,三者分開保存。若執行時間偶爾超過週期,記錄峰值和原因,不能只記錄平均。回捲或時間校正時,先暫停補做策略並報告狀態,避免把所有延遲一次補出而造成負載尖峰。離線表的每個數字都能由時間線重算,工程測試則需依平台工具確認。
驗收週期事件時,每次都保存目標時間、實際觸發時間、處理開始與完成時間。若採完成後重算,十次事件的時間會把每次處理時間加進去;若採目標時間排程,落後時要依規格補做、跳過或重新對齊。正常案例應能由記錄重算,異常案例則要看到 missed 或延遲原因。時間回捲、時鐘校正、任務停止和處理超時都要單獨測試。不要用畫面每秒刷新一次當成 PLC 已準時觸發。
| 驗收項目 | 完成後應看到 | 不同時先查 |
|---|---|---|
| 週期對齊 | 目標時間與實際時間差在允許值 | 時間來源與單位 |
| 處理變慢 | 延遲或 missed 有紀錄 | 處理時間和排程策略 |
| 落後多週期 | 依規格補做或跳過 | 不可重疊與佇列容量 |
| 時鐘回捲 | 不產生巨大負延遲 | 平台回捲規則 |
復原時先保存原始記錄,確認輸入、狀態、診斷旗標和輸出,再依規格清除或重試。這些是教學案例,不是 PLC 模擬或實機結果。
看懂落後兩個週期時該做什麼
假設下一個目標時間是兩千毫秒,排程直到三千五百毫秒才再被執行。此時兩千與三千兩個目標都已過去,不能只寫一句延遲就結束。若採補做,要保存兩件待辦事件並限制每次處理量;若採跳過,應記錄跳過兩個目標,再把下一目標設為四千毫秒。
如果你的工作是取得現在溫度,晚到後連讀兩次,只能得到當下附近的資料,無法補回兩千毫秒那一刻的真實溫度。只有上游已有時間戳緩衝資料,補讀才可能還原漏掉的樣本。因此「不能漏資料」通常還需要緩衝與序號設計,不能只靠快速連續觸發彌補。
若工作是資料整理,歷史資料仍完整保留,補做就可能合理。這時要把每件工作原本的目標時間一起保存,不把實際補做時間冒充原始取樣時間。佇列容量不足時也要報告,不能為了追趕而讓單次掃描執行無上限迴圈,拖慢其他流程。
量測時把開始延遲與執行時間分成兩欄。實際開始減目標時間是開始延遲,實際完成減實際開始才是處理時間。假設目標一千、開始一千零二十、完成一千一百,延遲二十毫秒,處理八十毫秒。兩者原因不同,不能把一百毫秒全部怪給處理程式。
最後核對使用的時間來源。牆上時鐘可能因校時而跳動,週期判斷通常需要適合量測間隔的單調時間來源;計數器也可能回捲。請依目標平台提供的型別與差值規則實作,不用未查證的直接大於比較跨越回捲。本文表格使用無回捲的理想時間軸,實際時鐘測試另行記錄。
附錄記錄欄位:事件序號、目標時間、時間來源、實際開始、實際完成、處理時間、掃描時間、Busy、missed、策略和結果。用這張表先做離線推導,接著才在指定工程軟體中確認。不要把手算結果寫成測試通過。
本篇未選定單一 PLC 平台,因此不虛構時間 API。時間排程、週期任務、解析度與回捲規則列為待依目標 PLC 官方手冊確認。