3. 工业相机接口与触发模式配置
任务目标
完成工业相机(以海康威视MV-CA系列GigE接口相机为例)的接口初始化与三种触发模式配置:连续采集模式、软件触发模式、硬件外触发模式。通过代码实现相机的连接、参数配置、取流启停,并验证每种模式下图像采集是否按预期工作。
环境依赖
- 海康威视MVS SDK(含
MvCameraControl.h与链接库) - GigE接口工业相机一台(或MVS虚拟相机用于调试)
- 千兆网口、网线(或虚拟网卡)
- Visual Studio 2019+ / GCC,C++11及以上
关键完整代码
#include <stdio.h>
#include <string.h>
#include <chrono>
#include <thread>
#include "MvCameraControl.h"
// 错误码打印
#define CHECK(expr) do { \
int ret = (expr); \
if (ret != MV_OK) { \
printf("Error at %s:%d - ret=0x%X\n", __FILE__, __LINE__, ret); \
return ret; \
} \
} while(0)
// 枚举并连接第一个GigE相机
int ConnectCamera(MV_CC_DEVICE_INFO_HANDLE* deviceHandle) {
MV_CC_DEVICE_INFO_LIST deviceList;
memset(&deviceList, 0, sizeof(deviceList));
CHECK(MV_CC_EnumDevices(MV_GIGE_DEVICE, &deviceList));
if (deviceList.nDeviceNum == 0) {
printf("No GigE camera found.\n");
return MV_E_NODATA;
}
// 打印设备信息
MV_CC_DEVICE_INFO* pInfo = deviceList.pDeviceInfo[0];
printf("Connecting to: %s\n", pInfo->SpecialInfo.stGigEInfo.chModelName);
CHECK(MV_CC_CreateHandle(deviceHandle, pInfo));
CHECK(MV_CC_OpenDevice(*deviceHandle));
return MV_OK;
}
// 配置触发模式: 0=连续, 1=软件触发, 2=硬件外触发(Line0)
int SetTriggerMode(MV_CC_DEVICE_INFO_HANDLE handle, int mode) {
MVCC_ENUMVALUE trigMode = {0};
CHECK(MV_CC_GetEnumValue(handle, "TriggerMode", &trigMode));
trigMode.nCurValue = (mode == 0) ? MV_TRIGGER_MODE_OFF : MV_TRIGGER_MODE_ON;
CHECK(MV_CC_SetEnumValue(handle, "TriggerMode", trigMode.nCurValue));
if (mode == 0) {
// 连续模式:关闭触发源
CHECK(MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE));
printf("Trigger: Continuous mode\n");
} else if (mode == 1) {
// 软件触发
CHECK(MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE));
printf("Trigger: Software mode\n");
} else if (mode == 2) {
// 硬件外触发:Line0上升沿
CHECK(MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0));
CHECK(MV_CC_SetEnumValue(handle, "TriggerActivation", MV_TRIGGER_ACTIVATION_RISINGEDGE));
printf("Trigger: Hardware Line0 rising edge\n");
}
return MV_OK;
}
// 采集一帧图像(带超时)
int GrabOneFrame(MV_CC_DEVICE_INFO_HANDLE handle, unsigned char* buf, int bufSize, MV_FRAME_OUT_INFO_EX* frameInfo) {
memset(frameInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));
CHECK(MV_CC_StartGrabbing(handle));
CHECK(MV_CC_GetOneFrameTimeout(handle, buf, bufSize, frameInfo, 1000));
CHECK(MV_CC_StopGrabbing(handle));
return MV_OK;
}
int main() {
MV_CC_DEVICE_INFO_HANDLE handle = NULL;
CHECK(ConnectCamera(&handle));
// 设置像素格式为Mono8以减小数据量(可选)
CHECK(MV_CC_SetEnumValue(handle, "PixelFormat", MV_PIXEL_FORMAT_MONO8));
unsigned char* frameBuf = new unsigned char[2048 * 2048]; // 预留足够空间
MV_FRAME_OUT_INFO_EX frameInfo;
// ---- 模式1: 连续采集 ----
CHECK(SetTriggerMode(handle, 0));
CHECK(GrabOneFrame(handle, frameBuf, 2048 * 2048, &frameInfo));
printf("Continuous: got frame %d x %d, size=%d\n",
frameInfo.nWidth, frameInfo.nHeight, frameInfo.nFrameLen);
// ---- 模式2: 软件触发 ----
CHECK(SetTriggerMode(handle, 1));
CHECK(MV_CC_StartGrabbing(handle));
CHECK(MV_CC_SetCommandValue(handle, "TriggerSoftware")); // 软触发命令
CHECK(MV_CC_GetOneFrameTimeout(handle, frameBuf, 2048 * 2048, &frameInfo, 1000));
CHECK(MV_CC_StopGrabbing(handle));
printf("Software trigger: got frame %d x %d\n", frameInfo.nWidth, frameInfo.nHeight);
// ---- 模式3: 硬件外触发 ----
CHECK(SetTriggerMode(handle, 2));
printf("Hardware trigger: waiting for external signal on Line0...\n");
CHECK(GrabOneFrame(handle, frameBuf, 2048 * 2048, &frameInfo));
printf("Hardware trigger: got frame %d x %d\n", frameInfo.nWidth, frameInfo.nHeight);
delete[] frameBuf;
CHECK(MV_CC_CloseDevice(handle));
CHECK(MV_CC_DestroyHandle(handle));
printf("All trigger modes verified successfully.\n");
return 0;
}
编译与运行
- 在MVS SDK安装目录下,将
Development\Includes加入头文件路径,Development\Libraries\win64加入库路径,链接MvCameraControl.lib。 - 编译:
g++ -o trigger_demo trigger_demo.cpp -I"$(MVS_ROOT)/Development/Includes" -L"$(MVS_ROOT)/Development/Libraries/win64" -lMvCameraControl(Windows下使用MSVC对应命令)。 - 运行前确保相机已连接且IP配置正确(可用MVS客户端工具确认相机可见)。
- 硬件触发模式需将信号发生器或PLC输出接至相机Line0引脚(建议3.3V TTL电平)。
验证方法与判定标准
- 连续模式:程序启动后应立即打印一帧图像的宽高与大小,无需外部信号。
- 软件触发:程序调用
TriggerSoftware命令后1秒内应收到图像,打印尺寸信息。 - 硬件触发:程序运行至该阶段后阻塞等待,此时向Line0输入一个上升沿脉冲(如按下按钮或由信号发生器输出),应能收到一帧图像并打印。
- 三种模式均打印出正确的图像尺寸(与相机分辨率一致)且无错误码,即判定通过。
常见问题
- 枚举不到相机:检查网线连接、关闭防火墙、使用MVS工具配置相机IP与主机IP在同一网段。
- 硬件触发无响应:确认Line0接线正确,触发源选择与相机硬件版本匹配(部分型号需用Line2或光耦输入)。
- 取流超时:连续模式下若曝光时间过长,可先减小曝光值;硬件触发时确认信号脉宽大于相机最小触发脉宽(通常>10μs)。