1. 项目背景与挑战:当视觉系统需要“开口说话”
在工厂的自动化产线上,视觉检测是常见的环节。康耐视的智能相机(Insight系列)就像产线上的“火眼金睛”,能快速识别产品缺陷、读取条码。但很多时候,光“看见”还不够,它还得把“看到”的结果准确地“告诉”产线的大脑——PLC(可编程逻辑控制器)。比如,相机检测到一个产品的序列号是“ABC123”,它需要把这个字符串信息传递给倍福(BECKHOFF)PLC,PLC才能根据这个信息指挥机械手分拣、记录数据或者触发后续流程。
这个“告诉”的过程,就是通信。听起来简单,不就是传个字符串嘛?但实际操作起来,你会发现这中间隔着一道“语言不通”的鸿沟。康耐视相机和倍福PLC是两家不同公司的产品,它们的通信协议、数据格式、处理逻辑都可能不一样。Modbus TCP协议虽然是个通用的“普通话”,但具体到如何用这门“普通话”准确无误地传递一个字符串,尤其是从相机(客户端)主动写到PLC(服务器)的保持寄存器里,里面全是细节和“坑”。
我接手这个项目时,就遇到了这个典型的异构设备集成难题。相机固件版本较老,没有现成的Modbus TCP客户端功能块,这意味着不能像用高级语言库那样简单调用一个WriteString()函数。一切都需要从最底层的协议帧开始,手动构造每一个字节的数据包。这就像你要发电报,不能直接说“你好”,而必须把每个字的电报码查出来,再按照严格的格式排列好,才能发送。这个过程虽然繁琐,但一旦打通,你对工业通信的理解会深刻很多。这篇文章,我就把自己从零开始,实现康耐视相机向倍福PLC发送字符串的完整过程、踩过的坑以及最终的解决方案,毫无保留地分享给你。
2. 核心原理拆解:Modbus TCP与字符串的“编码游戏”
在动手写代码之前,我们必须把Modbus TCP协议和字符串处理的几个核心原理吃透。这就像盖房子前先看懂图纸,能避免后面返工。
2.1 Modbus TCP协议帧:你的数据“信封”
Modbus TCP协议可以看作是在标准的TCP/IP协议之上,包裹了一层简单的应用层协议。它定义了一个固定的“信封”格式来装载你的数据。这个信封叫做MBAP报文头(Modbus Application Protocol header),加上后面的协议数据单元(PDU),就构成了一个完整的请求帧。
对于一个“写多个保持寄存器”(功能码0x10)的请求,帧结构是这样的:
[ 事务标识符 (2字节) ] [ 协议标识符 (2字节) ] [ 长度 (2字节) ] [ 单元标识符 (1字节) ] [ 功能码 (1字节) ] [ 起始地址 (2字节) ] [ 寄存器数量 (2字节) ] [ 字节计数 (1字节) ] [ 寄存器值 (N x 2字节) ]
对我们来说,关键字段是:
- 单元标识符:可以理解为从站地址(Slave ID)。在TCP模式下,这个字段常被忽略或设为任意值(如0或1),倍福PLC通常也能接受。
- 功能码:0x10,代表“写多个保持寄存器”。
- 起始地址:你要从PLC的哪个寄存器开始写。这里有个大坑:Modbus协议中的地址通常是基于0的,但不同设备厂商的映射方式不同。对于倍福PLC使用TF6250模块,保持寄存器默认映射到输出映像区(Outputs),其地址偏移是12288(0x3000)。这意味着,如果你想写PLC的%MB0开始的区域,在Modbus报文里,起始地址要填0x3000。
- 寄存器数量:你要写多少个16位的寄存器。
- 字节计数:后面“寄存器值”部分的总字节数,等于
寄存器数量 * 2。 - 寄存器值:这才是我们真正要发送的数据内容,每个寄存器2个字节。
2.2 字符串到字节流:当字符遇上寄存器
我们的目标是发送一个字符串,比如"OK"。字符串在内存中是以ASCII码(或Unicode)的字节序列存储的。"OK"的ASCII码是0x4F, 0x4B。
问题来了:Modbus的保持寄存器是16位(2字节)宽的。我们不能直接发送0x4F, 0x4B这两个字节就完事。我们必须确保发送的总字节数是偶数,因为寄存器数量必须是整数。如果字符串长度是奇数(比如"ABC",字节为0x41, 0x42, 0x43),我们就需要补一个字节(通常是0x00,即空字符)来凑成偶数。
更复杂的是字节序(Endianness),也就是大名鼎鼎的“大小端”问题。在网络上传输多字节数据时,需要约定字节的顺序。Modbus协议规定使用大端序(Big-Endian),即高位字节在前,低位字节在后。对于一个16位的寄存器值,比如0x1234,在数据流中应该是0x12(高字节)在前,0x34(低字节)在后。
但这里有一个极易混淆的点:我们发送的是字节流。当我们把两个字符'A'(0x41)和'B'(0x42)放入一个寄存器时,这个寄存器的值应该是0x4142。按大端序在网络上传输,字节流应该是[0x41, 0x42]。然而,在康耐视相机的某些数据处理函数中,如果你不特别指定,它可能会按照小端序来处理字符串到二进制数据的转换,即它认为0x4142这个值应该输出为[0x42, 0x41]。这就导致了数据在PLC端解析时出现错位。
2.3 倍福PLC的内存映射:数据最终“安家”在哪
在倍福PLC这边,我们通过TF6250模块将Modbus的保持寄存器映射到PLC的某个内存区域。通常,我们映射到%MB区(字节内存)。例如,我们将起始地址0x3000映射到%MB0。
当相机发送来[0x41, 0x42, 0x43, 0x44]这四个字节(对应字符串"ABCD"),PLC会将其依次存入%MB0, %MB1, %MB2, %MB3。如果你在PLC里定义了一个STRING类型的变量指向%MB0,它就能正确显示出"ABCD"。
但是,由于前面提到的大小端问题,如果相机发送的字节顺序是错的,比如发成了[0x42, 0x41, 0x44, 0x43],那么PLC内存中%MB0=0x42, %MB1=0x41...,显示出来的字符串就成了"BADC",每两个字符都交换了位置。这就是我们后面要解决的核心难题。
3. 实战第一步:配置倍福PLC作为Modbus TCP服务器
让PLC作为服务器“等待”连接,配置起来相对简单。这就像在家里安装一个信箱,并告诉邮差信箱的地址和取信规则。
3.1 安装必要的软件包
首先,你需要在安装了TwinCAT 3的工程电脑上,安装TF6250- Modbus TCP软件包。这个包是倍福官方提供的Modbus TCP服务器/客户端功能组件。
- 访问倍福官网的下载中心,搜索“TF6250”。
- 使用你的倍福账号登录(没有的话需要注册一个,密码要求比较复杂)。
- 下载对应你TwinCAT 3版本的TF6250安装包。
- 运行安装程序,按照提示完成安装。安装完成后,在Visual Studio的TwinCAT PLC编程环境中,你就能在“库管理器”里看到相关的库文件了。
3.2 创建PLC项目并配置Modbus服务器
接下来,在TwinCAT开发环境中进行配置:
- 创建PLC项目:在你的TwinCAT解决方案中,添加一个新的Standard PLC Project。
- 添加库引用:在PLC项目的“References”里,添加
Tc2_ModbusSrv库。这个库就是TF6250安装后提供的。 - 编写PLC程序:在
MAIN程序(或你自定义的程序块)中

与倍福PLC的ModbusTCP字符串通信实战解析&spm=1001.2101.3001.5002&articleId=149927422&d=1&t=3&u=687b69062f744a05926e6ceee6574c76)
388

被折叠的 条评论
为什么被折叠?



