
工业相机"心跳"监测脚本(C# 版) 支持海康 / Basler / 堡盟,一套代码搞定多品牌在线状态监控!
"产线半夜停机,发现相机离线了?"
"PLC 发了触发信号,但相机没反应?"
"现场网络一抖,相机就'假死'?"
在工业视觉系统中,相机的在线状态 是整个检测流程的基石。然而,不同品牌的相机 SDK 各有千秋,如何用统一、高效、低开销的方式监控它们的"心跳"?
本文将为你揭晓答案,并提供一份可直接复用的 C# 跨平台心跳监测脚本,完美支持 海康(Hikvision)、Basler、堡盟(Baumer) 三大主流品牌。
🤔 一、什么是"心跳"?为什么需要它?
- 心跳(Heartbeat):指定期向相机发送一个轻量级指令(如读取设备信息),并等待其响应。
- 目的 :
- 实时感知相机是否在线。
- 提前预警网络中断或相机异常。
- 避免因相机"假死"导致的产线长时间停机。
💡 关键点 :心跳操作必须极其轻量,不能干扰正常的图像采集流程。
🔧 二、各品牌 .NET SDK 的心跳实现方式
| 品牌 | SDK | 心跳方法 | 注意事项 |
|---|---|---|---|
| 海康 (Hikvision) | MVS .NET SDK | MyCamera.GetDeviceInfo() |
需要先打开设备,调用后无需关闭。 |
| Basler | pylon .NET | Camera.CameraInfo[CameraInfoKey.ModelName] |
可以在不开启流的情况下获取信息。 |
| 堡盟 (Baumer) | Baumer GAPI .NET | camera.GetModel() |
设备对象保持打开即可,调用非常快。 |
💻 三、核心代码:跨品牌心跳监测器(C#)
我们使用 C# 8.0+ 和 接口 + 工厂模式,将不同品牌的实现细节封装起来。
1. 定义通用接口 (ICameraHeartbeat.cs)
csharp
// ICameraHeartbeat.cs
using System;
public interface ICameraHeartbeat : IDisposable
{
// 初始化连接
bool Connect(string deviceID);
// 执行一次心跳检查
bool Ping();
// 获取品牌名称
string GetBrandName();
}
2. 海康相机实现 (HikHeartbeat.cs)
csharp
// HikHeartbeat.cs
using System;
using MvCamCtrl.NET; // 引用海康MVS SDK
public class HikHeartbeat : ICameraHeartbeat
{
private MyCamera camera = new MyCamera();
private bool isConnected = false;
public bool Connect(string deviceID)
{
var deviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
MyCamera.MV_CC_EnumDevices(MyCamera.MV_GIGE_DEVICE, ref deviceList);
for (int i = 0; i < deviceList.nDeviceNum; i++)
{
var devInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(
deviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
// 这里可以根据deviceID进行匹配(例如通过IP或序列号)
if (/* 匹配逻辑 */)
{
int nRet = camera.MV_CC_CreateDevice(ref devInfo);
if (nRet == MyCamera.MV_OK)
{
nRet = camera.MV_CC_OpenDevice();
isConnected = (nRet == MyCamera.MV_OK);
return isConnected;
}
}
}
return false;
}
public bool Ping()
{
if (!isConnected) return false;
var devInfo = new MyCamera.MV_CC_DEVICE_INFO();
int nRet = camera.MV_CC_GetDeviceInfo(ref devInfo);
return (nRet == MyCamera.MV_OK);
}
public string GetBrandName() => "Hikvision";
public void Dispose()
{
if (isConnected)
{
camera.MV_CC_CloseDevice();
camera.MV_CC_DestroyDevice();
isConnected = false;
}
}
}
3. Basler 相机实现 (BaslerHeartbeat.cs)
csharp
// BaslerHeartbeat.cs
using System;
using Basler.Pylon; // 引用pylon .NET SDK
public class BaslerHeartbeat : ICameraHeartbeat
{
private Camera camera;
private bool isConnected = false;
public bool Connect(string deviceID)
{
try
{
// 可根据deviceID(如序列号)精确查找
camera = new Camera();
camera.Open();
isConnected = true;
return true;
}
catch
{
return false;
}
}
public bool Ping()
{
if (!isConnected) return false;
try
{
// 访问任意CameraInfo属性即可触发通信
_ = camera.CameraInfo[CameraInfoKey.ModelName];
return true;
}
catch
{
return false;
}
}
public string GetBrandName() => "Basler";
public void Dispose()
{
camera?.Close();
camera?.Dispose();
isConnected = false;
}
}
4. 主监控服务 (HeartbeatService.cs)
csharp
// HeartbeatService.cs
using System;
using System.Threading;
using System.Threading.Tasks;
public class HeartbeatService
{
private readonly ICameraHeartbeat camera;
private readonly int intervalMs;
private CancellationTokenSource cts;
public HeartbeatService(ICameraHeartbeat camera, int intervalMs = 1000)
{
this.camera = camera;
this.intervalMs = intervalMs;
}
public async Task StartAsync()
{
cts = new CancellationTokenSource();
_ = Task.Run(async () =>
{
while (!cts.Token.IsCancellationRequested)
{
bool isAlive = camera.Ping();
Console.WriteLine($"[{camera.GetBrandName()}] 心跳: {(isAlive ? "正常" : "失败!")}");
if (!isAlive)
{
// TODO: 集成企业微信/邮件告警
}
await Task.Delay(intervalMs, cts.Token);
}
}, cts.Token);
}
public void Stop() => cts?.Cancel();
}
5. 使用示例
csharp
// Program.cs
class Program
{
static async Task Main(string[] args)
{
// 示例:监控一台Basler相机
var baslerCamera = new BaslerHeartbeat();
if (baslerCamera.Connect("Your_Basler_Serial_Number"))
{
var service = new HeartbeatService(baslerCamera, 1000);
await service.StartAsync();
// 主程序继续运行...
Console.ReadLine();
service.Stop();
}
}
}
⚠️ 四、重要注意事项
- 资源释放 :务必实现
IDisposable并正确释放 SDK 对象,防止句柄泄漏。 - 线程安全 :心跳线程与主图像采集线程不要共享同一个相机实例。建议为心跳单独创建一个轻量级连接。
- 频率选择 :心跳间隔建议 500ms - 2000ms。过快会增加网络负担,过慢则失去预警意义。
- 堡盟特殊功能 :堡盟相机支持
HeartbeatTimeout功能,可配置相机在收不到心跳时自动断开连接,这是最可靠的方式,应优先使用。
💬 结语
一个健壮的心跳监测机制,是工业视觉系统稳定运行的"定海神针"。通过本文提供的跨品牌 C# 模板,你可以快速为你的项目加上这道保险。
让每一台相机都"活"在你的掌控之中。