从视觉检测到PLC控制:C#上位机如何实现工业现场多设备联动?

上个月接了个汽配厂的活,他们的发动机密封垫产线之前全靠人工目检,一天下来工人眼睛花,漏检率还高。老板要求搞个“眼睛+大脑+手脚”的系统:用相机当眼睛,YOLO当大脑,PLC当手脚,检测到缺陷直接分拣。花了三周时间调通,今天把这套C#上位机+YOLO+PLC的联动方案拆解开,从架构到代码,全是能直接落地的干货。
一、系统整体架构:稳定压倒一切
先给大家看这套系统的核心架构,没有花里胡哨的设计,全是工业现场验证过的可靠组合:
为什么这么选?给大家算笔账:
- C#上位机:厂里老系统都是WinForms,技术栈统一,维护成本低;
- YOLOv8n:速度快(640x640分辨率推理<50ms),精度够,导出ONNX后能直接在C#里跑,不用装Python环境;
- Modbus TCP:不用额外装OPC UA服务器,PLC侧编程简单,连车间电工都能看懂;
- 西门子S7-1200:稳定,抗干扰,汽配厂车间里的电磁干扰根本不是事。
二、核心模块实现:每一行代码都为7x24小时运行设计
1. YOLO视觉检测:从模型到C#调用的全流程
第一步:模型准备
我用LabelImg标注了5000张密封垫缺陷图(划痕、变形、气泡各占1/3),训练YOLOv8n,重点是导出ONNX格式时要加上--opset 12参数,否则C#里的ONNX Runtime会报错。
第二步:C#调用ONNX Runtime
这里有两个坑必须提醒大家:一是图像预处理必须和训练时完全一致(Resize到640x640、RGB通道、归一化到0-1);二是一定要用using语句释放资源,否则产线跑一晚上内存就爆了。
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
public class YoloDetector
{
private readonly InferenceSession _session;
private readonly string[] _classNames = { "划痕", "变形", "气泡" };
public YoloDetector(string modelPath)
{
var sessionOptions = new SessionOptions();
sessionOptions.AppendExecutionProvider_CPU(0); // 用CPU推理,工控机没显卡也能跑
_session = new InferenceSession(modelPath, sessionOptions);
}
public List<DetectionResult> Detect(Mat image)
{
// 1. 图像预处理:Resize、转RGB、归一化
var resized = image.Resize(new Size(640, 640));
var rgb = new Mat();
Cv2.CvtColor(resized, rgb, ColorConversionCodes.BGR2RGB);
var inputTensor = ConvertMatToTensor(rgb);
// 2. 推理
var inputs = new List<NamedOnnxValue>
{
NamedOnnxValue.CreateFromTensor("images", inputTensor)
};
using var results = _session.Run(inputs);
// 3. 后处理:NMS去重、解析检测框
return PostProcess(results, 0.5f, 0.4f); // 置信度0.5,NMS阈值0.4
}
private DenseTensor<float> ConvertMatToTensor(Mat mat)
{
var tensor = new DenseTensor<float>(new[] { 1, 3, 640, 640 });
var data = mat.GetData<byte>();
for (int i = 0; i < 640; i++)
{
for (int j = 0; j < 640; j++)
{
tensor[0, 0, i, j] = data[(i * 640 + j) * 3 + 0] / 255f; // R
tensor[0, 1, i, j] = data[(i * 640 + j) * 3 + 1] / 255f; // G
tensor[0, 2, i, j] = data[(i * 640 + j) * 3 + 2] / 255f; // B
}
}
return tensor;
}
// PostProcess方法省略,核心是NMS和坐标转换
}
2. C#与PLC通信:加心跳、重连,一个都不能少
通信我选了工业界用烂的HslCommunication库,稳定、文档全。但工业现场最容易出问题的就是通信,所以我加了两个关键机制:心跳包和自动重连。
using HslCommunication.ModBus;
using System.Threading;
public class PlcController
{
private readonly ModbusTcpNet _plc;
private Thread _heartBeatThread;
private volatile bool _isRunning;
public PlcController(string ip, int port = 502)
{
_plc = new ModbusTcpNet(ip, port);
_plc.ConnectTimeOut = 2000; // 连接超时2秒
}
public bool Connect()
{
var result = _plc.ConnectServer();
if (!result.IsSuccess)
{
Console.WriteLine($"PLC连接失败:{result.Message}");
return false;
}
// 启动心跳线程
_isRunning = true;
_heartBeatThread = new Thread(HeartBeatLoop) { IsBackground = true };
_heartBeatThread.Start();
return true;
}
private void HeartBeatLoop()
{
while (_isRunning)
{
Thread.Sleep(5000); // 每5秒心跳一次
var result = _plc.ReadInt16("M100"); // 读一个无关的寄存器做心跳
if (!result.IsSuccess)
{
Console.WriteLine("PLC心跳失败,尝试重连...");
_plc.ConnectServer();
}
}
}
public bool SendDefectSignal(bool hasDefect)
{
// 写入M100:1=有缺陷,0=正常,重试3次
for (int i = 0; i < 3; i++)
{
var result = _plc.Write("M100", (short)(hasDefect ? 1 : 0));
if (result.IsSuccess) return true;
Thread.Sleep(100);
}
Console.WriteLine("写入PLC失败,已重试3次");
return false;
}
public void Disconnect()
{
_isRunning = false;
_heartBeatThread?.Join();
_plc.ConnectClose();
}
}
3. PLC控制逻辑:简单到电工都能维护
PLC侧我用西门子TIA Portal写的,逻辑非常简单:当M100为1时,Q0.0输出触发分拣气缸,延迟2秒后复位。给大家看时序图,一目了然:
三、实战效果:三个月收回成本,老板笑开了花
这套系统上线后,我每周都去汽配厂跟进数据,给大家看真实的效果:
- 人工成本:从6个目检工减到1个(只负责补料和设备巡检),每月省3万;
- 漏检率:从5%降到0.1%,客户投诉几乎为零;
- 产线节拍:从每分钟30件提到40件,产能提升33%。
唯一的小插曲是车间里的电磁干扰,一开始相机偶尔丢帧,后来给相机的GigE线加了两个磁环,问题就解决了。
四、常见问题与优化建议
1. 推理速度不够快怎么办?
如果产线节拍要求更高(比如每分钟60件),可以试试这两个方法:
- 模型量化:用ONNX Runtime把FP32模型转成INT8,速度能提30%,精度损失不到1%;
- OpenVINO加速:如果工控机是Intel的CPU,用OpenVINO执行Provider,推理速度能再提20%。
2. 通信丢包怎么解决?
除了我代码里的心跳和重连,还可以加两个机制:
- 请求确认:PLC收到信号后,写一个寄存器给上位机确认,没收到确认就重发;
- 报警机制:连续5次通信失败,上位机弹出报警窗口,同时触发PLC的声光报警。
3. 相机触发时机怎么选?
尽量用硬件触发(比如PLC输出一个24V信号给相机),不要用软件定时触发。硬件触发能保证每次拍照都在产品的同一位置,检测精度更高。
最后说两句
工业现场的多设备联动,从来不是拼技术有多高深,而是拼稳定、可靠、易维护。C#上位机+YOLO+PLC这套组合,既能利用YOLO的强大视觉能力,又能发挥PLC的控制稳定性,而且对传统工控人非常友好——不用学Python,不用搞复杂的框架,就能把视觉检测落地到产线。
如果大家在实际项目中遇到类似问题,欢迎一起探讨。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)