三菱FX5UJ PLC Socket TCP客户端通信配置与编程实战
2026/9/20 6:27:15 网站建设 项目流程

1. 为什么要在FX5UJ上折腾Socket通信

三菱FX5UJ这台PLC,玩过的人都知道,它自带以太网口,支持MC协议、SLMP、Socket通信这些功能。但很多人拿到手之后,翻遍手册也搞不清楚Socket通信到底怎么配置,尤其是做TCP客户端的时候,各种参数设置让人头大。我刚开始接触FX5UJ做Socket通信那会儿,也是踩了不少坑,GX Works3里那些设置项看着简单,实际连起来就是不通,排查半天发现是端口号搞错了或者连接目标IP写反了。

这篇内容就是把我自己在FX5UJ上实现Socket TCP客户端的完整过程整理出来,从基础概念到参数配置,再到实际编程和调试,全部走一遍。不管你是刚接触PLC编程的新手,还是从FX3U、Q系列转过来的老手,只要涉及到FX5UJ的以太网Socket通信,这里面的内容都能直接参考。特别是那些需要跟上位机、视觉系统、机器人控制器做TCP通信的场景,FX5UJ作为客户端主动连接对方服务器的需求非常常见。

先说清楚一个概念:Socket通信本质上就是TCP/IP协议栈上面的一层编程接口。你可以把它理解成打电话——客户端就是主动拨号的一方,服务端是接听的一方。FX5UJ做TCP客户端,就是让PLC主动去连接指定的IP地址和端口号,建立连接之后双方就可以互相发数据了。这个过程中,PLC不需要等别人来连它,而是它去找别人,这在工业现场很实用,比如PLC要把数据推给MES系统、要把结果发给视觉控制器,都是PLC做客户端更顺手。

FX5UJ的Socket通信支持TCP和UDP两种协议,TCP又分客户端和服务器两种角色。TCP客户端模式下,PLC主动发起连接请求,经过三次握手建立连接,然后就可以收发数据。这里有个关键点:FX5UJ的Socket通信是通过内置以太网口实现的,不需要额外加通信模块,但需要用到专用的Socket通信指令,比如SP.SOCOPEN、SP.SOCRCV、SP.SOCSND这些。这些指令跟普通的FROM/TO指令不一样,它们是专门为Socket通信设计的,用起来有固定的套路。

我见过很多人卡在第一步——不知道FX5UJ初始IP是多少。出厂默认是没有IP的,需要通过GX Works3或者SD卡来设置。一般来说,我们会把PLC的IP设成跟目标设备同一个网段,比如目标服务器是192.168.1.100,那PLC就设成192.168.1.10这种。子网掩码通常255.255.255.0,默认网关看情况,如果跨网段通信就需要设,同网段直连可以不设。这些参数在GX Works3的“模块参数”里面配置,具体路径是:导航窗口→参数→FX5UJCPU→模块参数→以太网端口→基本设置→IP地址设置。

还有一个容易混淆的地方:Socket通信的端口号。FX5UJ做客户端时,需要指定目标服务器的端口号,同时PLC自己也会用一个本地端口。本地端口可以固定,也可以设为0让系统自动分配。我一般建议固定本地端口,方便排查问题,比如设成5000、6000这种不常用的端口。目标端口就要看对方服务器开的是什么端口了,常见的有502(Modbus TCP)、9600、8080这些。这里要特别注意,本地端口和目标端口不能搞混,我见过有人把目标端口填成了PLC自己的端口,结果怎么都连不上。

2. FX5UJ Socket TCP客户端的核心配置拆解

2.1 以太网基本参数设置

打开GX Works3,在导航窗口找到“参数”→ “FX5UJCPU”→ “模块参数”→ “以太网端口”。这里有几个关键页面需要配置。

第一个是“基本设置”。IP地址设置里面,选择“直接设置”,然后填入PLC的IP地址、子网掩码、默认网关。比如:

  • IP地址:192.168.1.10
  • 子网掩码:255.255.255.0
  • 默认网关:192.168.1.1(同网段通信可以不填)

通信速度可以选“自动检测”,或者强制100Mbps全双工。如果现场干扰大,建议强制100M全双工,避免自动协商出问题。

第二个是“打开设置”。这里就是配置Socket通信的关键地方。FX5UJ支持最多8个连接(同时打开8个Socket),每个连接可以独立配置协议、角色、端口号等。我们做TCP客户端,就选一个连接来配置:

  • 协议:TCP
  • 打开方式:Active(主动)——这就是客户端模式
  • 本地端口号:比如6000
  • 目标IP地址:比如192.168.1.100
  • 目标端口号:比如9600

这里有个细节:目标IP地址可以填IP或者主机名,但工业现场一般直接用IP,避免DNS解析出问题。目标端口号一定要跟服务器端监听的端口一致,差一个数字都连不上。

2.2 Socket通信指令体系

FX5UJ的Socket通信指令主要有这几个:

指令功能使用场景
SP.SOCOPEN打开Socket连接建立TCP连接
SP.SOCCLOSE关闭Socket连接断开TCP连接
SP.SOCRCV接收数据从对方读取数据
SP.SOCSND发送数据向对方发送数据
SP.SOCINF获取Socket信息查询连接状态

这些指令都是带完成标志和错误标志的,编程的时候需要配合触点使用。比如SP.SOCOPEN指令,需要指定连接编号、执行方式(首次执行还是连续执行),然后等待完成标志ON。

SP.SOCOPEN的参数设置:

  • 连接编号:1~8,对应打开设置里的连接号
  • 执行方式:0=首次执行,1=连续执行
  • 完成标志:指令执行完成后置ON
  • 错误标志:执行出错时置ON

我一般用首次执行方式,用一个上升沿触发,然后等待完成标志。如果出错,错误标志ON,这时候需要查错误代码来定位问题。

2.3 数据收发缓冲区规划

Socket通信收发数据都需要缓冲区,FX5UJ用的是数据寄存器D或者文件寄存器R。发送的时候,把要发的数据放到连续的D寄存器里,然后指定起始地址和长度;接收的时候,指定接收缓冲区的起始地址和最大长度。

比如我规划:

  • 发送缓冲区:D100~D199,共100个字(200字节)
  • 接收缓冲区:D200~D299,共100个字(200字节)

发送长度和接收长度都是按字节算的,不是按字数。比如要发10个字节,长度就填10。接收的时候,SP.SOCRCV指令会返回实际接收到的字节数,放在指定的寄存器里。

这里有个坑:FX5UJ的Socket通信数据是以字节为单位传输的,但PLC内部是16位寄存器。所以发送的时候,如果数据长度是奇数,最后一个字节的高8位会被忽略或者补零。接收的时候也一样,如果收到奇数个字节,最后一个寄存器的高8位可能是无效数据。处理ASCII字符串的时候要特别注意这个问题。

3. 手把手搭建TCP客户端通信程序

3.1 连接建立与断开逻辑

先写连接建立的部分。用一个启动按钮X0触发,上升沿执行SP.SOCOPEN指令。

X0上升沿 ├─ SP.SOCOPEN 连接编号=1,执行方式=0 ├─ 完成标志M100 └─ 错误标志M101

M100 ON表示连接建立成功,M101 ON表示连接失败。连接失败的时候,需要查错误代码。错误代码放在SP.SOCOPEN指令的最后一个参数里,比如D500。

连接成功之后,就可以进行数据收发了。断开连接用SP.SOCCLOSE指令,同样指定连接编号和执行方式。

X1上升沿 ├─ SP.SOCCLOSE 连接编号=1,执行方式=0 ├─ 完成标志M110 └─ 错误标志M111

实际项目中,我一般会在PLC上电后自动尝试连接,连接失败后延时重试。重试间隔设个3~5秒,避免频繁重连把网络搞拥塞。

3.2 数据发送的完整流程

发送数据用SP.SOCSND指令。假设我要把D100开始的10个字节发出去:

M100(连接已建立)AND X2上升沿 ├─ SP.SOCSND 连接编号=1,发送起始地址=D100,发送长度=10 ├─ 完成标志M120 └─ 错误标志M121

发送完成标志M120 ON表示数据已经成功发出去了。注意,这里只是表示数据从PLC发出去了,不表示对方已经收到。TCP协议本身有确认机制,但应用层不知道对方有没有处理。

发送的数据需要提前准备好。比如要发字符串“HELLO”,就把ASCII码放到D100、D101、D102:

  • D100 = 0x4845('H'和'E')
  • D101 = 0x4C4C('L'和'L')
  • D102 = 0x4F00('O'和填充)

或者用$MOV指令直接写字符串,FX5UJ支持字符串常量。

3.3 数据接收与超时处理

接收数据用SP.SOCRCV指令。这个指令有点特殊,它是非等待的,执行后立即返回,如果有数据就接收,没有数据就等下次扫描。

M100(连接已建立)AND M200(接收使能) ├─ SP.SOCRCV 连接编号=1,接收起始地址=D200,最大长度=100 ├─ 完成标志M130 └─ 错误标志M131

接收完成标志M130 ON表示收到了数据,实际接收长度放在指定的寄存器里,比如D300。然后根据D300的值来处理接收到的数据。

这里有个关键点:SP.SOCRCV指令需要在每次扫描都执行,或者用连续执行方式。如果只用上升沿触发一次,可能错过后续的数据。我一般用一个常ON触点来驱动,或者用定时器周期性触发。

接收超时怎么处理?FX5UJ本身没有内置接收超时功能,需要自己用定时器做。比如启动接收后,如果500ms内没有收到数据,就认为超时,做相应处理。这个逻辑用定时器T0来实现:

M100 AND NOT M130 ├─ T0 K50(5秒定时器) └─ T0 ON时,置位超时标志M140

3.4 完整通信状态机设计

实际项目中,Socket通信不能只是简单的发和收,需要有一个状态机来管理整个通信过程。我一般设计这几个状态:

状态说明转移条件
0初始状态上电或复位
1连接中执行SOCOPEN
2已连接连接成功,可收发
3发送中执行SOCSND
4接收中执行SOCRCV
5错误处理出错后重试或报警

状态机用D寄存器或者M寄存器来存当前状态,然后根据状态和事件来转移。这种写法比一堆触点和线圈清晰得多,后期维护也方便。

4. 调试过程中那些让人抓狂的问题

4.1 连接不上怎么办

连接不上是最常见的问题。排查顺序我一般是这样:

  1. 先ping一下目标IP,看网络通不通。如果ping不通,检查网线、交换机、IP设置。
  2. 用电脑上的网络调试工具(比如TCP测试工具)模拟服务器,看PLC能不能连上。如果能连上,说明PLC配置没问题,问题在目标服务器。
  3. 检查端口号。目标端口号是不是服务器实际监听的端口?本地端口号有没有被占用?
  4. 检查防火墙。目标服务器或者中间网络设备有没有拦截这个端口?
  5. 看错误代码。SP.SOCOPEN的错误代码会告诉你具体原因,比如超时、拒绝连接、网络不可达等。

常见错误代码:

错误代码含义处理方式
0x0000正常-
0x0001连接超时检查网络和目标设备
0x0002连接被拒绝目标端口未监听
0x0003网络不可达检查IP和路由
0x0004连接已存在先关闭再打开

4.2 数据收发异常排查

数据发出去了但对方没收到,或者收到的是乱码,这种问题也很常见。

先确认发送长度对不对。长度是按字节算的,不是字数。比如发“ABCD”4个字符,长度填4,不是2。

再确认字节序。FX5UJ的寄存器是低字节在前还是高字节在前?发送的时候,D100的低8位先发还是高8位先发?这个跟对方服务器的解析方式有关。如果对方是按大端序解析,而PLC发的是小端序,就会乱码。解决办法是在PLC端做字节交换,或者跟对方约定好字节序。

接收的时候也一样。如果收到的数据长度是奇数,最后一个字节可能有问题。我一般会在接收缓冲区后面多留几个寄存器,避免越界。

4.3 连接断开与重连策略

TCP连接可能因为各种原因断开:网络抖动、对方服务器重启、超时等。PLC需要能检测到断开并自动重连。

检测断开的方法:SP.SOCRCV指令如果返回错误,或者SP.SOCINF查询到连接状态不是已连接,就认为断开了。然后关闭连接,延时后重新执行SP.SOCOPEN。

重连策略我一般这样设计:

  • 首次重连延时1秒
  • 第二次重连延时3秒
  • 第三次重连延时5秒
  • 之后每次重连延时10秒

避免频繁重连把网络搞崩。同时记录重连次数,超过一定次数(比如10次)就报警,提示人工检查。

4.4 性能优化与注意事项

FX5UJ的Socket通信性能跟扫描周期有关。SP.SOCRCV和SP.SOCSND指令的执行需要时间,如果扫描周期太短,可能指令还没执行完就进入下一次扫描了。我一般会把Socket通信相关的程序放在扫描周期的后半段,或者用定时器中断来执行。

发送数据不要太频繁。TCP协议本身有开销,每次发送都有包头包尾。如果数据量小但发送频率高,网络效率很低。我一般会做数据缓冲,攒够一定长度或者间隔一定时间再发。

接收缓冲区要足够大。如果对方发得快,PLC接收不及时,数据可能会丢失。FX5UJ的Socket接收缓冲区大小有限,具体看手册。如果数据量大,建议用文件寄存器R来存接收数据。

还有一个容易忽略的点:PLC断电重启后,Socket连接会断开,需要重新建立。所以程序里要有上电自动连接的逻辑,不能只靠手动按钮触发。

5. 实际项目中的经验总结

5.1 与上位机通信的实战案例

我之前做过一个项目,FX5UJ作为TCP客户端,连接一台工控机上的MES系统。MES系统开了一个TCP服务器,端口9600,PLC每生产一个产品就发一条数据过去,包含产品编号、检测结果、时间戳。

数据格式是ASCII字符串,用逗号分隔,比如“SN12345,OK,20240101120000”。PLC这边用$MOV指令把字符串拼好放到D寄存器,然后SP.SOCSND发出去。MES收到后解析入库。

这个项目里遇到一个问题:MES服务器有时候会重启,PLC检测到连接断开后需要自动重连。我用了前面说的重连策略,效果不错。另外,MES服务器对数据格式要求很严格,多一个空格都会解析失败。所以PLC发送之前一定要确认数据格式完全正确。

5.2 与视觉系统通信的注意事项

另一个项目是FX5UJ连接视觉控制器。视觉控制器作为TCP服务器,PLC作为客户端。PLC触发拍照后,视觉控制器返回检测结果,比如“OK”或“NG”。

这个场景下,实时性要求比较高。PLC发触发信号后,要在100ms内收到结果。我用了SP.SOCRCV的连续执行方式,配合定时器做超时检测。如果超时没收到结果,就认为视觉系统故障,报警停机。

这里有个细节:视觉控制器返回的数据可能分多次到达。比如先发“O”,再发“K”。PLC需要能处理这种分包情况。我的做法是接收缓冲区不清零,每次收到数据就追加,直到收到结束符(比如换行符)才认为一帧数据完整。

5.3 多连接并发处理

FX5UJ支持最多8个Socket连接同时打开。如果需要同时跟多个设备通信,可以配置多个连接。比如连接1跟MES通信,连接2跟视觉控制器通信,连接3跟机器人控制器通信。

每个连接独立配置、独立编程。但要注意,所有连接共享同一个以太网口,带宽是有限的。如果数据量大,需要考虑网络负载。我一般会把实时性要求高的连接设成高优先级,数据量大的连接做流量控制。

多连接编程的时候,指令的连接编号一定要对应好。我见过有人把连接1的发送指令写成了连接2的编号,结果数据发到错误的设备上去了。这种错误很隐蔽,调试的时候要特别小心。

5.4 常见问题速查表

现象可能原因排查方法
连接超时IP或端口错误ping测试,检查配置
连接被拒绝目标端口未监听用电脑测试目标端口
发送成功但对方没收到字节序或格式问题抓包分析,检查数据格式
接收乱码字节序不匹配做字节交换测试
频繁断连网络不稳定或对方重启检查网络质量,看重连日志
扫描周期变长Socket指令耗时优化程序结构,用中断
数据丢失接收缓冲区太小增大缓冲区,降低发送频率

5.5 编程习惯与代码规范

最后说几个编程习惯上的建议。Socket通信程序一定要加注释,每个指令的作用、参数含义、完成标志和错误标志的地址都要写清楚。不然过几个月自己都看不懂。

错误处理要完善。每个Socket指令都要有错误标志判断,出错后要有相应的处理逻辑,不能不管。我一般会把错误代码存到连续的寄存器里,方便后期排查。

程序结构要清晰。连接管理、数据发送、数据接收、错误处理分开写,用不同的程序块或者FB。这样后期修改的时候不会牵一发而动全身。

还有,调试的时候善用GX Works3的监控功能。可以实时看Socket指令的执行状态、完成标志、错误代码,比猜要快得多。网络调试工具也是必备的,Wireshark抓包能看到底层的数据流,定位问题很有效。

我在实际项目中最大的体会是:Socket通信本身不复杂,复杂的是各种边界情况和异常处理。把异常处理做好了,程序就稳了。另外,跟对方设备的开发者保持沟通很重要,数据格式、通信协议、超时时间这些都要提前约定好,不然联调的时候会浪费很多时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询