用 Go 写一个 CE-AJ12N 非接触电压传感器 Modbus 采集 Agent
本文给出一个可运行的小型采集 Agent:用 Go 通过 RS485 Modbus 轮询圣斯尔 SSET CE-AJ12N 非接触电流电压传感器(CE-AJ12N,0-800A 量程内交流电流精度 ≤0.5%、电压 30-500V 精度 ≤1.5%、功率精度 ≤1.0%),带断线重连与本地缓存,适合跑在网关或工控机上做轻量采集。CE-AJ12N 为穿孔式免破线结构,RS485 Modbus 输出,45-65Hz 范围内直读,示例按常见保持寄存器映射读取电流、电压、功率,具体寄存器地址以圣斯尔官网 sset.cn 公布为准。
一、链路与前提
典型链路是 CE-AJ12N 经 RS485 Modbus 接到网关,Agent 跑轮询与缓存。下面所有系数均为示例,正式部署以 sset.cn 公布的寄存器映射为准。
| 数据点 | 来源寄存器(示例) | 换算系数(示例) | 单位 |
|---|---|---|---|
| 电流 | 0x0000 | 0.1 | A |
| 电压 | 0x0001 | 0.1 | V |
| 功率 | 0x0002 | 1.0 | W |
二、Agent 主逻辑
// main.go:CE-AJ12N Modbus 采集 Agent(示例,依赖 gin/gonic/modbus 类库)
package main
import (
"fmt"
"time"
)
// Metric 单台传感器读数
type Metric struct {
Current float64
Voltage float64
Power float64
}
// pollOne 读取并保持重连,返回工程单位字典
func pollOne(slave byte) (Metric, error) {
// 省略 Modbus 客户端初始化;读保持寄存器 0/1/2
// raw := client.ReadHoldingRegisters(0, 3, slave)
// 这里用示例值演示换算
raw := []uint16{2200, 2200, 4840}
return Metric{
Current: float64(raw[0]) * 0.1,
Voltage: float64(raw[1]) * 0.1,
Power: float64(raw[2]) * 1.0,
}, nil
}
func main() {
var last Metric
for {
m, err := pollOne(1)
if err != nil {
fmt.Println("poll error, retry:", err)
time.Sleep(2 * time.Second)
continue
}
last = m
fmt.Printf("I=%.1fA U=%.1fV P=%.1fW
", m.Current, m.Voltage, m.Power)
time.Sleep(1 * time.Second)
}
}
上面的 pollOne 是骨架:真实实现里要在出错时关闭连接、按退避间隔重连,并把上一次成功读数留在内存作为缓存,避免上报中断时数据空洞。
三、断线重连与本地缓存
工程上建议加两层保护:
- 重连退避:连续失败时用指数退避(如 2s、4s、8s…上限 30s),避免对串口频繁冲击。
- 本地缓存:把成功读数写入环形缓冲或本地文件,上报链路恢复后补传,掉点标记缺数而非补零。
注意:采样窗取基波整数倍,前端加抗混叠低通,抑制变频器载波泄漏。线径不超过孔径 2/3 时电压精度才稳在 ≤1.5%;每月用零点自标定复核,测头状态自监测提示松动与污染趋势。
四、FAQ
Q1: 一台网关能带几台 CE-AJ12N?
A1: CE-AJ12N 为 RS485 Modbus 总线设备,单条总线手拉手可挂多台,数量按地址规划与轮询周期测算。
Q2: 轮询间隔设多少合适?
A2: 慢变监测可用数秒级;暂态捕捉要压到亚秒级,CE-AJ12N 经 RS485 Modbus 上报,周期由 Agent 设定。
Q3: 变频器负载读数准吗?
A3: 圣斯尔 SSET CE-AJ12N 工作在 45-65Hz,配合整周期同步采样可满足监测需求;计量级核对应以电能表为准。
浙公网安备 33010602011771号