
做机器视觉项目最绕不开的一步就是把相机、视觉控制器和PLC之间的数据打通。我最近在一个汽车零部件检测现场调试海康威视视觉控制器MV-VB2100-120G手头要同时对接西门子S7-1200和产线上一台老设备折腾了一圈之后海康视觉通讯配置里最核心、最通用的方案就是TCP加Modbus。这篇文章就把我在配置过程中对TCP与Modbus协议的选型判断、报文结构、实操步骤和踩坑记录完整整理一遍尤其适合正在做视觉对接产线、又对通信协议半懂不懂的自动化工程师。文本里不会只讲“怎么点按钮”更多会聊“为什么这么配”以及哪些地方容易把人坑到怀疑人生。如果你已经入手了海康的视觉控制器、工业相机或者只是想在VMVisionMaster里把结果发给PLC这篇内容应该能帮你少走不少弯路。1. 项目背景与通讯方案选型1.1 这套配置要解决什么实际问题视觉系统在产线里的角色说白了就是一台“会看质量的眼睛”。它判断完一个产品是OK还是NG得把结果告诉PLCPLC再决定让气缸把它推到合格品道还是不良品道。如果视觉判断完了却传不出去整条线就是瞎的。我这次用的海康威视视觉控制器MV-VB2100-120G配套的软件平台是VisionMaster。它本身有几个网口既可以接工业相机采集图像也要预留一个网口和PLC通讯。现场的情况是控制器和PLC在同一个电柜里距离不超过三米环境干扰不大没有交换机也能直接网线对接。但产线改造时总会遇到各种品牌混用比如三菱、西门子、欧姆龙甚至国产PLC都有这种情况下用一个通用协议比绑死某个厂家的专用协议要省心得多。而这套方案的最终目标是视觉检测完成之后把结果写入PLC的指定寄存器或线圈PLC通过轮询或中断方式获取数据完成后续分拣动作。整个过程要稳定不能丢数据也不能因为断线导致整条产线停机。1.2 为什么是TCP和Modbus而不是其他方案先说TCP。它是传输层协议几乎所有的控制器、PLC、工控机都支持。海康视觉控制器本身跑的是Windows或嵌入式系统用TCP Socket是最简单、最不容易出兼容性问题的方式。相比串口TCP不需要关心波特率、数据位、停止位这些参数网络通就行。再说Modbus。Modbus是应用层协议它最大的优势是“老”老到几乎所有PLC都原生支持。西门子有Modbus TCP库三菱有内置功能欧姆龙有专门模块更不要说像永宏、台达、汇川这些国产PLC了。所以只要PLC端开一个Modbus TCP服务视觉控制器这边就能用通用协议把结果写过去不需要为某一款PLC单独开发驱动。热词里有人提到“发那科和小原siv32走PROFINET配置通讯”这属于另一个场景。PROFINET在汽车焊装线上确实常见但它的配置复杂度和授权成本比Modbus高而且不同厂家的GSD文件版本经常对不上。如果现场没有明确指定实时总线要求我通常不会一上来就推荐PROFINET。Modbus TCP跑在普通以太网上100米以内网线随便拉性价比非常高。1.3 什么时候不要用ModbusModbus不是万能的它有两个明显短板。第一它没有主动上报机制PLC必须要轮询才能拿到数据。如果你的视觉结果需要在几毫秒内触发设备动作那Modbus的响应时间可能不够这时候应该考虑TCP直接推送或者硬I/O。第二Modbus的数据类型比较简单传一个布尔值或者16位整数很轻松但传浮动点数、字符串、数组就要做字节拼接两边约定不好就会读出一堆莫名其妙的数字。我遇到过有人非要用Modbus传图像坐标数组结果一个结果要拆成二三十个寄存器通信效率和调试成本都很高。这种情况下我更建议用TCP直接传JSON或自定义二进制报文解析起来反而方便。选型这件事不是越高级越好而是和业务匹配才合适。2. 从原理角度拆解TCP与Modbus2.1 TCP长连接与短连接为什么视觉系统偏爱长连接很多第一次做通讯的人会问TCP连接怎么还分长短我每次都要解释一遍短连接就是每发一次数据建立连接、发送、断开循环往复。长连接就是建立一次连接之后一直保持反复收发数据直到设备停机或连接异常断开。视觉检测的特点是高频次、小数据量。产线上每秒可能检测两三个产品如果每个产品都重新经历一次TCP三次握手和四次挥手时间成本太高而且频繁创建和销毁连接还会导致端口处于TIME_WAIT状态短时间内建立不了新连接。我在现场就见过因为用短连接导致设备运行几小时后就报“无法连接服务器”的情况。所以海康视觉控制器和PLC通信几乎都是用TCP长连接。具体到配置上就是客户端和服务端只建立一次Socket之后一直保持。图像检测程序在循环里反复向同一条连接写入结果PLC端只管监听读取不需要检查连接状态是否每次都是ESTABLISHED。长连接也有代价就是必须处理“假死”问题。网络线松了、交换机重启、对端程序崩溃连接不一定能立刻感知。所以我在TCP方案里一定会加心跳机制比如每500毫秒发一个心跳字节超过3秒没收到回应就判定连接断开主动重连。心跳的间隔要结合PLC扫描周期来设定太频繁会占用带宽太慢又会延迟故障发现。2.2 TCP三次握手与断线重连机制TCP三次握手是建立可靠连接的基础。客户端先发SYN服务端回SYNACK客户端再回ACK这样两边都确认了对方的收发能力。我在培训新人的时候喜欢打一个比方这就像两个人打电话先问一句“你听得见吗”对方说“听得见你说什么”这边再回一句“我也听得见开始吧”。看似多余但这套流程确保了双方都在线、都能收发。四次挥手是断开连接的过程重点是要让双方都确认数据发完了。但实际的工程现场经常不是正常挥手而是异常断开。比如直接拔网线、PLC断电、控制器进程被杀这些情况下TCP层根本来不及挥手。所以断线重连机制很重要。海康视觉控制器作为服务端或客户端都可以设置重连参数关键是重连间隔和重连次数要设合理。我习惯把重连间隔设在1到3秒之间太短会把日志刷爆太长会影响产线恢复速度。曾经有个现场把重连间隔设成了10秒操作工就觉得设备响应太慢实际不是程序问题是重连策略太保守了。这里也顺便回答一下热词里“tcp和udp的区别”。UDP不保证送达不保证顺序虽然速度快但在视觉检测这种不允许丢数据的场景我一般不推荐直接裸用。如果你对实时性有极高要求可以考虑UDP加应用层确认但那实现复杂度就上去了。2.3 Modbus协议结构与功能码Modbus的报文结构并不复杂关键是理解它的数据模型。它把数据分成四类线圈、离散输入、输入寄存器、保持寄存器。其中线圈和离散输入都是位数据寄存器是16位数据。具体说明我用一张表整理出来Modbus数据模型地址范围读写属性典型用途线圈Coil000001-065536可读可写控制输出信号、写视觉判定布尔结果离散输入Discrete Input100001-165536只读读取传感器状态输入寄存器Input Register300001-365536只读读取模拟量输入保持寄存器Holding Register400001-465536可读可写读写视觉检测数据、坐标、参数实际使用中我最常用的是保持寄存器因为视觉结果、坐标值、判定码都可以写进保持寄存器PLC随时可以读走。偶尔也用线圈来写OK/NG标志位因为布尔值在PLC里占一个位逻辑处理起来比整数更直接。功能码方面常用的是这么几个01读线圈、02读离散输入、03读保持寄存器、04读输入寄存器、05写单线圈、06写单寄存器、15写多线圈、16写多寄存器。视觉系统作为Modbus从站时PLC会发03、04来读视觉系统作为主站主动写PLC时会用06或16。这里要特别提醒05和06是“写单”操作一次只能写一个地址如果你要写一串数据尽量用15和16不但效率高还能保证数据一致性。2.4 Modbus TCP与Modbus RTU差异及网关应用Modbus RTU走串口Modbus TCP走以太网。两者报文结构上RTU有CRC校验每包数据还要带设备地址TCP则是在标准Modbus报文前面加了一个MBAP报文头长度固定为7个字节然后就不需要CRC了因为TCP/IP层已经帮你做了可靠传输。MBAP头具体内容是事务处理标识符2字节、协议标识符2字节固定为0、长度2字节、单元标识符1字节。很多人第一次抓包看Modbus TCP报文会懵看到前面一长串数字不知道是什么。我举个例子读PLC保持寄存器起始地址0、数量10的请求报文是00 01 00 00 00 06 01 03 00 00 00 0A拆开看就是事务ID0x0001协议ID0x0000长度0x0006从单元标识符开始到结束共6个字节单元ID0x01功能码0x03起始地址0x0000寄存器数量0x000A。如果现场有设备只支持RTU又想在以太网里走Modbus TCP就需要一个网关。网关的工作就是把TCP报文里的MBAP头剥掉补上CRC校验后转成RTU发到串口反过来也一样。我用的某品牌网关配置起来很简单设置好串口波特率和从站地址就行但一定要注意波特率匹配见过好几个人现场就是卡在9600和19200不一致上。3. 海康视觉控制器通讯配置实操3.1 硬件准备与网络拓扑先说硬件MV-VB2100-120G这台视觉控制器我用下来的感觉是配置不算顶配但足够稳定。它前面板上有独立网口一般建议用一个网口接工业相机另一个网口接PLC或上层交换机两个网段分开避免图像数据流和通讯数据流互相干扰。网络拓扑上最简方案是视觉控制器和PLC直接网线对接两端配同网段IP。复杂一点的是都接到产线交换机上再通过交换机互联。直接对接的优点是延迟最低、故障点少缺点是不方便多台设备同时访问视觉控制器。我建议在做样机验证时先直连等程序稳定了再接到交换机上这样排查问题会容易不少。IP规划也很重要。我习惯在项目开工前就列一张IP表格谁是什么IP、网关是什么、子网掩码是多少全部提前规定。比如视觉控制器A网口是192.168.1.10PLC是192.168.1.20子网掩码统一255.255.255.0。不要随手写不然现场设备多了光排查IP冲突就能耗掉半天。3.2 海康视觉控制器网络参数设置拿到MV-VB2100-120G之后第一次开机进入系统先在系统设置里确认网卡状态。因为我用的控制器预装的是Windows环境下的视觉处理平台所以网卡配置和普通电脑一样在控制面板\网络连接里修改IPv4地址。这里有个细节网卡的高级设置里有一个“巨型帧”和“绿色以太网”选项。工业现场我不建议开绿色以太网节能模式否则可能会导致网口在一段时间无数据后进入休眠状态等视觉结果要发送时有延迟。巨型帧如果交换机不支持也会导致大包被丢弃所以稳妥起见关闭或保持默认。配完IP用命令行ping一下对端PLC的IP确认网络通。ping不通就先查网线、查IP、查防火墙不要急着去配置软件。在调试阶段我建议关闭Windows防火墙或者至少把Modbus TCP使用的502端口和自建TCP服务使用的端口加入允许列表不然程序会莫名其妙发不出数据。3.3 VisionMaster中启用Modbus TCP从站海康的VisionMaster里面有一个“通信配置”模块在流程编辑里把通信配置拉进来然后双击打开配置界面。先把使能开关打开通信类型选择Modbus TCP Server从站。这里要解释一下视觉控制器此时作为从站PLC主动来读数据。用从站模式的好处是不需要PLC端配置太多只用监控对应寄存器就够了。坏处是PLC必须按周期轮询数据实时性取决于PLC的刷新速度。协议参数按照上面讲的报文结构来填本地端口默认为502单元标识符默认1。如果你的PLC侧用了多台Modbus设备单元标识符用来区分不同从站但多数情况下只有一台视觉控制器保持1就行。接下来最关键的是建立寄存器映射表。VisionMaster的通信配置里允许用户自定义地址和数据的对应关系。比如我把检测结果写入保持寄存器地址0把坐标X写入地址1坐标Y写入地址2。这样PLC去读40001、40002、40003就能拿到对应数据。那边PLC工程师需要知道的地址我通常直接从40001开始给他们描述但编程时要注意PLC指令内部地址有的是从0开始算。就是说模块里的地址0对应Modbus协议里的40001也对应PLC数据块里的某些偏移量有时候会因为“0”还是“1”的差异导致数据对不上这个后面专门讲。3.4 用TCP Socket自定义协议和PLC侧对接如果PLC不支持Modbus或者项目需要传输更灵活的数据结构那就走TCP Socket。海康视觉控制器在VisionMaster里可以用“逻辑脚本”或C#二次开发实现Socket通信原理上是一样的视觉结果生成后拼一个字符串或字节数组通过Socket发送给指定IP和端口。我去年做过一个项目PLC是某国产小众品牌它的以太网口不支持标准Modbus库于是我用TCP方案实现了一套自定义协议。流程是这样的视觉控制器作为TCP客户端主动连接PLC的服务器端口连接成功后每次检测完发送一条固定格式的报文比如帧头结果坐标校验尾。PLC侧写一段Socket接收程序收到报文后按协议解析并触发相应的输出。这样做的好处是PLC不用轮询视觉结果到了就主动推送实时性好。但风险也很明显所有通信逻辑都要自己写包括心跳、超时处理、粘包拆包。我建议如果真的选择TCP自定义协议务必先在电脑上用网络调试助手模拟两端把报文格式调到完全一致再上产线不然后期调试非常痛苦。这里也顺带提到一个热词“Cap或C#的集成如果你在VisionMaster里用C#脚本写Socket记得在项目程序退出时主动关闭连接并释放资源否则下次启动会报端口占用。3.5 用Modbus Poll和Modbus Slave搭建仿真联调环境在没有PLC在场的情况下怎么验证视觉控制器的Modbus配置对不对我的做法是用Modbus Poll和Modbus Slave这两个工具。Modbus Poll模拟主站Modbus Slave模拟从站是Modbus调试中必不可少的工具。调试流程分两种情况。如果视觉控制器是Modbus从站那我在电脑上运行Modbus Poll作为主站去连接视觉控制器的IP和端口。界面里填好从站IP、端口502、从站地址1选择功能码03读保持寄存器然后点击连接基本就能看到寄存器里的实时数值。视觉检测触发后数值会变化就说明从站这边写数据成功了。如果视觉控制器是Modbus主站主动去写PLC那我就在电脑上开Modbus Slave模拟一个从站配置好端口502把地址映射填好然后看视觉控制器发过来的数据能不能显示在Slave的界面里。两边能对上说明主从关系和数据地址都正确。有一点必须说明Modbus Poll和Modbus Slave是收费软件免费版有功能限制。网上很多帖子在问“Modbus Poll密钥”或者“Modbus Slave密钥”这里我不能提供破解方法建议去官网购买授权。如果只是临时调试免费试用版够用了没必要为了省几百块钱去冒安全风险。4. 实际联调中的问题排查与避坑4.1 PLC读不到视觉控制器数据的排查思路这个问题出现的频率最高几乎每一个Modbus联调项目都会遇到。PLC读数据读到超时或读到全0值别第一时间怀疑程序写错了按下面顺序排查。先ping IP确认网络通。然后看PLC组态里的从站IP端口对不对很多PLC的Modbus TCP默认端口不是502尤其是一些国产PLC它把端口设置成了自定义值两边必须保持一致。再看单元标识符即从站地址有的PLC固定填255但视觉控制器这边配置的单元ID是1这时候用Modbus Poll试一下不填地址或者填255能不能通。最后检查寄存器地址换算。PLC里读40001指令里写的地址可能要从0开始那么40001对应的实际偏移就是040002对应1。如果你不小心把地址写成了40001而协议栈里又自动加了1那实际访问的就是40002也就是寄存器偏移量1的值自然读不到你写的数据。这个问题在项目交接时特别常见我一般会在文档里标注清楚“所有地址均按0起始偏移PLC侧请自行加40001”。4.2 TCP连接失败的几个原因端口占用与防火墙TCP连接失败的时候先看报错。如果你在程序日志里看到类似“error: listen tcp 127.0.0.1:11434: bind: only one usage of each socket address”或者“failed to listen tcp on 108”的提示几乎可以确定是端口被占用了。Windows下用命令netstat -ano | findstr 502可以看到哪个进程占用了502端口然后去任务管理器把对应进程结束或者换一个端口。正常情况下Modbus TCP服务端口就是502但很多我们自己的TCP程序会用一个自定义端口这时要确认端口没有和其他软件冲突。再一个常见问题是防火墙拦截。Windows默认防火墙对入站连接是拦截的你本机作为服务端时外部PLC怎么都连不上但你在本机用回环地址连却没问题。遇到这种情况直接把TCP端口加入防火墙入站规则或者临时把防火墙关掉验证等确认是防火墙问题时再细化规则。4.3 数据大小端不对导致的“倒序”问题这是调试中最隐蔽的坑。PLC和视觉控制器中多字节数据存储存在大小端差异。比如整数12345十六进制0x3039发送时按字节序可能是30 39也可能收到的是39 30。Modbus协议本身没有规定大小端全靠通信双方约定所以经常出现PLC读到的数值翻了几十倍、甚至变成负数的情况。解决方法是两边统一大小端设置。多数PLC软件里可以配置字内字节顺序比如西门子S7-1200的Modbus TCP指令里就有一个“ByteOrder”参数选Big Endian或Little Endian。海康视觉控制器侧如果能把返回数据配置为高位在前通常对西门子、三菱这类大端PLC更友好。遇到这类问题时不要猜我一般直接用Modbus Poll写一个已知数值然后抓包或者看PLC侧的原始字一眼就能判断是不是字节序颠倒了。4.4 数据刷新慢和超时设置Modbus TCP是轮询机制PLC扫描周期和通信超时时间决定了数据刷新速度。如果PLC扫描周期是10毫秒但通信诊断周期设置成了1000毫秒那会影响故障响应速度。如果你在视觉检测的PLC程序里用“重读几次才算数”的方式判断结果那也是人为增加了延迟。我习惯的调法是PLC侧的通信超时设在200毫秒到500毫秒之间扫描周期尽量不超过50毫秒这样一般产线都够用。如果视觉检测节拍非常快比如每分钟120件也就是500毫秒一件那这个速度足够应付了。如果确实要更低延迟就得减少轮询的寄存器数量或者改用TCP推送。另外PLC里的Modbus通信指令一般都会有一个“执行完成后翻转完成位”的逻辑比如你用西门子的MB_CLIENT每次调用后读取状态字。很多新手不检查完成位就继续发下一条指令这会导致通信队列堵塞数据越刷新越慢。4.5 工业现场稳定性的几个额外建议在现场待久了你就会发现协议配置本身只占20%的工作量剩下80%都在处理各种莫名其妙的问题。我总结几个稳定性方面的建议。第一网线一定要用工业级带屏蔽的至少是超五类以上。普通办公网线在电柜里靠近变频器时信号会被干扰虽然TCP本身有重传机制但重传次数多了会增大延迟。我亲眼见过一根网线在电柜里走线距离长导致视觉结果发送成功率只有70%换了一根屏蔽网线后故障消失。第二如果在视觉控制器和PLC之间经过工业交换机确保交换机端口是千兆并且关闭不必要的网络管理功能比如STP生成树协议。STP在网络成环时会自动阻塞端口但在简单链式拓扑里有时会导致端口在链路变更后几秒内不可用。第三上位机和视觉控制器不要混用同一个网卡。MV-VB2100-120G这种控制器一般有多个网口一个用来接相机局域网一个用来接产线控制网两个网段的IP绝对不要乱填否则路由表混乱后视觉控制器可能连相机都找不到了。4.6 现场试运行时的日志记录习惯最后再多说一句不要等设备出了问题才去翻日志。我在每一个视觉通讯项目里都会要求保留日志功能每次连接成功、断开、重连每次发送结果包每次收到异常响应都要记录时间和关键数据。日志文件建议按天切割保留至少30天。有一次产线凌晨停机操作工说视觉控制器偶尔不发结果。等我第二天到现场日志显示凌晨3点17分开始每15秒就重连一次仔细看发现是PLC在某时段会主动断开TCP连接。如果没有日志这个问题根本无从查起。所以在调试阶段把日志做得越详细后期维护越省心。5. 最后的几点实操心得上面这些写出来看着挺长但实际做起来就是一个不断验证的过程。我个人的体感是新手拿到海康视觉控制器和PLC通信的任务时永远先从小处做先配通网络、再建立最简单的Modbus读写、再往里填业务逻辑。不要一上来就想着把所有检测数据都通过通信传出去那只会让你同时面对图像算法和通信两层报错根本分不清是哪里出了问题。另外想分享一个沟通层面的经验和PLC工程师对点表时一定要用纸笔把寄存器映射表写清楚谁来填、谁来读、数据类型是什么、字节序是大端还是小端、刷新频率多少每一条都确认签字。很多现场扯皮都是因为口头沟通完两边对“地址是从0还是1开始”的理解完全不一样。最后再留一个小技巧Modbus调试时如果你手头没有现成的PLC可以先用一个通用Modbus调试软件在电脑上做仿真。先把视觉控制器的配置调通再和PLC对接。这样一旦出现问题你能迅速判断是视觉侧的问题还是PLC侧的问题不用在两台设备之间来回折腾。做工业通讯最值钱的其实不是协议本身而是把出问题的范围快速缩小、快速定位的能力。