PLC+HMI+边缘AI融合控制器实战:视觉检测项目全流程解析

发布时间:2026/9/28 18:16:01
PLC+HMI+边缘AI融合控制器实战:视觉检测项目全流程解析 1. 为什么“PLCHMI边缘AI”要装进一台设备第一次把宏集DC-Pi接进电控柜时我下意识摸了摸外壳确认它不是一块树莓派套了个工业壳。真正把程序跑起来之后我才意识到这台设备改变的不是体积而是整个设备开发的思路。过去做一个带视觉检测的工位电控柜里至少要塞三个盒子PLC负责逻辑控制触摸屏负责交互工控机或者AI盒子负责图像识别。三个盒子之间用MODBUS、OPC UA、继电器IO线互相咬合调试时先要把PLC程序下载下去再给触摸屏刷画面接着在工控机上装Python环境、装推理模型最后还得花大量的时间做标签映射和通讯对接。一个简单的“相机检测到缺陷后气缸剔除”动作现场调半天很正常。DC-Pi的核心价值就是把这三样东西放到同一台设备里用一个IP地址、一套数据空间把PLC、HMI、边缘AI串起来。这篇文章不写产品说明书我按照自己实际调试一个视觉检测项目的过程来聊先从设计思路讲清楚它为什么能融合三类角色再拆开硬件和软件栈然后给出一条能直接复现的实操路径最后把现场踩过的坑整理成排查清单。无论你是做PLC出身的老工控人还是熟悉Python但刚碰工业设备的AI工程师这篇文章应该能帮你省掉不少弯路。1.1 传统“三件套”方案的痛点“三件套”方案本身没有问题中小型设备上它是最成熟的组合。但用久了你会发现痛点非常集中三个设备来自不同厂家软件各是一套工程师的技能要求也被迫扩大到PLC编程、组态软件、Linux应用三个方向数据互通要提前约定好协议Modbus TCP便宜但数据类型简单OPC UA好用但标签配置和服务器部署都费时间电控柜里的走线、开关电源、串口服务器、网线布局每多一台设备就多一层故障点最麻烦的是调试阶段PLC说数据写过去了AI程序说没读到经常要靠Wireshark抓包判断到底是谁的问题。这些痛点对大型产线来说可以忍因为有专门的电气工程师和软件工程师分工。但对单机设备、小型产线、改造项目来说集成成本太高。设备越小型化越需要“一台设备干完所有事”。DC-Pi这类融合控制器的出现本质上是把曾经默契配合的几个角色硬生生合并进了同一个处理器。1.2 DC-Pi的设计思路一个IP一套数据空间拆开DC-Pi的软件架构你会发现它没有把PLC逻辑做成Linux上的一个模拟软件那么简单。我手头这台设备PLC运行时跑在单独的核心上HMI和AI推理跑在另一套应用环境里两套环境之间通过本地数据和虚拟IO交换信息。也就是说PLC不用关心AI模型是OpenCV跑的还是ONNX Runtime跑的AI程序也不用去解析Modbus报文。两边共享一套变量空间HMI天然就能直接读到PLC里的线圈状态和AI返回的结果。这在逻辑上等同于把以前“PLC以太网口对工控机网口”的网络通讯变成了同一台设备内部的内存复制毛病一下少了很多。边缘AI在这个架构里的位置也比较务实它不追求在设备上做训练而是只做推理。模型在PC上用GPU训练好再转换成ONNX或TensorFlow Lite格式部署进去。这样既保住了数据不出厂区的隐私性也不需要让控制器去扛训练的巨大算力。后面我会用一个真实项目把这条链路完整串起来。2. 硬件底子与软件栈一台DC-Pi内部到底怎么分工网上很多介绍融合控制器的文章上来就列接口参数看完还是不知道里面的软件怎么协作。这一节我把硬件和软件栈分开讲重点说清楚“实时控制”和“非实时AI”为什么能在一台机器里共存。2.1 配置接口它不是树莓派换了个壳我拿到的DC-Pi版本核心配置大致如下具体批次可能有差别但整体定位差不多项目参数用途说明CPU四核ARM Cortex-A721.8GHz无风扇被动散热适合导轨安装内存4GB LPDDR4同时跑PLC运行时、HMI服务和轻量AI推理足够存储32GB eMMC存放系统、HMI工程、模型文件和本地日志电源24V DC和绝大多数PLC、传感器统一供电工业接口2路千兆以太网、2路RS232/485、8路DI、8路DO、4路AI/AO覆盖中小型设备的常见IO需求扩展能力mPCIe、USB、HDMI可扩展相机、Wi-Fi、4G/5G模块这个配置里CPU算力放在工控机领域并不算猛但它跑的是ARM架构功耗低、无风扇、能塞进导轨电控箱。关键是它把工业IO也做进去了意味着AI程序可以直接关联DI/DO信号而不需要再挂一个USB转IO模块。有的同行问为什么不用性能更猛的x86我的理解是这类设备要的是“够用”而不是“跑分”。在中低速视觉检测、设备状态监测这类场景里INT8量化后的轻量模型在ARM上跑几十毫秒一帧完全能接受换来的是整机功耗和稳定性。你非要拿它去跑深度学习大模型实时检测高速产线那还是老老实实上独立GPU。2.2 软件栈实时控制和非实时AI怎样共存DC-Pi的软件栈可以分成两层看第一层是实时控制层。设备内置了基于IEC 61131-3的PLC运行时支持梯形图、结构化文本ST、功能块图等编程语言。工程软件用的是Codesys生态这意味着网上大量关于Codesys、Inoproshop的教程和技巧可以迁移过来。实时层主要干三件事采集DI/AI信号、执行逻辑控制、输出DO/AO信号。这一层的任务周期一般在1到10毫秒必须稳定不能因为AI推理把吞吐抢走就卡顿。第二层是应用层跑的是Linux系统。HMI Web服务和AI推理服务都在这一层。HMI以网页形式提供现场触摸屏或办公室电脑用浏览器就能打开不用安装客户端。AI服务可以用Python、Node-RED等工具编写调用摄像头、加载ONNX或TensorFlow Lite模型。两层之间通过一个本地高速数据通道交换变量。PLC定义一个bTriggerToAI变量AI服务读到这个变量后就会去执行拍照推理再把结果写回bAIResultNG和bAIResultReady。整个过程不需要走以太网也没有网关转发所以数据一致性比传统的跨设备通讯好得多。如果你只把DC-Pi当成“一个能跑Python的PLC”那理解就偏了。它的价值是两个运行时共享同一套变量空间让AI的结果在下一拍就能被PLC逻辑读到而不是绕一圈网络再回来。2.3 性能指标算力、实时性、功耗的取舍融合设备最怕的不是某项指标不够而是所有指标互相打架。这里我放几个实际运行中比较关键的指标大家可以对照自己的需求指标实测参考值说明PLC任务周期2~10ms与工程配置相关非高速运动控制够用AI单帧推理80~150msYOLOv5s INT8量化模型640x640输入HMI页面刷新200~500msWeb HMI与页面复杂度和网速有关整机功耗10~20W比传统“PLC工控机”低很多工作温度-20~60℃无风扇设计适合电控柜环境这个表说明了一个重要原则PLC周期和AI推理延迟是数量级不同的两件事。你可以拿2ms的PLC周期去处理气缸动作但别指望AI能在2ms内返回结果。合理的设计是让AI成为“非实时服务”PLC通过握手变量等待它的结果而不是把所有逻辑都压在AI的响应时间上。我见过有人把AI推理放在PLC任务里轮询结果PLC扫描周期被拖到几十毫秒报警灯闪烁都变得一顿一顿。正确做法是把AI和PLC解耦PLC发起触发AI异步返回中间用状态机等待。3. 实操从零跑通一个“AI视觉检测自动剔除”项目说了一堆架构不如跟着一个项目走一遍。下面这个案例是我在一台包装机改造上实际跑过的产品通过传送带传感器触发相机拍照AI判断外观是否有缺陷发现缺陷后由气缸把不良品推到侧边料箱。3.1 需求梳理与方案拓扑先明确系统动作序列传送带电机持续运行光电传感器检测到产品到位产生一个上升沿信号DC-Pi收到信号后通知AI服务抓拍当前相机画面AI模型判断产品外观是否有缺陷如果合格产品继续向前不动作如果缺陷PLC根据传送带速度和相机到剔除气缸的距离延时触发气缸电磁阀HMI实时显示检测总数、良品数、不良数并可查看最近的不良品照片。IO分配我这样规划信号类型说明bSensorDI0光电传感器触发信号bRejectCylinderDO0剔除气缸电磁阀bConveyorMotorDO1传送带电机接触器bEmergencyStopDI1急停按钮相机USB接口直接连到DC-Pi这个方案里相机没有走独立网卡直接插USB。原因是中低速检测场景下USB相机的带宽和延迟完全够用布线也简单。如果相机触发要求更精确后续可以改成硬件触发或者接GigE网口相机DC-Pi的千兆网口也支持。3.2 PLC侧逻辑设计状态机比梯形图更好排查在Codesys工程里我用结构化文本写了一个简单的状态机。相比梯形图ST在处理“等待AI结果”这种多状态逻辑时清晰得多尤其是后期要加连续不良判断、自动复位这些功能时ST的好处会越来越明显。核心变量声明如下VAR stMachine : INT : 0; // 0待机 1运行 2等待AI 3剔除延时 4剔除动作 bSensor : BOOL; // 传感器 bRejectCylinder : BOOL; // 气缸 bConveyorMotor : BOOL; // 传送带 bTriggerToAI : BOOL; // 通知AI拍照 bAIResultReady : BOOL; // AI返回标志 bAIResultNG : BOOL; // AI判断结果 nRejectDelay : INT; // 剔除延时计数 nTotalCount : INT; // 总检测数 nNGCount : INT; // 不良数 END_VAR主逻辑CASE stMachine OF 0: // 待机等待启动 IF bStart THEN stMachine : 1; END_IF 1: // 运行等待产品到位 IF bSensor THEN bTriggerToAI : TRUE; // 触发AI抓拍 stMachine : 2; END_IF 2: // 等待AI结果返回 IF bAIResultReady THEN nTotalCount : nTotalCount 1; IF bAIResultNG THEN nNGCount : nNGCount 1; // 按速度和距离计算延时设为扫描周期个数 nRejectDelay : 80; stMachine : 3; ELSE bTriggerToAI : FALSE; stMachine : 1; END_IF END_IF 3: // 延时等待产品到达剔除位 IF nRejectDelay 0 THEN nRejectDelay : nRejectDelay - 1; ELSE bRejectCylinder : TRUE; // 气缸推出 stMachine : 4; END_IF 4: // 保持气缸动作一定时间 stMachine : 3; // 这里简化逻辑实际会加一个到位保持定时 // 正常应该再切换回待机状态 bRejectCylinder : FALSE; bTriggerToAI : FALSE; stMachine : 1; END_CASE上面这个状态机是简化版实际项目里我会把气缸的伸出时间用单独的定时器控制避免卡在状态4里出不来回。但核心思路能体现出来PLC不直接调摄像头不直接算模型它只做两件事——发出触发信号然后等待AI的握手结果。现在网上有很多AI Agent辅助生成PLC代码的教程我也试过让大模型生成ST代码框架。拿来写状态机的骨架确实快但IO映射、时序匹配这些现场细节还是得靠工程师自己核对。我建议把AI生成的代码当参考草稿不要直接下载到设备里。3.3 HMI画面不止是按钮和指示灯DC-Pi的HMI是网页式组态不需要额外的HMI组态软件直接在浏览器里拖拽控件、绑定变量即可。和我以前用过的威纶通、组态王的体验不一样的是它的变量绑定直接对应PLC全局变量不用再搞一遍地址映射。我给这个项目做了四个页面总览页显示设备状态、当前模式、实时产量手动页手动/自动切换单独控制传送带和气缸AI监控页显示检测总数、不良数、不良率最近不良品照片缩略图点击还能放大查看报警记录页记录急停动作、连续不良等事件。关于嵌入相机画面我强烈建议把AI检测后的图片回传到本地而不是直接把实时视频流塞进HMI。Web HMI里嵌RTSP视频流虽然能看但带宽占用高多个客户端同时打开时会造成卡顿。更稳的做法是AI服务每拍一帧就把缩略图存到本地文件夹HMI相册控件去读文件列表。这样操作工能看到NG图片维修工也能翻历史实用性远超实时视频。用过西门子博途HMI仿真的人应该记得“仿真按钮无反应”的尴尬多数情况是变量连接没同步或仿真顺序不对。DC-Pi的Web HMI因为是直接绑定PLC标签少了一道中间映射这类问题基本不存在。唯一的代价是如果你现场网络不好Web页面加载会慢这时候最好把HMI工程也部署成离线模式。3.4 AI推理服务模型部署和数据回写AI服务我用的Python推理框架是ONNX Runtime。模型先用YOLOv8n在PC上训练好导出为ONNX再用INT8量化压缩最后拷贝到DC-Pi的/opt/ai/model/目录下。服务端的轮询逻辑大概这样import onnxruntime as ort import cv2 import numpy as np import time session ort.InferenceSession( /opt/ai/model/package_defect_int8.onnx, providers[CPUExecutionProvider] ) while True: # 等待PLC发出的拍照触发信号 if plc.read(bTriggerToAI): frame camera.grab() # 前处理resize到640x640归一化 blob preprocess(frame) outputs session.run(None, {session.get_inputs()[0].name: blob}) # 后处理判断是否存在缺陷 ng, conf postprocess(outputs) # 先写结果再写Ready标志位 plc.write(bAIResultNG, ng) plc.write(rAIResultConf, conf) plc.write(bAIResultReady, True) # 等待PLC复位标志位 while plc.read(bTriggerToAI): time.sleep(0.005) plc.write(bAIResultReady, False) time.sleep(0.02)这里有一个细节值得注意写回PLC变量的顺序一定是先写结果再写Ready标志位。如果反过来PLC看到Ready为TRUE时结果可能还是上一帧的旧值误判概率会大大增加。PLC和Python之间的数据访问我用的是设备内置的变量接口底层既不是Modbus也不是OPC UA而是共享内存式的本地通道。这样做的好处是写入延迟极低几乎可以和PLC扫描周期同步。但如果你用OPC UA方式联接就要注意OPC UA的采样间隔和发布间隔默认100ms的设置有时候会让PLC读到的AI结果滞后很多。3.5 联调过程延迟和节拍怎么匹配联调阶段我建议按这个顺序来不要一上来就把模型和PLC全部打开先把AI服务的输出固定成“始终NG”或“始终OK”验证PLC逻辑分支是否正确跳转再把PLC的触发标志位固定成TRUE验证相机抓拍和模型推理流程最后把两边都解开进行真实联动。验证真实联动时要测量的关键参数是“传感器触发到AI结果写回”的总延迟。我实测在INT8量化模型下单帧推理大约80到120毫秒加上相机抓拍和变量写入总延迟在150到200毫秒左右。延迟直接决定剔除气缸的延时参数。计算方法很简单相机拍照位置到剔除气缸的距离是0.6米传送带速度是0.3米/秒产品从拍照点到剔除点需要2秒PLC扫描周期是10ms那延时计数值就是2秒除以10ms等于200。如果实际跑起来发现气缸动作晚了先别急着改延时先确认传送带速度是否有波动再做二次微调。这个参数在HMI上最好开放出来因为现场不同的产品尺寸可能需要不同的延时。4. 现场最容易踩的坑与排查实录再好的设备现场调试也不会一帆风顺。下面几个问题是我和几个同行交流时出现频率最高的坑。4.1 实时任务和AI抢CPU怎么压症状PLC运行时报任务周期超时或者HMI上的指示灯刷新变慢但AI推理明明没有卡住。原因默认情况下Linux会把AI进程调度到任意核心上如果恰好抢了PLC运行时所在核心实时性就崩了。解决办法在DC-Pi的管理界面里把PLC运行时固定到某个核心比如核心0把AI进程固定到其他核心用taskset指定CPU亲和性taskset -c 2,3 python3 /opt/ai/ai_service.py 如果AI进程偶尔有高优先级需求可以再用chrt调整实时调度策略但我不建议把AI设成实时优先级否则它会反过来抢占别的系统进程。另外AI推理前做一次热身也非常关键。ONNX Runtime在第一次推理时会加载模型和初始化内存耗时可能是后续推理的好几倍。如果服务启动后第一帧触发就在冷启动状态PLC等待时间会特别长。可以在服务启动时主动跑一次空推理把模型预热完成。4.2 Codesys连接与端口设置问题很多同事第一次连DC-Pi时在Codesys网关里扫不到目标设备报“建立连接需要目标PLC的AMSNetID和端口号”。这个问题十有八九是端口号或NetID没配对。Codesys生态的PLC默认端口通常是11740但有些工程在导入设备时被改成11741两边不一致就死活连不上。遇到这个问题先到DC-Pi的系统设置页面查实际端口号再回到IDE里的连接配置中核对。还有一个常见的低级错误DC-Pi有两路网口一路是设备本身的管理口一路是PLC通讯口。把工程电脑插到管理口的工程师经常发现自己能打开HMI页面但Codesys怎么都连不上PLC。原因是管理口和PLC口分属不同网络接口得在通讯设置里指定正确的网卡地址。4.3 AI结果回写PLC的“丢数据”问题症状PLC偶尔会收到AI的Ready标志为TRUE但读到的结果还是上一次的合格状态。原因写回顺序不对结果还没更新就先置位了Ready或者因为PLC扫描周期和AI写入周期不同步PLC在同一个周期内先读了结果后读了Ready标志导致结果和标志不匹配。解决办法有几个严格保持“先写结果后写Ready”的顺序在PLC侧使用沿判断只有检测到Ready从FALSE变为TRUE的上升沿才读取结果在AI侧写一个序列号每次结果变化后让序列号加一PLC记录上一次序列号只有序列号更新才认为结果有效把结果和Ready打包成一个32位整型高位存结果低位存Ready标志一次写入避免分时不一致。我强烈建议在要求高的场合用第二种加第四种的组合可靠性最强。4.4 故障速查表下面是现场调试时我打印出来贴在电控柜上的速查表症状都是真实见过的现象可能原因排查方法PLC任务周期超时报警AI进程抢占CPU资源taskset限制AI到独立核心Codesys扫描不到设备AMSNetID或端口号不对检查设备端口号是否为11740HMI页面上PLC变量显示异常Web HMI缓存或浏览器版本太旧清理缓存使用Chrome内核浏览器AI结果偶尔误判模型训练样本不足或拍摄角度差异增加缺陷样本调整ROI区域相机抓拍延迟高USB带宽被其他设备占用换GigE相机或独立USB控制器气缸剔除动作不准传送带速度波动或延时设置不对加编码器测速PID调节速度稳定设备启动后AI服务自动退出依赖库路径不对或模型文件损坏检查systemd服务日志重新导入模型PLC里读不到AI状态变量名大小写不一致全局变量列表统一命名规范5. 这种融合方案适合你吗谈谈使用边界DC-Pi这类设备优点很明显但我不认为它能覆盖所有工业控制场景。下面把适合和不适合的情况摊开说。5.1 哪些场景真正受益第一类是中小型单机设备比如包装机、锁螺丝机、小型检测机、实验设备。它们逻辑不算复杂IO点数几十个但又要一点视觉或AI能力过去单独配一台工控机成本太高用DC-Pi刚好。第二类是对数据隐私有要求的改造项目。设备数据不出厂区检测图片都留在本地AI结果直接控制设备动作不依赖云端。对有保密要求的工厂这一点比算力更重要。第三类是分布式的设备状态监测。一台DC-Pi管一台设备通过OPC UA或MQTT把数据汇总到车间中控。由于本地已经做了边缘判断中控端的计算压力会小很多而且断网时每台设备仍能自主运行。5.2 哪些场景我还是建议用老方案如果项目需要高速多轴运动插补周期要求1ms以内我会直接选专业的运动控制器而不是在融合控制器上纠结。DC-Pi的PLC是通用控制器的定位不是顶级运动控制。如果你的AI模型是复杂的目标检测大模型或者需要跑生成式模型那也请老老实实用带GPU的工控机。边缘AI设备强在“恰到好处”的推理而不是算力怪兽。还有一种情况必须尊重客户标准大型集团往往指定PLC品牌型号比如西门子、汇川、欧姆龙这时候DC-Pi的Codesys生态即使功能没问题也很难通过电气标准化评审。方案再合理也要先过企业标准这关。5.3 对比DC-Pi与传统“PLC工控机”方案我整理了一个比较客观的对比表维度传统PLCHMI工控机DC-Pi融合方案部署复杂度高三套系统分别安装调试低一个设备一套软件数据链路需要网关/协议转换本地数据空间直接共享实时控制能力看PLC选型下限高满足中小型设备不算顶级AI算力扩展工控机可加GPU固定适合轻量推理维护成本多套软件多套备件单一设备备份和还原简单整机功耗高明显更低上手门槛要会PLC、组态、Linux会Codesys和Python基本够5.4 我的几点体验和后续扩展实际用下来我最喜欢的一点是调试的“单点性”。以前AI和PLC联调出问题我总得判断是网络问题还是协议问题还是时序问题。DC-Pi里PLC和AI跑在同一个设备上变量直接共享出问题时基本能确定是逻辑写错还是模型判断错误排查范围小了很多。我后来在这个项目上加了一层“AI预警”逻辑单次NG不直接触发停机只记录到统计表和报警记录只有当连续3件NG时PLC才强制停机并亮红色报警灯。这样既保留了AI的预测能力也避免模型偶发误判把产线搞停。这种策略对现场操作工很友好他们能明显感受到设备“有智能”又不会被频繁误报骚扰。权限管理这块也值得提一嘴。DC-Pi的WebHMI自带用户权限分级我通常设三级操作工只能看画面和复位报警调试工程师能改参数和切手动管理员才能上传新模型和更新PLC程序。产线上有厂家远程维护需求时还能通过SSH通道更新模型文件不用专门爬到电控柜前面插U盘。最后送大家一个调试顺序的建议先跑通PLC逻辑再把AI服务的结果固定成测试值验证分支最后才挂真实模型。凡是联调阶段反复出怪问题的项目基本都是有人跳过了其中一步。AI和PLC同时打开的时候出了故障你根本分不清是模型误判还是逻辑没写对按顺序来一次就能定位到根因。