4. 光模块发射光功率自动化测试

任务说明

本案例实现一个最小可复现的发射光功率自动化测试流程:通过 SCPI 控制光模块进入发射状态,在多个温度点下用光功率计读取发射光功率,并记录为 CSV。代码使用可替换的仪器驱动接口,便于接入真实设备。

环境与依赖

  • Python 3.8+
  • 无第三方库依赖(使用标准库 socket、csv、time)
  • 光模块与光功率计需支持 SCPI over TCP(默认端口 5025)

核心实现

import socket, csv, time

class ScpiInstrument:
    """最小 SCPI over TCP 客户端"""
    def __init__(self, host, port=5025, timeout=5.0):
        self.sock = socket.create_connection((host, port), timeout=timeout)
        self.sock.settimeout(timeout)
        self.buf = b""

    def write(self, cmd):
        self.sock.sendall((cmd + "\n").encode())

    def query(self, cmd):
        self.write(cmd)
        while b"\n" not in self.buf:
            self.buf += self.sock.recv(4096)
        line, self.buf = self.buf.split(b"\n", 1)
        return line.decode().strip()

    def close(self):
        self.sock.close()

class OpticalModule:
    """光模块控制:进入发射状态、设置温度"""
    def __init__(self, inst):
        self.inst = inst

    def enter_tx(self):
        # 打开发射通道,进入发射状态
        self.inst.write(":SOURce:CHANnel1:OUTPut ON")
        self.inst.write(":SOURce:CHANnel1:STATe TX")

    def set_temperature(self, celsius):
        self.inst.write(f":SOURce:TEMPerature {celsius}")
        # 等待温度稳定
        time.sleep(2.0)

    def is_tx(self):
        return self.inst.query(":SOURce:CHANnel1:STATe?") == "TX"

class PowerMeter:
    """光功率计:读取发射光功率(dBm)"""
    def __init__(self, inst):
        self.inst = inst

    def read_power_dbm(self):
        return float(self.inst.query(":MEASure:POWer?"))

def run_tx_power_test(module_host, meter_host, temps, out_csv="tx_power.csv"):
    module_inst = ScpiInstrument(module_host)
    meter_inst = ScpiInstrument(meter_host)
    module = OpticalModule(module_inst)
    meter = PowerMeter(meter_inst)

    module.enter_tx()
    assert module.is_tx(), "光模块未进入发射状态"

    rows = []
    for t in temps:
        module.set_temperature(t)
        p = meter.read_power_dbm()
        rows.append((t, p))
        print(f"温度 {t}°C -> 发射光功率 {p} dBm")

    with open(out_csv, "w", newline="") as f:
        w = csv.writer(f)
        w.writerow(["temperature_C", "tx_power_dBm"])
        w.writerows(rows)

    module_inst.close()
    meter_inst.close()
    return rows

if __name__ == "__main__":
    # 示例:25/45/70°C 三个温度点
    run_tx_power_test("192.168.1.10", "192.168.1.20", [25, 45, 70])

执行流程

连接仪器 进入发射状态 (TX ON) 设置温度点 等待稳定 读取光功率 (dBm) 记录 CSV (温度, 功率) 下一温度点

运行与验证

  1. 将 module_host、meter_host 替换为实际仪器 IP,运行 python tx_power_test.py。
  2. 观察控制台是否依次打印每个温度点对应的发射光功率。
  3. 检查生成的 tx_power.csv,应包含表头 temperature_C,tx_power_dBm 及每个温度点一行数据。
  4. 通过条件:光模块进入 TX 状态断言通过;每个温度点均成功读取到数值型功率;CSV 行数与温度点数量一致。

常见问题

  • 连接超时:确认仪器 SCPI 端口(默认 5025)开放且 IP 可达。
  • 温度未稳定:可增大 set_temperature 中的 time.sleep 或改为轮询温度查询命令。
  • SCPI 命令差异:不同厂商命令前缀不同,按实际手册替换 :SOURce、:MEASure 等命令。