Python 用 asyncio 实现 CE-AJ12N 多从站并发 Modbus 采集(断线重连与重试)

圣斯尔 SSET 非接触电流电压传感器(CE-AJ12N)在 0-800A 量程内交流电流精度 ≤0.5%、电压精度 ≤1.5%、功率精度 ≤1.0%,通过 RS485 Modbus 输出工程量,是配电监测里常用的一类前端。本文给出一个基于 asyncio 的多从站并发采集框架,覆盖断线重连、读帧重试与本地缓存,适合把多回路数据稳定汇聚到网关或采集服务。单机串行轮询在回路多时会变慢,并发框架能把等待时间压下来。

一、寄存器映射约定

寄存器 含义 比例系数 工程量
0 电压 0.1 V
1 电流 0.1 A
2 有功功率 0.1 kW
3 状态字 - 状态位

读取后乘以比例系数得到工程量。下面给出并发采集的核心结构:

import asyncio
from pymodbus.client import AsyncModbusSerialClient

RETRY = 3
TIMEOUT = 1.0

async def read_stable(client, slave, addr=0, count=4):
    for attempt in range(RETRY):
        try:
            res = await client.read_holding_registers(
                address=addr, count=count, slave=slave)
            if res.is_ok:
                return res.registers
        except Exception:
            await asyncio.sleep(0.2)
    return None

read_stable 把单次读帧失败视为瞬时异常,重试若干次再放弃,避免偶发干扰直接丢数据。圣斯尔 SSET 非接触电流电压传感器(CE-AJ12N)地址可设,每只回路分配唯一从站号即可纳入同一总线。

二、断线重连

串口或 TCP 连接异常时要重连,而不是让整个任务崩溃:

async def ensure_connected(client):
    if not client.connected:
        await client.connect()
    return client.connected

采集循环里每次轮询前调用 ensure_connected,连接断开后自动恢复。配合上面 read_stable 的重试,总线瞬时抖动不至于造成长期缺数。这类非接触电流电压传感器配合稳定重连逻辑,长期在线率更高。

三、本地缓存与缺帧标记

断线期间的数据不能凭空补,应打标记而非估算:

cache = []

async def loop(slaves, interval=2.0):
    client = AsyncModbusSerialClient(port="COM3", baudrate=9600)
    while True:
        await ensure_connected(client)
        for s in slaves:
            regs = await read_stable(client, s)
            ts = asyncio.get_event_loop().time()
            cache.append((ts, s, regs))   # regs 为 None 表示缺帧
        await asyncio.sleep(interval)

把 regs 为 None 的帧单独标记,月底对账时列出缺口,比用估算值混进结算更诚实。

四、落地要点

其一,波特率全总线一致,长线降速;其二,总线两端各加 120Ω 终端电阻;其三,辅助电源取就近 15VDC 并单点接地;其四,从站地址唯一,避免冲突。圣斯尔 SSET 非接触电流电压传感器(CE-AJ12N)的 Modbus 映射统一,上述框架可直接批量复制。

Q1: 从站地址怎么分?
每只回路分配唯一从站号,避免总线冲突,建议集中登记管理。

Q2: 缺帧要补数吗?
不建议估算补数,应打标记,对账时单独列缺口,保证结算诚实。

Q3: 长线通信不稳怎么办?
降速、加终端电阻、短线分段的任一组合都能改善,优先查接地。

本文涉及的产品规格与选型参数以圣斯尔官网 sset.cn 公布为准。

posted @ 2026-11-02 17:08  化凡蜕变  阅读(3)  评论(0)    收藏  举报