4. 光源控制器与频闪触发设置

任务目标

在机器视觉检测系统中,连续照明会导致发热严重、寿命缩短,且环境光干扰难以抑制。本案例要求配置光源控制器,使其工作在频闪触发模式:仅在相机曝光瞬间点亮光源,从而大幅降低发热并有效抑制环境光干扰。

环境与依赖

  • 硬件:光源控制器(支持外部触发,如OPT-DPA1024E)、环形光源、工业相机(支持硬件触发)、信号发生器或PLC(提供触发信号)
  • 软件:光源控制器厂商配置工具(或串口调试助手)、相机SDK(如海康MVS)
  • 接线:相机触发输出(或外部触发源)→ 光源控制器触发输入(TRIG+ / TRIG-)

实现方案

频闪触发的核心逻辑是:外部触发信号到来时,控制器以设定的电流和持续时间点亮光源,触发结束后自动熄灭。本案例以串口指令配置控制器参数,并给出相机端触发联动的最小验证代码。

关键完整代码

# 光源控制器频闪触发配置(串口指令方式)
import serial
import time

# 控制器串口参数(依据设备手册调整)
SERIAL_PORT = 'COM3'
BAUDRATE = 115200
TIMEOUT = 0.5

# 指令帧格式(以OPT-DPA系列为例,实际以手册为准)
# 帧头 + 地址 + 命令字 + 数据 + 校验
FRAME_HEAD = 0xAA
ADDR = 0x01

def build_frame(cmd, data):
    """构造指令帧:帧头+地址+命令+数据长度+数据+累加和校验"""
    length = len(data)
    frame = bytes([FRAME_HEAD, ADDR, cmd, length]) + data
    checksum = sum(frame) & 0xFF
    return frame + bytes([checksum])

def set_strobe_mode(ser, current_ma=100, pulse_us=500):
    """
    配置频闪模式:
    - 工作模式:频闪(外部触发)
    - 恒流值:current_ma(毫安)
    - 触发脉宽:pulse_us(微秒)
    """
    # 命令0x10:设置工作模式为频闪(0x02表示外部触发频闪)
    mode_cmd = build_frame(0x10, bytes([0x02]))
    ser.write(mode_cmd)
    time.sleep(0.05)

    # 命令0x11:设置恒流值(2字节,单位mA)
    current_bytes = current_ma.to_bytes(2, 'little')
    current_cmd = build_frame(0x11, current_bytes)
    ser.write(current_cmd)
    time.sleep(0.05)

    # 命令0x12:设置触发脉宽(2字节,单位us)
    pulse_bytes = pulse_us.to_bytes(2, 'little')
    pulse_cmd = build_frame(0x12, pulse_bytes)
    ser.write(pulse_cmd)
    time.sleep(0.05)

    print(f"[配置完成] 频闪模式 | 电流={current_ma}mA | 脉宽={pulse_us}us")

def read_controller_status(ser):
    """读取控制器状态,验证配置是否生效"""
    query_cmd = build_frame(0x20, b'')  # 0x20:查询状态
    ser.write(query_cmd)
    resp = ser.read(8)
    if len(resp) >= 6:
        mode = resp[4]
        current = int.from_bytes(resp[5:7], 'little')
        print(f"[状态] 模式码={mode} | 设定电流={current}mA")
        return mode == 0x02
    return False

if __name__ == '__main__':
    try:
        ser = serial.Serial(SERIAL_PORT, BAUDRATE, timeout=TIMEOUT)
        set_strobe_mode(ser, current_ma=150, pulse_us=300)
        ok = read_controller_status(ser)
        print("配置验证:", "通过" if ok else "失败")
        ser.close()
    except serial.SerialException as e:
        print(f"串口打开失败: {e}")

相机端触发联动(验证用最小代码)

# 相机硬件触发 + 光源频闪联动(以海康MVS SDK为例)
from mvsdk import MvCamera

# 初始化相机并设置为硬件触发
cam = MvCamera()
cam.open_device(0)
cam.set_trigger_mode(1)  # 1=硬件触发
cam.set_trigger_source(0)  # Line0

# 开始采集(每次外部触发,相机曝光同时光源频闪)
cam.start_grabbing()
frame = cam.get_frame(timeout=1000)  # 等待触发帧
if frame is not None:
    print(f"采集成功,图像尺寸: {frame.width}x{frame.height}")
cam.stop_grabbing()
cam.close_device()

运行与验证

  1. 配置控制器:运行Python脚本,串口连接控制器,观察输出“配置完成”和“配置验证:通过”。
  2. 验证频闪效果:用信号发生器输出5V/10Hz方波到控制器TRIG+,目视光源应随触发信号闪烁(亮灭交替),而非常亮。
  3. 联动验证:将相机触发输出接入控制器触发输入,运行相机采集代码。在正常环境光下,连续采集10帧,观察图像亮度是否稳定且无明显环境光过曝。
  4. 判定标准:光源仅在触发时点亮(可用手机慢动作视频确认);相机采集的图像亮度均匀,无频闪条纹或环境光干扰造成的亮度波动。

常见问题

  • 光源不亮:检查触发信号电平是否匹配(多数控制器支持5-24V),确认脉宽设置是否过短(建议≥100μs)。
  • 图像有明暗条纹:触发频率与相机帧率不匹配,或脉宽大于相机曝光时间,应确保脉宽略小于曝光时间。
  • 串口无响应:确认控制器地址(默认0x01)和波特率是否与设备手册一致。