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

工业相机"心跳"监测脚本(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();
        }
    }
}

⚠️ 四、重要注意事项

  1. 资源释放 :务必实现 IDisposable 并正确释放 SDK 对象,防止句柄泄漏。
  2. 线程安全 :心跳线程与主图像采集线程不要共享同一个相机实例。建议为心跳单独创建一个轻量级连接。
  3. 频率选择 :心跳间隔建议 500ms - 2000ms。过快会增加网络负担,过慢则失去预警意义。
  4. 堡盟特殊功能 :堡盟相机支持 HeartbeatTimeout 功能,可配置相机在收不到心跳时自动断开连接,这是最可靠的方式,应优先使用。

💬 结语

一个健壮的心跳监测机制,是工业视觉系统稳定运行的"定海神针"。通过本文提供的跨品牌 C# 模板,你可以快速为你的项目加上这道保险。

让每一台相机都"活"在你的掌控之中。

相关推荐
404号扳手2 小时前
03大模型核心原理
人工智能·llm
我能坚持多久2 小时前
String类常用接口的实现
c语言·开发语言·c++
沪漂阿龙在努力2 小时前
深度拆解LangChain Chains与LCEL:从Runnable到生产级AI工作流
人工智能
花间相见2 小时前
【大模型微调与部署03】—— ms-swift-3.12 命令行参数(训练、推理、对齐、量化、部署全参数)
开发语言·ios·swift
AI专业测评2 小时前
2026网文圈大地震:顶配AI写作神器实测,这几款让“代练”彻底失业
人工智能·算法·aigc·ai写作
轻口味2 小时前
HarmonyOS 6 轻相机应用开发1:功能介绍与框架搭建
数码相机·华为·harmonyos
默 语2 小时前
Java的“后路“:不是退场,而是换了一种活法
java·开发语言·python
t***5442 小时前
Orwell Dev-C++和Embarcadero Dev-C++哪个更稳定
开发语言·c++
七月稻草人2 小时前
ToClaw炒股个人踩坑实录:我实盘 2 个月踩过的坑、避坑指南与真实使用感受
大数据·人工智能·toclaw