一 累加器先分整數與顯示值
長時間累加常見兩種錯誤:把有限寬度的計數器當成永遠不會回捲,或把浮點顯示值當成計數權威。本篇案例 先採 uint32 計數器,最大值 4294967295;若計數器沒有 reset 且真實增量小於 2^32,差值可用模 2^32 計算。
整數權威欄位保存 raw_counter、last_counter、delta、total_uint64 或更寬的工程累計值;display_value 只是格式化結果。若設備只提供 uint32 回讀,長期 total 仍需由應用層保存回捲次數或更寬資料,不能把畫面上的十進位字串再轉回浮點當權威。
回捲公式成立有前提:沒有中途 reset,且兩次讀取間真實增加量小於模數。若停機時間太久或事件速率太高,增加量可能已達模數,單次 new-old 無法判斷。此時應標記 Ambiguous,要求縮短取樣週期或使用硬體提供的更寬計數。
| 欄位 | 型別角色 | 用途 | 限制 |
|---|---|---|---|
| raw_counter | uint32 | 設備目前計數 | 可能回捲 |
| last_counter | uint32 | 上次有效快照 | reset後不可直接相減 |
| delta | uint32/uint64 | 本次增量 | 需檢查模數前提 |
| total_authoritative | 更寬整數 | 長期累計 | 需保存回捲/重啟狀態 |
| display_value | 格式化數值 | HMI/報表 | 不可反作權威 |
計數器讀取要盡可能形成一致快照。若高低字分開讀取,回捲或更新可能發生在兩次讀取之間,組合值未必是某一時刻的真值。本文不指定廠牌讀取指令,實作前需查目標設備是否提供鎖存、雙讀比對或一致性旗標;沒有證據時應標記 snapshot_uncertain。
資料快照要帶 sample_time、quality、reset_marker 和 counter_epoch。若來源品質無效,不更新 last_counter;若發現 reset,重新建立基線,不能把重啟後的小值當成巨大負差。
二 模數回捲逐步計算
本篇案例 的邊界案例是 old=4294967290、new=7。若期間真實只增加 13,模數差為 (7-4294967290) mod 4294967296=13。計算可以拆成 new>=old 的普通差,或 new<old 時以 (MAX-old+1)+new;本例new<old才附帶wrap_detected=1;普通增加分支不設定回捲。這仍以無reset且真增量小於模數為前提。
另一案例 old=100、new=80。若另有可信速率上限,能證明這段間隔不可能增加4294967276,這筆資料才與模型不符,不能把 2^32-20 當成真實增量。先查 reset、通訊快照一致性、來源代號和讀取順序,再決定是否拒收。
| old | new | 假設 | delta | 狀態 |
|---|---|---|---|---|
| 4294967290 | 7 | 真增量13且未reset | 13 | ValidWrap |
| 100 | 130 | 普通增加 | 30 | Valid |
| 100 | 80 | 速率上限排除巨量增量 | 拒收 | UnexpectedDecrease |
| 50 | 5 | 發現重啟 | 不計算 | ResetBaseline |
| 4294967290 | 10 | 可能跨多次回捲 | 不確定 | Ambiguous |
如果來源可能在一次取樣間跨過兩次回捲,即使算式得到一個小正數,也不能宣稱正確。驗收應先用最大事件速率與最長取樣間隔估計上限,要求真實增量遠小於 4294967296;否則改用更寬計數或縮短週期。
回捲判斷還要用最大速率做上限估算。假設來源每秒 1000 次、最長 10 分鐘未讀,可能增加 600000,尚小於 2^32;若來源每秒 10000000 次,同樣 10 分鐘可能增加6000000000,超過模數,模數差的唯一解前提失效;是否跨幾次邊界還取決於起點。這個計算應列入取樣週期設計。
回捲事件應寫入事件紀錄,包含 old、new、epoch、sample_time、delta_rule 和 reset evidence。不要因畫面總量連續就刪掉 raw,因為回捲判斷需要原始快照。
模數差是數學公式,實作前須先確保減法不會在有號三十二位元中溢位。可使用經核對的更寬型別或平台明訂的無號模數運算;不能先算錯再取餘數,也不能假設所有PLC整數溢位都自動回捲。
三 binary32 精度損失
IEEE 754 的浮點格式不是所有 REAL 都相同。以 binary32 為例,有效精度有限;當數值接近 2^24=16777216 時,加 1 可能不改變儲存結果。這不表示每個 PLC 的 REAL 都一定是 binary32,而是提醒必須依目標型別與手冊核對,不能用「REAL 都一樣」推論。
離線示例:若 float32 累計值已是 16777216,再做 +1,採最近且一半取偶數的binary32捨入時,結果仍是16777216;加2得到可精確表示的16777218。若用它累計脈衝,少量增量會消失,且後續差值看不出哪一輪漏掉。整數計數器應保持權威,浮點只在需要工程單位或畫面格式時轉換。
累計時間也要小心。若每輪用 float32 加 dt=0.001 s,長時間後相鄰可表示值間距可能大於 0.001;應以整數 tick 或更寬型別保存時間,再在計算或顯示時轉換。單位必須明確是秒、毫秒或 tick,不能同時混用。
| 情境 | 權威表示 | 風險 | 驗收方式 |
|---|---|---|---|
| 脈衝總數 | uint32/uint64 | 回捲與reset | 查epoch與delta |
| 工程累積量 | 整數原量×比例 | 浮點小增量消失 | 抽查原始計數 |
| 累計時間 | 整數tick/更寬整數 | dt單位錯或精度不足 | 核對tick到秒 |
| HMI顯示 | 格式化REAL | 顯示捨入 | 不可回寫權威 |
浮點精度測試要指定格式,而不是只寫 REAL。可用離線程式把整數轉成 binary32,測試 16777216、16777217、16777218 的表示結果,再把結果與目標平台實際資料型別文件比對。若平台使用不同精度,應建立另一組測試,不能直接沿用 binary32 結論。
顯示轉換應最後一次完成,並保留原始整數。若工程量是每脈衝 0.01 L,先用整數 total_count,再以 total_count×0.01 產生顯示;不要每輪把顯示後的 12.34 L 再加 0.01,避免捨入漂移。
四 重啟 reset與資料驗收
重啟後不能直接沿用 RAM 中的 last_counter,除非該資料的保持性與一致性已由目標平台和工程設計確認。安全流程是讀取來源計數、取得 reset/epoch 證據,建立新 baseline,將本次delta標示為未建立增量;若內部以零暫存,也必須附baseline-only狀態,不能聲稱期間真增量是零,並在事件中記錄 BaselineAfterRestart。
若設備有明確 reset command,reset 前後應分成兩個 epoch。reset 前最後值不能和 reset 後第一個小值相減;如果 reset 期間仍可能有事件,還要由設備規格定義是否遺失。應用層不能只看數字變小就自動補回 2^32。
長期驗收可用三段:正常增加 100→130 得 30;回捲 4294967290→7 得 13;重啟後 500→12 先建立基線不計算。再加入 binary32 顯示測試,確認畫面格式不會覆寫整數權威。
所有異常都要有 reason:CounterWrap、UnexpectedDecrease、ResetBaseline、AmbiguousGap、InvalidSample 或 PrecisionDisplayOnly。這些狀態應與 delta、total、sample_time 一起交付;只顯示「累計正常」不足以讓人追查。
累計時間積分也要保留原始 dt。若每輪只更新 total_seconds,發生通訊停頓或時鐘倒退後就無法重算。保存 tick_before、tick_after、dt_units、time_epoch 和 quality,可把「資料真實增加」與「計時不可靠」分開。
若總量需要跨重啟保存,應把 epoch、累積回捲次數與保存時間一起備份;只有一個 total 數字不足以判斷它是否曾被reset。
本文是離線數學與資料設計教學,沒有使用特定 PLC 的回捲寄存器或特殊指令。IEC 61131-3 的語言標準不等於某平台的記憶體保持和計數器規格,實作前仍需查目標型號手冊。
五 驗收 FAQ與來源
本篇案例 通過條件是:uint32 最大值寫對;old=4294967290、new=7 得 13;跨多次回捲被標記不確定;reset 後建立新基線;binary32 在 2^24 附近的 +1 不被當成可靠整數累加;整數權威與顯示值分離;累計時間單位與來源明確。
FAQ1:old=4294967290、new=7 為何是 13?答:在沒有 reset 且真實增量小於 2^32 的前提下,(7-4294967290) mod 4294967296=13。
FAQ2:看到 new 比 old 小就一定是回捲嗎?答:不一定。可能是 reset、來源換代、讀取錯序或多次回捲;要先查 epoch、取樣間隔與最大速率。
FAQ3:binary32在2^24加1會怎樣?答:採最近且一半取偶數時會捨回2^24;不同捨入模式需另查。PLC的REAL是否採此格式和運算模式,也要由平台確認。
FAQ4:可以用 HMI 顯示的浮點總量當累加器權威嗎?答:不可以。整數計數與回捲狀態保存為權威,浮點只用於工程單位顯示或明確的計算結果。
參考:NumPy finfo官方文件:浮點精度及格式參數,僅供數值驗算參考。