3. 水下控制模块电气功能与通信链路测试
测试对象与链路构成
水下控制模块(SCM)的电气功能测试,核心不是“通电亮灯”,而是验证三条相互独立的通道:供电通道(从水面UPS经脐带缆到SCM内部电源分配)、绝缘通道(各导体对地及导体间的绝缘电阻)、通信通道(Modbus RTU over RS-485 与 CAN 总线,含冗余A/B链路)。长距离脐带缆带来的分布电容与线路衰减,是误码率上升和冗余切换变慢的主要物理原因,因此测试必须用可调模拟线缆(电感+电容网络)替代真实脐带缆,才能在水面完成可重复的验证。
测试用例设计(供电 / 绝缘 / 通信 / 冗余)
四类用例共用同一套夹具,但激励与判据完全不同。下表给出可直接执行的用例骨架,参数为教学示例值,实际执行前须以SCM规格书和API 17F条款核定。
| 用例编号 | 测试项 | 激励与连接 | 观测点 | 通过判据(示例) |
|---|---|---|---|---|
| SCM-E-01 | 供电电压与纹波 | 电源设 24 V,负载接 SCM 全部电气负载 | TP-PWR | 23.8–25.2 V,纹波 ≤200 mVpp |
| SCM-E-02 | 过流保护 | 限流从 2 A 缓升至 3 A | 电源告警 + TP-PWR | 2.2 A 前限流动作,SCM 不损坏 |
| SCM-E-03 | 绝缘电阻 | 500 VDC,分别测各导体对地、导体间 | 绝缘测试仪读数 | ≥100 MΩ,60 s 内无击穿 |
| SCM-E-04 | Modbus 基本收发 | 0 km 模拟缆,9600 bps,读保持寄存器 | 协议分析仪 | CRC 正确率 100%,响应 <100 ms |
| SCM-E-05 | 长缆误码率 | 模拟缆 5/10/20 km,连续发 10⁵ 帧 | 误码统计 | 20 km 下 BER ≤1×10⁻⁶ |
| SCM-E-06 | CAN 链路误码 | 250 kbps,20 km 模拟缆,10⁵ 帧 | CAN 分析仪 | 错误帧率 ≤0.1% |
| SCM-E-07 | 冗余切换时间 | A 链路物理断开,B 链路在线 | 示波器双通道 + 时间戳 | 切换 ≤500 ms,切换后首帧正确 |
| SCM-E-08 | 切换回切 | A 恢复后观察是否回切或保持 | 链路状态字 | 行为符合规格书定义,无反复抖动 |
关键实现:误码率与切换时间的测量方法
误码率不能靠“看着通信正常”判断,必须构造已知帧序列并统计。下面给出一个可运行的 Python 脚本,用串口向 SCM 发送递增序号帧,同时记录回读序号,统计丢帧/错帧率;切换时间则通过记录“A 链路断开时刻”与“B 链路首帧正确到达时刻”的差值得到。脚本中的串口对象需按实际测试台替换端口号。
import serial, time, struct
PORT = "COM3" # 测试台实际串口
BAUD = 9600
N_FRAMES = 100000 # 10^5 帧
TIMEOUT = 0.05
def crc16(data: bytes) -> int:
crc = 0xFFFF
for b in data:
crc ^= b
for _ in range(8):
crc = (crc >> 1) ^ 0xA001 if crc & 1 else crc >> 1
return crc
def build_frame(seq: int) -> bytes:
body = struct.pack(">H", seq & 0xFFFF)
return body + struct.pack(">H", crc16(body))
def run_ber_test(ser, n=N_FRAMES):
sent = recv_ok = 0
t0 = time.time()
for seq in range(n):
frame = build_frame(seq)
ser.write(frame)
sent += 1
ser.timeout = TIMEOUT
echo = ser.read(4)
if len(echo) == 4 and echo == frame:
recv_ok += 1
dt = time.time() - t0
ber = (sent - recv_ok) / sent
print(f"发送 {sent} 帧, 正确回读 {recv_ok} 帧, BER={ber:.2e}, 耗时 {dt:.1f}s")
return ber
def measure_switch_time(ser, link_ctrl):
# link_ctrl: 可调用对象,用于断开 A 链路
t_disconnect = time.time()
link_ctrl.disconnect_a()
while True:
ser.timeout = 0.01
data = ser.read(4)
if len(data) == 4 and data[2:] == struct.pack(">H", crc16(data[:2])):
t_first_b = time.time()
break
switch_ms = (t_first_b - t_disconnect) * 1000
print(f"冗余切换时间 = {switch_ms:.1f} ms")
return switch_ms
if __name__ == "__main__":
with serial.Serial(PORT, BAUD, timeout=TIMEOUT) as ser:
run_ber_test(ser)
# measure_switch_time(ser, link_ctrl) # 接入链路控制夹具后启用
模拟缆长的选择应覆盖“标称长度”和“1.5 倍标称长度”两档,因为误码率对缆长呈非线性恶化;只测标称长度容易漏掉裕量不足的问题。切换测试至少重复 5 次,取最大值作为判据,避免单次偶然值。
结果判读与常见异常
- 误码率随缆长陡增:多为终端电阻缺失或阻值不匹配(RS-485 应为 120 Ω),先用万用表在断电状态确认 A/B 线间电阻约 60 Ω(两端各 120 Ω 并联)。
- 绝缘电阻偏低但未击穿:检查测试时是否已断开浪涌保护器与滤波器,这些器件在 500 VDC 下会拉低读数,属于测试方法问题而非 SCM 缺陷。
- 切换时间超标:确认心跳超时判据(示例为连续 3 帧超时)与波特率匹配;波特率越低,3 帧超时本身耗时越长,切换时间预算需按最慢波特率核算。
- 切换后首帧 CRC 错误:常见于 B 链路收发器使能时序与总线空闲间隔不足,需在切换逻辑中加入总线静默延时。
绝缘测试必须在 SCM 断电、所有通信接口拔除的条件下进行,500 VDC 直接施加在通信收发器上可能造成永久损伤。测试顺序建议:绝缘 → 供电 → 通信 → 冗余切换,前一项不合格不进入后一项。