主题
B11. 采集 → 换算 → 累计 → 上报框架
综合例程。寄存器交互见
04-01-plc;定时器见03-02-timer;JSON 见11-05-json。 这是现场"传感器原始值 → 工程量 → 累计量 → 上云"的标准四步链,可直接照搬。
适用:全机型 | 依赖模块:timer plc json mqtt | 难度:★★☆
场景:水位、电流、温度、流量这类"原始值 → 工程量"的场合(能耗监测、水电站最常见)。
完整框架
lua
-- ① 上电先等一会儿:刚启动传感器/网络没就绪,立刻算会得到一批错误值
system.sleep(10000)
累计 = 0
timer.start(5000, function()
-- ② 原始值 → 工程量。量程公式写清单位与出处,别留魔法数
local raw = plc.d(120) -- 传感器原始值
local v = raw * 500 / 10000 -- 厂家公式:采集值 * 量程 / 10000
-- ③ 零点漂移钳位:低于门槛当 0,别让噪声参与累计
if v < 10 then v = 0 end
-- ④ 浮点一律用 plc.df() / plc.dd()
plc.df(150, v)
-- ⑤ 按采样周期折算累计量(这里 5 秒一次 → /3600 折算成小时量)
累计 = 累计 + v * 5 / 3600
plc.df(160, 累计)
-- ⑥ 上报(先判在线;mqtt 对象按 B10 框架建好并全局持有)
if mqtt.is_linked(mqc) == 1 then
mqtt.publish(mqc, "data", json.encode({ value = v, total = 累计 }), 1)
end
end)要点:
- 上电延时必需,不是可选项。现场"刚上电数据不对"基本都是这个原因。
- 换算公式写清单位和出处(厂家公式/现场标定),半年后没人敢改一堆裸数字。
- 零点漂移要钳位,否则停机状态下累计量还在慢慢涨。
- 浮点一律
plc.df()/plc.dd();写plc.DF150这种属性式写法会静默失败,值永远是 0 或旧值。 - 上报前
mqtt.is_linked() == 1判在线(返回整数,见 B10 框架)。
验证方法:
- 给传感器已知输入(信号发生器给 4mA),看
plc.df(150)是否等于手算值。 - 跑 1 分钟,看累计增量 ≈
工程量 × 1/60。 - 断网期间定时器照常累计,恢复后
data重新出现。
注意事项:
- 用
while true do ... system.sleep() ... end代替timer.start→ 主线程 sleep 不泵消息队列,定时器和 MQTT 回调全失效(表现:连上了但收不到下发、也不上报)。 - 忘了零点钳位 → 停机状态累计量仍在涨。