跳到主要内容

PT100 温度监控:Modbus RTU/TCP 接入 InfluxDB v3

本示例演示如何通过 ME31-XDXX0400 四通道采集模块对高精度 PT100 传感器进行温度监控。数据管道同时支持 Modbus RTU 和 Modbus TCP 两种传输层,内置指数移动平均(EMA)滤波以消除噪声,并将遥测数据定期写入 InfluxDB v3。

PT100 温度监控

本示例实现的功能

  • 双传输层支持:通过一个标志变量即可在 RS485(Modbus RTU)与以太网(Modbus TCP)之间切换。
  • 1Hz 轮询:每 1000ms 向通道 1 请求一次整型温度数据。
  • EMA 滤波:对 PT100 读数应用指数移动平均(ALPHA = 0.2),平滑温度波动。
  • InfluxDB v3 集成:每 10 秒使用 InfluxDB Line Protocol 批量写入滤波后的温度数据。
  • 启动自检:脚本初始化时自动查询设备固件版本。
  • 故障检测:当传感器返回断线状态(-99.9 °C)时记录告警日志。

端到端数据流

设备与线路协议

ME31-XDXX0400 是一款四通道 PT100 采集模块,可作为 Modbus 从站(RTU)或 Modbus 服务器(TCP)运行。

  • 物理层:RS485(9600 8N1)和 RJ45 以太网(10/100M)。
  • 缩放规则:温度值以 16 位有符号整数存储,物理值 = 寄存器值 × 0.1
  • 错误标识:特殊值 0xFC19(-999)表示传感器断线。

下表列出了本示例用到的主要 Modbus 寄存器。

地址寄存器名称访问类型缩放系数单位描述
0x0190CH1_TEMP_INT输入寄存器(04)0.1°C通道 1 整型温度
0x07DCFW_VERSION保持寄存器(03)1固件版本号
0x2328CH1_OFFSET保持寄存器(03)0.1°C通道 1 校准偏移量

CycBox 配置

引擎配置了两个并发连接,Lua 脚本通过标志变量选择激活路径。

PT100 温度监控

连接索引映射

connection_id传输层编解码器目标/端口
0串口Modbus RTU/dev/ttyUSB0(9600 8N1)
1TCP 客户端Modbus TCP192.168.7.7:502

配置 JSON

[
{
"app": {
"app_transport": "serial_port_transport",
"app_codec": "modbus_rtu_codec",
"app_transformer": "disable_transformer",
"app_encoding": "UTF-8"
},
"modbus_rtu_codec": {
"with_receive_timeout": 20
},
"serial_port_transport": {
"serial_port_transport_data_bits": 8,
"serial_port_transport_port": "/dev/ttyUSB0",
"serial_port_transport_parity": "none",
"serial_port_transport_baud_rate": 9600,
"serial_port_transport_stop_bits": "1",
"serial_port_transport_flow_control": "none"
}
},
{
"app": {
"app_transport": "tcp_client_transport",
"app_codec": "modbus_tcp_codec",
"app_transformer": "disable_transformer",
"app_encoding": "UTF-8"
},
"tcp_client_transport": {
"tcp_client_transport_timeout": 5000,
"tcp_client_transport_keepalive": true,
"tcp_client_transport_nodelay": true,
"tcp_client_transport_port": 502,
"tcp_client_transport_host": "192.168.7.7"
},
"modbus_tcp_codec": {
"unit_id": 2
}
}
]

Lua 管道详解

以下脚本管理轮询生命周期和数据处理。它使用 on_timer 回调维持稳定的采样率,不受下游延迟影响。

-- ME31-XDXX0400 PT100 温度监控
-- 支持 Modbus RTU(串口)和 Modbus TCP,通过标志变量切换。
-- 每 1 秒轮询一次通道 1 温度,应用指数移动平均(EMA)滤波,
-- 每 10 秒将滤波数据写入 InfluxDB。启动时一次性读取设备信息。
--
-- 设备:ME31-XDXX0400 四通道 PT100 模块
-- 协议:Modbus RTU(波特率 9600 8N1)或 Modbus TCP
-- Modbus 地址:从站 1(RTU),单元 2(TCP,由配置决定)
--
-- 寄存器映射:
-- 0x0190 CH1_TEMP_INT 输入寄存器 温度整数值(×0.1 °C),0xFC19(-999)= 断线
-- 0x07DC FW_VERSION 保持寄存器 固件版本

local CONNECTION_MODE = "RTU" -- 改为 "TCP" 以使用 Modbus TCP
local CONN_ID = (CONNECTION_MODE == "TCP") and 1 or 0
local SLAVE_ADDR = 1
local TCP_UNIT_ID = 2

local POLL_MS = 1000
local INFLUX_INTERVAL_MS = 10000
local ALPHA = 0.2 -- EMA 平滑系数

local last_poll_ms = 0
local last_influx_ms = 0
local filtered_temp = nil

local INFLUX_URL = get_env("INFLUX_URL") or "http://localhost:8181"
local INFLUX_TOKEN = get_env("INFLUX_TOKEN") or "<REDACTED>"
local INFLUX_DB = "cycbox"

function on_start()
log("info", "启动 ME31-XDXX0400 监控。模式:" .. CONNECTION_MODE)

-- 启动时读取固件版本
if CONNECTION_MODE == "TCP" then
modbus_tcp_read_holding_registers(0x07DC, 1, 100, CONN_ID)
else
modbus_rtu_read_holding_registers(SLAVE_ADDR, 0x07DC, 1, 100, CONN_ID)
end
end

function on_timer(now_ms)
-- 轮询通道 1 温度
if now_ms - last_poll_ms >= POLL_MS then
if CONNECTION_MODE == "TCP" then
modbus_tcp_read_input_registers(0x0190, 1, 0, CONN_ID)
else
modbus_rtu_read_input_registers(SLAVE_ADDR, 0x0190, 1, 0, CONN_ID)
end
last_poll_ms = now_ms
end

-- 定期写入 InfluxDB
if now_ms - last_influx_ms >= INFLUX_INTERVAL_MS then
if filtered_temp ~= nil then
local line_data = string.format("me31_temp,channel=1 temperature=%.2f", filtered_temp)
influxdb_write_v3_async(INFLUX_URL, INFLUX_TOKEN, INFLUX_DB, line_data, "auto", true, false)
end
last_influx_ms = now_ms
end
end

function on_receive()
-- 仅处理来自激活连接的消息
if message.connection_id ~= CONN_ID then return false end
local modified = false

-- 检查固件版本
local fw_key = (CONNECTION_MODE == "TCP") and string.format("modbus_tcp_%d:holding_07DC", TCP_UNIT_ID)
or string.format("modbus_rtu_%d:holding_07DC", SLAVE_ADDR)
local fw_ver = message:get_value(fw_key)
if fw_ver then
message:add_int_value("Firmware_Version", fw_ver)
modified = true
end

-- 检查通道 1 温度
local temp_key = (CONNECTION_MODE == "TCP") and string.format("modbus_tcp_%d:input_0190", TCP_UNIT_ID)
or string.format("modbus_rtu_%d:input_0190", SLAVE_ADDR)
local raw_temp = message:get_value(temp_key)
if raw_temp then
-- uint16 转 int16(二进制补码)
if raw_temp > 32767 then
raw_temp = raw_temp - 65536
end

if raw_temp == -999 then
log("warn", "通道 1 传感器断线")
else
local temp_c = raw_temp * 0.1

-- 应用 EMA 平滑滤波
if filtered_temp == nil then
filtered_temp = temp_c
else
filtered_temp = ALPHA * temp_c + (1 - ALPHA) * filtered_temp
end

message:add_float_value("CH1_Temperature_Filtered", filtered_temp)
message:add_float_value("CH1_Temperature_Raw", temp_c)
modified = true
end
end

return modified
end

回调逻辑说明

  1. on_start:发起一次对寄存器 0x07DC(固件版本)的读取请求。
  2. on_timer:管理两个独立的循环。第一个每 1 秒触发一次 Modbus 读取;第二个每 10 秒将累积的滤波值写入 InfluxDB。
  3. on_receive:负责数据解析,处理负温度的二进制补码转换,将整数原始值乘以 0.1 进行缩放,并按公式 EMA_now = (ALPHA × Value) + ((1 - ALPHA) × EMA_prior) 计算 EMA。

下游服务契约

InfluxDB v3

数据通过 InfluxDB v3 write_async API 以 Line Protocol 格式写入。

  • Measurementme31_temp
  • Tagschannel=1
  • Fieldstemperature(浮点型)
  • 精度:Auto

Line Protocol 示例:

me31_temp,channel=1 temperature=24.52

运维注意事项

  • 环境变量:脚本需要在 CycBox 环境中配置 INFLUX_URLINFLUX_TOKEN
  • 滤波响应速度ALPHA = 0.2 提供中等平滑效果。增大 ALPHA 趋近 1.0 时滤波减弱(响应更快但噪声更多);减小 ALPHA 趋近 0.0 时滤波增强(更平滑但响应更慢)。
  • 地址冲突:Lua 脚本默认从站 ID 为 1,而手动输入模板可能配置为从站 ID 2。请确保脚本中的 SLAVE_ADDR(RTU)和 TCP_UNIT_ID(TCP)与设备拨码开关设置一致。

常见问题与建议

  • 2 线 PT100 接线:使用 2 线传感器时,必须按照厂商说明将 CHx-COM x 端子短接,否则模块会报告传感器断线。
  • TCP 超时:Modbus TCP 编解码器配置了 5000ms 超时。网络拥塞时 on_receive 回调可能触发不及时,导致 InfluxDB 写入延迟。
  • 密钥安全:若需共享配置,切勿将 INFLUX_TOKEN 硬编码在脚本中。请始终使用 get_env 函数从引擎的安全环境存储中读取密钥。