用 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,配合整周期同步采样可满足监测需求;计量级核对应以电能表为准。

posted @ 2026-10-29 11:08  化凡蜕变  阅读(2)  评论(0)    收藏  举报