← 所有文章

FIELD NOTES / PLC 程式與控制

工程單位換算鏈如何避免重複倍率

PLC 程式與控制作者:站長預估 7 分鐘閱讀

以 raw=253、0.1°C/count、offset=0 示範工程單位換算至25.3°C與77.54°F,防止倍率、偏移及版本重複套用。

本文目錄

一 先建立不可猜測的換算契約

本例的 raw=253 不能只看數字就猜成 25.3 °C。輸入契約要列出 raw_type、來源量程、單位、倍率、偏移、方向與已縮放標誌。本案例明訂 raw 是未縮放的整數,倍率 0.1 °C/count,偏移 0 °C;所以 engineering_celsius=253×0.1=25.3 °C。若上游已把 253 轉成 25.3,再套一次 0.1,就會錯成 2.53 °C。

每筆資料帶 unit、scale、offset、source_version 與 scaled_flag。scaled_flag=false 的值才進入 raw→工程值步驟;true 表示已完成指定縮放,不能再套同一鏈。這個旗標不是靠目前數值推導,因為 raw=253、已縮放=253.0 都可能是合法值。來源版本改變時,必須重新確認倍率與偏移,不能沿用舊快取。

本案例換算鏈分兩段:第一段把 raw 253 轉成 25.3 °C;第二段使用明訂的華氏公式 F=C×9/5+32,得到 25.3×1.8+32=77.54 °F。華氏值是顯示或報表單位,不能回寫成新的 raw 後再重複轉換。每一段都保留 input_value、input_unit、output_value、output_unit 與 formula_version。

欄位 案例值 意義 錯誤風險
raw 253 來源未縮放整數 誤當工程值
scale 0.1 °C/count 倍率 重複套用
offset 0 °C 偏移 漏加或加兩次
engineering_celsius 25.3 °C 第一段輸出 單位遺失
display_fahrenheit 77.54 °F 第二段輸出 拿來當raw

換算契約還要指定資料方向與更新週期。若 raw 在每秒更新一次,source_timestamp 應跟著每筆變化;若 HMI 每 500 ms 讀取同一值,不應把重複讀取當成新樣本。批次或歷史系統可用 sample_id 去重,但不能藉由時間間隔猜測是否已縮放。

換算函式要拒絕缺少契約的輸入。若收到 253 但 unit=unknown 或 scaled_flag 缺失,狀態應為 ContractMissing;不要以「看起來像 0.1 倍」自動判斷。這會讓錯誤早些暴露,也能避免同一數值在不同來源被套用不同倍率。

二 逐步計算與反向檢查

先保存 raw=253,再計算 celsius=253×0.1+0=25.3。若需回到 raw,使用 raw_estimate=(celsius-offset)/scale=(25.3-0)/0.1=253;這個反算只在值未被四捨五入或飽和時成立。顯示成 25.30 °C 不代表多了精度,原始 raw 仍是追溯權威。

再計算 fahrenheit=25.3×9/5+32=45.54+32=77.54 °F。若報表只保留 77.5,日後反算會有誤差;因此保存未格式化的工程值與顯示值。若要將 °F 輸入轉回 °C,應使用 C=(F-32)×5/9,並標示這是另一個方向的公式,不能把 32 當成一般偏移在所有單位鏈中重複套用。

換算鏈可用中間物件表示:RawValue(253, raw_unit, v1)→Celsius(25.3, v1)→Fahrenheit(77.54, display_v2)。每個節點都有來源與版本,若 v1 的倍率從 0.1 改為 0.01,新資料走新鏈,歷史結果不應靜默重算。重算要建立 derived_version,並保留舊結果。

步驟 公式 輸入 輸出
1 raw×0.1+0 253 raw 25.3 °C
2 C×9/5+32 25.3 °C 77.54 °F
反算1 (C-0)/0.1 25.3 °C 253 raw
反算2 (F-32)×5/9 77.54 °F 25.3 °C

若 raw 使用有號 16 位整數,先核對負值與零點,不要把 253 的正數案例外推為所有量程。假設 raw=-100、scale=0.1、offset=0,工程值是 -10 °C;若顯示單位改成 °F,結果是 14 °F。這些計算都要帶著 unit 與版本,避免正負號在轉型時消失。

驗收至少測試 raw=0、raw=253、raw=1000 及超量程值。raw=0 在本契約得到 0 °C,不代表任何其他來源的零點;raw=1000 得 100 °C。若來源規定量程 0–1000 counts,raw=1001 應先標 RangeRejected,不應先轉成 100.1 °C 再由顯示層截斷。

三 避免重複倍率與混合單位

最常見錯誤是兩個模組都以為自己負責縮放。通訊模組把 253 變成 25.3 後,HMI 綁定又依 tag 名稱套 0.1,得到 2.53。解法是讓資料結構明確標示 scaled_flag=true、unit=°C、scale_applied=v1,後續模組只允許 °C→°F 的轉換,不允許再走 raw→°C。

偏移也要避免重複。若 raw=4000、scale=0.1、offset=-40,工程值是 360 °C;若 offset 已在設備內扣除,應在契約標示 offset_applied=true。不能因畫面顯示正常就把 -40 再加一次或漏掉一次,應用反算 raw 與來源校準點驗證。

單位不能只放在變數名稱。命名 temp_253 不能說明是 raw count、°C 還是 °F;資料封包內要帶 unit code 或契約版本。若來源把 25.3 寫成「253」並宣稱 unit=0.1°C,數值與單位必須一起保存,不能把字串外觀當作單位證據。

錯誤情況 實際鏈 錯誤結果 排查
重複倍率 253→25.3°C→×0.1 2.53°C 看scaled_flag
漏偏移 raw×0.1,漏offset 偏移錯 核對校準版本
重複華氏 25.3°C→77.54°F→再套1.8 錯誤 限制輸出單位
單位遺失 253無unit 不可判斷 ContractMissing
版本混用 v1 raw配v2 scale 數值漂移 保存source_version

多段鏈的每一步都可做單元測試:raw→°C、°C→°F、°F→°C,以及已縮放輸入的拒絕測試。輸入 25.3 °C、scaled_flag=true 時,測試應直接進第二段得到 77.54 °F;若函式要求 raw 卻收到工程值,應回 ContractMismatch,不應默默重新解釋。

若系統同時支援顯示、控制與歷史,建議控制值使用明確工程單位欄位,顯示值另存格式化字串,歷史則存 raw 與工程值。不要讓 HMI 格式化結果回流成控制輸入,除非另有明確反算與權限流程。

四 範圍 精度與故障排查

排查異常值時按鏈逐層核對:先查 raw 是否是本批來源,再查 unit、scale、offset、scaled_flag、source_version,接著重算工程值,最後才查 °F 顯示格式。若 253 變成 2.53,優先看倍率是否重複;若 25.3 變成 77.54 以外的值,查華氏公式或單位標記;若只差 0.01,查最後一次四捨五入位置。

範圍檢查要寫在每一段的輸出規格。raw 0–1000、°C 0–100、°F 32–212 是本案例的自訂範圍,不能套到所有感測器。超範圍資料保存 raw 與 reason,不要夾到邊界後標成正常。若工程值有有限精度,需保存 conversion_precision,不能把顯示兩位小數當成量測精度。

離線驗收可使用四筆:raw=0→0 °C→32 °F,raw=253→25.3 °C→77.54 °F,raw=1000→100 °C→212 °F,raw=1001→RangeRejected。再另送 25.3,標成 scaled_flag=true 且 unit=°C,確認只做 °C→°F;若程式仍套 raw 倍率,測試應失敗並記錄 DoubleScale。

症狀 先查 預期判斷 修正
結果2.53°C scaled_flag/scale DoubleScale 跳過raw段
結果77.54°F 中間unit 正確兩段鏈 保存中間值
只差0.1 rounding位置 格式化過早 最後一次格式化
超量程變100 range順序 被夾限 保留Rejected
歷史前後不同 source_version 版本混用 derived_version

當兩個來源都送出 253,不能只依數值合併。來源 A 可能是 0.1°C/count,來源 B 可能是 0.01°C/count;必須依 source_id、unit、scale_version 建立不同鏈。排查報表要列出來源契約,讓工程師能看出數值相同但物理意義不同。

本文以算式、契約與驗收資料說明轉換鏈。實際資料型別、字串格式、持久化與單位代碼仍須查選定控制器和感測器手冊,不能用通用欄位名稱取代廠商規格。

五 驗收 FAQ 與來源

本題基準鏈為 raw=253、scale=0.1、offset=0,得到 25.3 °C,再以 F=C×9/5+32 得 77.54 °F。所有中間單位、倍率、偏移、來源版本與 scaled_flag 均要保留;缺契約、超範圍或重複倍率都應拒收或標錯,不得用數值猜單位。

FAQ1:看到 raw=253 可以直接乘 0.1 嗎?答:只有輸入契約明訂 raw 未縮放、scale=0.1 且版本相符才可以;缺少 scaled_flag 或 unit 時應標 ContractMissing。

FAQ2:為何不能用 77.54 反推出 raw?答:華氏顯示值可能已四捨五入或來自另一版本;反算前要知道公式、精度、單位與來源版本,原始 raw 才是追溯權威。

FAQ3:偏移已在設備套用,應用程式還要加嗎?答:不能重複套用。契約要標 offset_applied 與版本,應用程式只執行尚未完成的鏈。

FAQ4:超量程可以夾到 100 °C 嗎?答:除非規格把夾限定義為有效替代值,否則保留原始值並標 RangeRejected,不能用夾限掩蓋來源故障。

參考:NIST SI units 官方資料:單位名稱與量值表述參考,非 PLC 轉換 API。

參考:Python decimal 官方文件:十進位精度與捨入參考,非 PLC 型別規格。

延伸閱讀