工业相机“心跳”监测脚本(C++版) 支持海康 / Basler / 堡盟工业相机

张开发
2026/4/20 7:42:43 15 分钟阅读

分享文章

工业相机“心跳”监测脚本(C++版) 支持海康 / Basler / 堡盟工业相机
工业相机“心跳”监测脚本C版 支持海康 / Basler / 堡盟一套代码搞定多品牌在线状态监控“产线半夜停机发现相机离线了”“PLC 发了触发信号但相机没反应”“现场网络一抖相机就‘假死’”在工业视觉系统中相机的在线状态是整个检测流程的基石。然而不同品牌的相机 SDK 各有千秋如何用统一、高效、低开销的方式监控它们的“心跳”本文将为你揭晓答案并提供一份可直接复用的 C 跨平台心跳监测脚本完美支持海康Hikvision、Basler、堡盟Baumer三大主流品牌。 一、什么是“心跳”为什么需要它心跳Heartbeat指定期向相机发送一个轻量级指令如读取设备信息并等待其响应。目的实时感知相机是否在线。提前预警网络中断或相机异常。避免因相机“假死”导致的产线长时间停机。关键点心跳操作必须极其轻量不能干扰正常的图像采集流程。 二、各品牌 SDK 的心跳实现方式品牌SDK心跳方法注意事项海康 (Hikvision)MVS SDKMV_CC_GetDeviceInfo()需要先打开设备句柄调用后立即释放。BaslerPylon SDKCInstantCamera::GetDeviceInfo()可以在不开启流的情况下获取信息。堡盟 (Baumer)BGAPI SDKBGAPI2::Device::GetModel()设备对象保持打开即可调用非常快。 三、核心代码跨品牌心跳监测器我们使用C17和策略模式将不同品牌的实现细节封装起来。1. 定义通用接口 (ICameraHeartbeat.h)// ICameraHeartbeat.h#pragmaonce#includestring#includechronoclassICameraHeartbeat{public:virtual~ICameraHeartbeat()default;// 初始化连接virtualboolConnect(conststd::stringdeviceID)0;// 执行一次心跳检查virtualboolPing()0;// 断开连接virtualvoidDisconnect()0;// 获取最后一次心跳的时间戳std::chrono::steady_clock::time_pointGetLastPingTime()const{returnlast_ping_time_;}// 获取品牌名称virtualstd::stringGetBrandName()const0;protected:std::chrono::steady_clock::time_point last_ping_time_;};2. 海康相机实现 (HikHeartbeat.cpp)// HikHeartbeat.cpp#includeICameraHeartbeat.h#includeMvCameraControl.h// 海康MVS SDK头文件classHikHeartbeat:publicICameraHeartbeat{public:boolConnect(conststd::stringdeviceID)override{// 通过设备ID查找并打开设备MV_CC_DEVICE_INFO_LIST stDevList;MV_CC_EnumDevices(MV_GIGE_DEVICE,stDevList);for(inti0;istDevList.nDeviceNum;i){MV_CC_DEVICE_INFO*pDevInfostDevList.pDeviceInfo[i];if(/* 匹配deviceID */){nRetMV_CC_CreateHandle(handle_,pDevInfo);if(nRetMV_OK){nRetMV_CC_OpenDevice(handle_);returnnRetMV_OK;}}}returnfalse;}boolPing()override{MV_CC_DEVICE_INFO stDevInfo;intnRetMV_CC_GetDeviceInfo(handle_,stDevInfo);last_ping_time_std::chrono::steady_clock::now();return(nRetMV_OK);}voidDisconnect()override{if(handle_){MV_CC_CloseDevice(handle_);MV_CC_DestroyHandle(handle_);handle_nullptr;}}std::stringGetBrandName()constoverride{returnHikvision;}private:void*handle_nullptr;};3. Basler 相机实现 (BaslerHeartbeat.cpp)// BaslerHeartbeat.cpp#includeICameraHeartbeat.h#includepylon/PylonIncludes.hclassBaslerHeartbeat:publicICameraHeartbeat{public:boolConnect(conststd::stringdeviceID)override{try{Pylon::CTlFactoryTlFactoryPylon::CTlFactory::GetInstance();camera_newPylon::CInstantCamera(TlFactory.CreateFirstDevice());// 这里可以根据deviceID进行更精确的匹配camera_-Open();returntrue;}catch(constGenICam::GenericException){returnfalse;}}boolPing()override{try{// 即使相机未开启流也能获取设备信息autoinfocamera_-GetDeviceInfo();last_ping_time_std::chrono::steady_clock::now();returntrue;}catch(constGenICam::GenericException){returnfalse;}}voidDisconnect()override{if(camera_camera_-IsOpen()){camera_-Close();}deletecamera_;camera_nullptr;}std::stringGetBrandName()constoverride{returnBasler;}private:Pylon::CInstantCamera*camera_nullptr;};4. 主监控循环// main.cpp#includethread#includechrono#includememory#includeiostreamvoidHeartbeatMonitorLoop(std::unique_ptrICameraHeartbeatcamera,intinterval_ms){while(true){boolisAlivecamera-Ping();autonowstd::chrono::steady_clock::now();autolastcamera-GetLastPingTime();autodiffstd::chrono::duration_caststd::chrono::milliseconds(now-last).count();if(!isAlive){std::cout[camera-GetBrandName()] 心跳失败离线超过 diff msstd::endl;// 此处可集成企业微信/邮件告警}else{std::cout[camera-GetBrandName()] 心跳正常 (diff ms)std::endl;}std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms));}}intmain(){// 示例监控一台海康相机autohik_camerastd::make_uniqueHikHeartbeat();if(hik_camera-Connect(Your_Hik_Device_ID)){std::thread(HeartbeatMonitorLoop,std::move(hik_camera),1000).detach();}// 主程序继续执行其他任务...while(true){/* ... */}}⚠️ 四、重要注意事项资源管理务必确保在Disconnect中正确释放 SDK 句柄否则极易造成内存泄漏。线程安全心跳线程与主图像采集线程不要共享同一个设备句柄。建议为心跳单独创建一个轻量级连接。频率选择心跳间隔建议500ms - 2000ms。过快会增加网络负担过慢则失去预警意义。堡盟特殊功能堡盟相机支持HeartbeatTimeout功能可配置相机在收不到心跳时自动断开连接这是最可靠的方式应优先使用。 结语一个健壮的心跳监测机制是工业视觉系统稳定运行的“定海神针”。通过本文提供的跨品牌 C 模板你可以快速为你的项目加上这道保险。让每一台相机都“活”在你的掌控之中。

更多文章