开场
这次我们来看一个欧姆龙 NJ/NX 系列 PLC 的实用通信案例:NJ501 如何通过无协议串口通信(RS-232C / RS-422A / RS-485)向第三方设备发送数据。
很多做项目集成的人会遇到一个情况:PLC 要对接的不是同品牌的运动控制器或伺服,而是一台扫码枪。如果扫码枪处在自动触发模式,那事情就简单,PLC 只管收;但如果扫码枪是被动触发,需要 PLC 先发一个“读码指令”它才出数据,问题就来了。这种场景没法用欧姆龙内置的 "串行通信" 功能块直接映射,很多人会去想写一个自定义协议,但在 NJ 里没有现成的串口自由协议指令,标准库也不提供无协议发送功能块,于是这条路就被卡住了。
这个案例的完整解决方案是:利用 NJ501 自带的物理串口,通过编写一个底层字节发送功能块,实现任意无协议数据帧的发送能力,并用它完成对扫码枪的数据触发。
先给出这个方案的核心判断:
- 硬件:NJ501 系列 CPU 自带的 RS-232C 口,或 NJ501 搭配 CJ1W-SCU 系列串行通信单元扩展出的串口。
- 软件:Sysmac Studio,功能块语言可以用 ST(结构化文本),项目类型选 NJ/NX 运动控制项目。
- 技术关键:用 Sysmac Studio 里的
SysmacBus底层通讯函数,配合特殊的功能块写法,直接向串口写一字节一字节发送。 - 难度:中等偏上。难点不在 ST 语法,而在于理解 NJ 系统服务里的串口分配方式,没有现成的可复制功能块会让人绕很久。
- 最终能力:PLC 可以按需要向串口设备发送自定义指令,比如
0x02、0x31、0x03这样的帧,也可以发送 ASCII 字符串"READ",从而触发扫码枪或其它仪表工作。
顺带说明,这个案例同样适用于 NX1P2、NX7 等支持 Sysmac Studio 串口功能的 CPU。NX1P2 本体也带串口,NJ501 本体带一个 RS-232C 口。如果是 NJ301、NJ101 这类没有本体串口的型号,就需要通过扩展 CJ 系列串行通信单元来实现,原理一致,只是物理端口位置不同。
下面直接从背景、硬件选型、Sysmac Studio 配置、功能块设计、实际测试到注意事项,完整拆解一遍。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目名称 | 欧姆龙 NJ501 无协议串口通信发送功能 |
| 涉及 CPU 型号 | NJ501 系列(也适用于 NJ/NX 系列支持串口的型号) |
| 通信方式 | 无协议 RS-232C / RS-422A / RS-485 |
| 主要解决的问题 | PLC 主动向扫码枪、仪表、打印机等第三方设备发送自定义数据帧 |
| 需要使用的软件 | Sysmac Studio(欧姆龙自动化软件) |
| 编程语言 | ST(结构化文本)为主,功能块设计 |
| 物理方案 | CPU 本体串口,或 CJ1W-SCU 串行通信单元扩展 |
| 是否需要第三方模块 | 不需要额外购买通信协议库,用系统自带函数实现 |
| 是否支持批量发送 | 支持,可设计成多次触发或循环定时发送 |
| 是否支持与上位机联动 | 支持,可通过 EtherNet/IP、HMI 或内部变量触发 |
| 适用场景 | 扫码枪触发、仪表指令下发、打印机控制、串口屏通信 |
| 难度评级 | 中等偏上,核心是实现底层字节发送功能块 |
从材料看,这个项目不同于欧姆龙官方标准的SerialComm指令。官方标准指令通常要求通信对象遵循 RS-232C 无协议通信的固定格式,而实际现场设备往往要自定义帧结构,这时就需要用底层方式直接写串口。
2. 适用场景与使用边界
2.1 项目到底解决什么问题
如果你只是让 NJ501 和另一台欧姆龙 PLC 通信,那没必要用无协议串口,直接用 EtherNet/IP 或 FINS 协议更稳定。真正需要无协议串口的场景,通常是 PLC 需要对接以下设备:
- 扫码枪:很多扫码枪需要 PLC 发送一条指令才开始读码。例如发送
STX、"TRG"、ETX这样的帧,扫码枪收到后触发一次扫描。 - 电子秤或仪表:仪表可能每隔一段时间需要被查询一次,PLC 要主动发送读取指令,然后等待仪表返回数据。
- 打印机:需要按预设字符串或字节流格式输出标签内容。
- 串口继电器板或 IO 模块:这类设备的指令格式往往是
0xAA 0x01 0x00 0x00 0x01,没有 PLC 标准库可直接支持,必须用自定义发送。
2.2 不适合什么场景
这个方案不建议用于以下情况:
- 高实时性运动控制总线通信:应该用 EtherCAT。
- 大量数据的连续性串口传输:无协议串口只适合短帧指令和应答式通信。
- 与电脑上位机做复杂报文交互:如果只是和 PC 通信,用 Socket 或 OPC UA 会更方便。
- 需要硬件流控和校验的复杂协议:无协议串口通信不能替代 Modbus-RTU 等成熟协议栈。
2.3 合规与安全提示
在实际项目中,如果要通过串口控制设备,务必先确认设备的通信协议和使用授权。涉及扫码枪触发、数据采集时,不应读取用户隐私数据,也不应把设备接入未经授权的系统。所有测试都应在一台独立 PLC 和串口设备上进行,避免影响正在运行的生产设备。
3. 硬件选型与环境准备
3.1 欧姆龙 NJ501 串口物理形态
NJ501 系列 CPU 的正面一般有一个标有RS232C的 D-Sub 9 针接口。这个口默认可以用来连接欧姆龙编程软件 CX-Programmer 或 Sysmac Studio 进行在线调试,同时也能在项目中被配置为无协议串口使用。
需要注意的是:如果该串口被 Sysmac Studio 占用为编程口,那么无协议通信就无法同时使用。实际项目中,通常使用以太网端口进行编程调试,释放本体串口给通信使用。如果 CJ1W-SCU 串行通信单元扩展口也用上了,在 Sysmac Studio 中会看到额外的串口节点。
NJ501 的串口规格以材料为准,需要确认以下几个参数:
- 端口位置:CPU 本体或 CJ1W-SCU 模块。
- 通信方式:RS-232C 或 RS-422A/485。
- 接口定义:D-Sub 9 针引脚。
- 通信参数:波特率、数据位、停止位、校验位。
3.2 Sysmac Studio 软件环境
编写 NJ501 无协议串口通信案例需要安装 Sysmac Studio。从网络材料可以看出,很多人在找 “欧姆龙 Sysmac Studio 在哪可以下载” 和 “欧姆龙编程软件怎么下载” 这类问题,可见软件安装本身就是项目里容易卡住的一环。
Sysmac Studio 通常由欧姆龙官方渠道提供下载或安装光盘。安装时需要注意:
- 最好在 Windows 10 或 Windows 11 专业版上安装,避免家庭版出现权限问题。
- 安装前关闭杀毒软件,否则部分驱动会被误删。
- 安装过程可能需要管理员权限。
- 项目版本与 CPU 的单元版本不匹配时要选择兼容模式。
- 升级包安装步骤一般是在基础版安装完成后,再运行升级包,升级包需要与基础版版本对应。
3.3 硬件连接与测试工具
除了 PLC 之外,还需要准备一套串口测试工具,用于验证 PLC 是否真的发送出了数据帧。常见选择:
- USB 转 RS-232C 串口线。
- 串口调试助手软件(如 SSCOM、友善串口助手等)。
- 或者直接用具备串口监视功能的扫码枪、仪表测试。
为了安全,建议在串口线路上接一个 USB 隔离器或按照设备手册接线,避免地电位差损坏设备。特别是 RS-232C 的发送线和接收线不能接反,D-Sub 9 针典型连接是:
| 引脚 | 信号 | 说明 |
|---|---|---|
| 2 | RXD | 接收数据 |
| 3 | TXD | 发送数据 |
| 5 | GND | 信号地 |
如果 PLC 的 3 脚接对方设备的 2 脚,PLC 的 2 脚接对方设备的 3 脚,GND 相连,才能正常收发。
4. 欧姆龙 NJ501 串口通信原理
在这个案例的讨论中,最常被提到的几个关键词是:欧姆龙 NJ501 无协议串口通信、Sysmac Studio、串行通信单元。要让 NJ501 通过无协议串口发送数据,本质上是解决一个问题:如何把一串自定义字节从 PLC 的串口真正发出去。
4.1 无协议通信与标准协议通信的区别
欧姆龙 PLC 的串口通信选项通常包括:
- Host Link 协议:用于连接上位机或触摸屏。
- Modbus-RTU 协议:用于连接支持 Modbus 的仪表。
- 无协议通信:完全按用户自定义的字节流发送和接收。
无协议模式不解析报文内容,PLC 只负责把用户指定的字节发出去,或者把收到的字节存到缓冲区。NJ501 的系统服务中,官方提供的标准做法是使用SerialComm功能块,但SerialComm更侧重于有固定格式的读取,而且配置步骤比较繁琐,尤其是当设备要求先发后收、并且帧内容不是固定长度时,就会显得不够灵活。
4.2 NJ501 没有"串口自由协议指令"
在 CJ 系列 PLC 中,有专门的TXD、RXD指令可以直接发送和接收无协议数据。NJ 系列改用 IEC 61131-3 标准编程体系,不再提供这种底层指令,标准库中的SerialComm功能块的执行逻辑和控制器内部结构绑定较深,没有现成的 "TXD" 可以直接调用。因此,很多工程师会在论坛上寻找功能块,但官方库并没有提供现成可自由定义帧格式的发送指令。
解决思路有两条:
- 用 Sysmac Studio 的系统函数开发底层串口写入功能块。
- 利用
SysmacBus之类的底层服务接口,将字节数组写入串口。
本案例采用第二种思路,通过 ST 语言编写一个用户功能块,把输入的一个字节数组整体写入串口。
4.3 对 NJ501 系统服务的理解
NJ501 的通信功能是通过系统服务调度完成的,不是简单的逻辑指令调用。串口操作被封装为多个系统功能块,用户需要在项目里创建自定义功能块,并调用系统函数。功能块中需要包含:
- 执行触发信号。
- 通信端口句柄或标识。
- 发送数据缓冲区。
- 发送长度。
- 完成标志和错误代码。
这些系统函数的确切名称需要根据当前 Sysmac Studio 版本、NJ501 单元版本进行确认。常见做法是在 Sysmac Studio 的 "功能块" 中右键选择 "插入系统功能块",查看与串口通信相关的函数库。如果你发现自己的软件版本里系统函数名称和旧版本不一样,以当前 Sysmac Studio 的函数库为准。
5. 使用 Sysmac Studio 实现无协议串口通信发送
5.1 新建项目并选择 CPU 型号
打开 Sysmac Studio 后,首先新建项目。
选择 "NJ501" 系列 CPU,并填入实际 CPU 型号,例如 NJ501-1400 或 NJ501-1500。如果使用 NX1P2 或者 NX7,也按实际型号选择。
项目建立后,需要先配置全局变量和轴设置,但本案例不涉及运动控制,可以跳过轴配置。
5.2 配置串口参数
在 Sysmac Studio 的 "配置和设置" 中,找到 CPU 或通信单元下的串口设置,需要配置:
- 通信设置:无协议。
- 波特率:9600 或 115200,需和扫码枪一致。
- 数据长度:7 或 8。
- 校验位:无、偶校验或奇校验。
- 停止位:1 或 2。
- 接收缓冲区大小:根据设备返回数据量调整。
- 流控:一般不开启。
实际项目中,这些参数要和设备厂商提供的通信协议完全一致。例如有的扫码枪要求 9600、8、N、1,如果 PLC 配置成 115200、8、E、1,那扫码枪不会响应。
5.3 创建发送字符串变量
在全局变量表中新建以下变量:
| 变量名 | 数据类型 | 注释 |
|---|---|---|
| SendData | ARRAY[0..31] OF BYTE | 待发送的数据字节 |
| SendLen | WORD | 实际发送长度 |
| SendExecute | BOOL | 发送触发信号 |
| SendDone | BOOL | 发送完成标志 |
| SendError | BOOL | 发送错误标志 |
| SendErrorID | WORD | 错误代码 |
由于无协议串口发送的本质是发送字节,所以使用字节数组保存要发送的报文。例如,要发送0x02 0x31 0x03,就设置 SendData[0] = 16#02,SendData[1] = 16#31,SendData[2] = 16#03。
5.4 编写 ST 功能块
在功能块中新建一个名为FB_NoProtocolSend的功能块,语言选择 ST。
功能块需要调用 Sysmac Studio 提供的串口写入系统功能块。由于系统功能块的名称和相关库变量会因为软件版本不同而存在差异,这里给出一个通用的 ST 结构,你需要根据当前软件函数库中实际可用的系统功能块名称替换。
FUNCTION_BLOCK FB_NoProtocolSend VAR_INPUT bExecute : BOOL; abData : ARRAY[0..31] OF BYTE; iDataLen : WORD; END_VAR VAR_OUTPUT bDone : BOOL; bError : BOOL; wErrorID : WORD; END_VAR VAR fbWrite : SerialWrite; // 替换为实际系统功能块 bTrigger : BOOL; END_VAR这里的SerialWrite只是示意名称。实际在 Sysmac Studio 中,需要从指令列表里选择与串行通信写入相关的功能块,插入后确认其输入输出管脚名称,再引用到自定义功能块里。
调用主程序时这样写:
fbSend( bExecute := SendTrigger, abData := SendFrame, iDataLen := 3 );5.5 主程序调用示例
假设要在扫码枪需要被触发时发送0x02 0x31 0x03,主程序里可以这样写:
// 帧内容 SendFrame[0] := 16#02; SendFrame[1] := 16#31; SendFrame[2] := 16#03; // 触发发送 SendTrigger := TRUE; SendTrigger := FALSE;需要注意的是,SendTrigger必须是一个上升沿有效信号。不要在同一个扫描周期内同时把SendTrigger的 TRUE 和 FALSE 顺序执行,这样可能导致功能块无法识别。更好的方式是先赋值SendTrigger := TRUE,然后再在下一段逻辑或下一周期复位为 FALSE。如果有丰富编程经验,也可以使用 R_TRIG 上升沿指令处理。
实际上,在 Sysmac Studio 的标准做法里,功能块的执行触发信号往往通过上升沿功能块或调用方式引入。最简单的做法是让 HMI 按钮触发一个内部 bool,则该 bool 作为功能块的输入,功能块内部会在检测到输入上升沿后开始发送数据。
5.6 使用字符串发送 ASCII 报文
有些设备需要发送 ASCII 字符串,例如扫码枪触发指令是"TRG",这时可以先把 ASCII 字符串转换成字节数组。实际上,常见做法是直接在程序中使用复制指令,将字符串常量复制到发送缓冲区:
Sysmac Studio 中字符串常量的长度是按字符计算的,而字节数组是按 BYTE 计算的。如果发送"TRG",那其实需要的是 3 个字节,字符'T'对应16#54,字符'R'对应16#52,字符'G'对应16#47。
为了演示,也可以直接在赋值语句中写入字符:
SendFrame[0] := BYTE_TO_USINT('T');不过在 ST 语言中,这种写法并不一定被接受。更实用的方式是在程序启动时用一个辅助循环把字符串的字节码搬运到数组中,或直接手写 16 进制数值。实际项目中,很多工程师宁可手写SendFrame[0] := 16#54;也不愿意做字符串转字节功能,因为这样排查更快。
5.7 配置扫描周期和串口系统任务
NJ501 的串口通信功能通常需要在系统服务中运行。如果在普通任务中直接调用阻塞式串口写入,可能会影响程序扫描周期的稳定性。最好把通信功能块放到一个独立任务中执行,例如周期为 10ms 或 50ms 的 "串口通信任务"。
在 Sysmac Studio 中,你可以创建多个任务,将功能块实例放在低优先级任务中,这样可以避免串口发送阻塞运动控制任务。
5.8 编译与下载
配置完成后进行编译。编译时会检查变量类型、功能块引脚连接和系统函数名称。常见的错误点包括:
- 功能块引脚名写错。
- 数组越界。
- 系统功能块与当前单元版本不兼容。
- 串口设置和实际硬件端口不一致。
编译通过后,需要通过以太网将项目下载到 NJ501。下载后一定要执行 "复位" 或 "运行",使新配置生效。如果 PLC 之前已经处于运行状态,修改串口设置可能导致系统切换为停止,需要重新启动运行。
6. 功能测试与效果验证
6.1 测试环境
假设测试环境如下:
- PLC:NJ501,通过以太网与 Sysmac Studio 连接。
- 串口:NJ501 本体 RS-232C。
- 测试设备:电脑 USB 转串口模块,连接到 PLC 的串口。
- 软件:串口调试助手。
实物连接时需要注意:
- PLC 的 TXD 接 USB 转串口模块的 RXD。
- PLC 的 RXD 接 USB 转串口模块的 TXD。
- GND 接 GND。
- 波特率、数据位等参数要一致。
6.2 测试步骤 1:基础字节发送
步骤一,设置串口调试助手为 9600、8、N、1,打开串口。
步骤二,在 NJ501 程序中设置发送帧内容:
SendFrame[0] := 16#02; SendFrame[1] := 16#31; SendFrame[2] := 16#03;步骤三,将SendTrigger由 FALSE 置 TRUE,触发发送功能块。
步骤四,观察串口调试助手的接收区,是否出现02 31 03。
如果接收到的数据和预期一致,说明发送功能块工作正常。如果收不到数据,不要急着检查程序,先确认串口调试助手是否收到了其它乱码,以此判断接线是否正确。如果收到乱码,多半是波特率或校验位不一致。如果完全没数据,重点检查接线和 PLC 串口是否被编程口复用。
6.3 测试步骤 2:字符串发送
修改发送帧内容为 ASCII 码。如果要发送"TRG":
SendFrame[0] := 16#54; SendFrame[1] := 16#52; SendFrame[2] := 16#47;触发后,串口调试助手接收区应显示54 52 47。如果串口调试助手开启"按 ASCII 显示"模式,则会直接显示TRG。
6.4 测试步骤 3:定时循环发送
如果扫码枪采用轮询触发方式,PLC 需要每隔一段时间发一次指令。可以在程序里增加一个定时器,定时时间到就触发发送:
IF T_15s.Q THEN SendTrigger := TRUE; END_IF SendTrigger := FALSE;实际工程中,不要直接在赋值后立刻复位,否则触发脉冲过窄。推荐使用一个定时器产生 200ms 的脉冲,再送入功能块输入。更好的做法是使用 R_TRIG 上升沿结构,这样触发只在条件满足的那一个扫描周期被捕获一次。
这里以 Sysmac Studio 中常用的定时器方式为例:
// 每 2 秒触发一次扫描请求 TON_1( In := NOT TON_1.Q, PT := T#2S, Q => TimerQ, ET => TimerET ); // 用上升沿检测形成单次脉冲 R_TRIG_1( CLK := TimerQ, Q => PulseSend ); IF PulseSend THEN SendTrigger := TRUE; ELSE SendTrigger := FALSE; END_IF;6.5 测试步骤 4:对接扫码枪
将 NJ501 的串口直接连接到扫码枪的串口。PLC 发送触发指令后,扫码枪应开始扫描。在成功读取条码后,扫码枪会把结果返回到 NJ501 的接收缓冲区。如果只是测试发送,可以不处理接收数据,但实际项目中接收才是难点。
如果扫码枪是 USB 接口,需要用支持串口协议转换的扫码枪底座,或者选用带 RS-232 接口的扫码枪。
7. 进阶:NJ501 结合扫码枪与字符串接收
很多无协议串口通信项目并不是只发送一两条指令就结束了。最常见的场景是:
- PLC 发送触发帧。
- 扫码枪返回一帧条码数据。
- PLC 接收并解析条码字符串。
- 判断是否为合法条码。
- 根据条码进行后续动作。
如果只看“发送”,本案例已经完整;但为了项目落地,必须考虑接收和解析。
7.1 接收数据的存储
无协议串口接收时,NJ501 需要把收到的字节存入缓冲区。在程序中可以定义接收缓冲区和接收长度:
VAR abRecvData : ARRAY[0..127] OF BYTE; iRecvLen : WORD; END_VAR系统功能块收到数据后,会把数据复制到 abRecvData 中,并把实际长度写入 iRecvLen。
7.2 条码数据的常见格式
很多扫码枪默认输出格式是:条码内容 + 回车换行。例如条码内容为ABC123456,那么实际返回的字节是:
41 42 43 31 32 33 34 35 36 0D 0A
其中0D 0A是回车换行。在解析时,程序需要忽略尾部的回车换行,把有效字符拼成字符串变量。
7.3 判断接收完成
判断一帧数据是否接收完成,常用两种方法:
- 固定长度判断:接收长度等于预期长度时认为接收完成。
- 超时判断:从收到第一个字节开始计时,如果在 50ms 到 200ms 内没有新字节,认为一帧接收完成。
在 Sysmac Studio 中,可以通过系统功能块获取接收到的字节数,然后在程序中比较。一般写法是轮询接收计数,如果计数不变,则代表接收结束。
7.4 字节数组转字符串
收到条码字节后,如果要在 HMI 或 Sysmac Studio 的变量监控中直接显示,需要把字节数组转换成字符串。欧姆龙 Sysmac Studio 中,ST 语言可以使用数组元素拼接字符串。例如:
sBarcode := ''; FOR i := 0 TO iRecvLen - 1 LOOP sBarcode := sBarcode + CHR(abRecvData[i]); END_FOR;CHR 的作用是把字节值转换为对应字符。不同版本的 Sysmac Studio 对 CHR 的支持可能有差异。如果你不确定是否支持 CHR,可以先在帮助文档里搜索“字符串转换”,或者使用中间变量辅助转换。
8. 接口 API 与批量任务
这个案例本身是 PLC 串口通信,不是 Web API 服务,所以没有标准 REST API 可以调用。但在自动化项目中,NJ501 往往还需要通过 EtherNet/IP 与上位机或 MES 系统交互,由上位机触发扫码请求。这种情况下,可以理解为“外部接口触发串口发送”。
8.1 用 EtherNet/IP 变量触发发送
Sysmac Studio 支持通过 EtherNet/IP 将 NJ501 的内部变量映射为显式报文标签。例如,上位机通过 EtherNet/IP 将一个SendTrigger变量写为 TRUE,NJ501 检测到上升沿后执行串口发送功能块。
这种方式可以解决“PLC 串口设备与上层系统间联动”的问题。上位机不需要关心 PLC 怎么发送串口报文,只需写一个布尔变量。
8.2 多次发送与批处理
如果需要连续读取多个产品条码,PLC 的逻辑可以设计为:
- 等待产品到位信号。
- 发送扫码触发帧。
- 等待扫码枪返回数据。
- 解析条码并判断 OK/NG。
- 如果 NG,可能会重新发送一次触发指令。
- 发送下一轮。
批量任务的重点不在发送本身,而在流程状态机设计。可以用一个 INT 型步骤变量来实现:
CASE nStep OF 0: // 等待触发信号 IF bStart THEN nStep := 10; END_IF; 10: // 发送扫码触发帧 SendTrigger := TRUE; nStep := 20; 20: // 等待发送完成 IF SendDone THEN nStep := 30; END_IF; 30: // 等待接收超时或接收完成 IF RecvDone THEN nStep := 40; ELSIF bTimeout THEN nStep := 90; END_IF; 40: // 解析条码 sBarcode := BuildString(abRecvData, iRecvLen); nStep := 50; 50: // 返回结果,等待下一次触发 bResultReady := TRUE; nStep := 0; END_CASE;这种结构便于维护,也容易添加重试、超时和报警逻辑。
8.3 控制周期与任务优先级
NJ501 中如果某个任务同时处理 HMI 通信、EtherNet/IP 通信和串口发送,可能导致串口发送抖动。更稳妥的做法是把串口通信放到一个独立任务中,周期设为 10ms 或 20ms,并设置中等优先级。运动控制任务保持在 1ms 或 2ms 周期,不要被通信任务拖累。
分配任务的技巧:
- 主任务:运动控制或逻辑控制。
- 附属任务 1:串口发送和接收处理。
- 附属任务 2:EtherNet/IP 数据映射或与上位机握手。
在程序体量不大的情况下,也可以把所有逻辑都写在主任务中,再依靠系统服务底层自动调度串口写入。但从稳定性和可排查性考虑,独立任务更好。
9. 资源占用与性能观察
9.1 扫描周期影响
功能块一旦触发,底层串口发送过程会占用一定时间,但 NJ501 的串口发送速度相对较快。如果发送一个 10 字节的帧,在 9600 波特率下,理论耗时约 10ms 左右。如果波特率为 115200,那这个时间会缩短到 1ms 左右。实际上,系统功能块的返回时序还受到任务周期影响。
如果发送频率不高,例如每 500ms 才发一次,程序扫描压力很小;如果要求 PLC 在 1ms 任务里频繁发送串口帧,这就不合理,串口本身的物理速度也跟不上。
9.2 如何处理发送失败
发送失败通常表现为SendError标志为 TRUE。失败原因可能包括:
- 串口被其它程序或功能块占用。
- 发送缓冲区被写满。
- PLC 任务周期过长,导致超时。
- 通信线路断开。
在程序中加入错误判断,输出错误代码:
IF fbSend.bError THEN nErrorCode := fbSend.wErrorID; END_IF;在 Sysmac Studio 的“错误表”中,可以根据错误代码查找到对应的系统错误定义。
9.3 Sysmac Studio 在线监控
把项目下载后,在 Sysmac Studio 的“在线监控”中可以实时观察:
- SendTrigger 的状态。
- SendDone 的状态。
- SendError 的状态。
- 待发送数组的内容。
- 如果做了接收功能,也能看到接收数组的内容。
在调试阶段,建议把SendFrame[0]、SendFrame[1]、iDataLen都拖到监视窗口,点击触发后逐条确认。
如果发生了发送超时或没有返回,可以在“数据追踪”中观察触发时间点前后的变量曲线,一般能快速定位是触发没产生,还是功能块没有正确执行。
10. 常见问题与排查方法
以下表格汇总做 NJ501 无协议串口通信项目时最容易遇到的问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 程序下载后 PLC 报错,无法运行 | 功能块引脚或系统函数不兼容 | 查看 Sysmac Studio 错误窗口和 PLC 错误日志 | 替换为当前系统库支持的功能块,检查单元版本 |
| 串口调试助手收不到任何数据 | 接线错误或串口被编程占用 | 检查 TXD/RXD/GND 接线,查看 PLC 串口设置是否被配置为编程口 | 使用以太网编程,释放串口;TXD/RXD 交叉连接 |
| 收到乱码 | 波特率、校验位或数据位不一致 | 核对扫码枪和 PLC 的串口参数 | 在 Sysmac Studio 和串口调试助手中统一参数 |
| 发送帧前几位丢失 | 触发信号被功能块内部复位 | 观察发送缓冲区赋值时机 | 先赋值数据,再触发发送,或使用 R_TRIG 上升沿 |
| 接收数据不完整 | 接收缓冲区太小或任务扫描慢 | 查看接收长度变量 | 增大缓冲区,缩短任务周期 |
| 功能块执行几百毫秒才完成 | 串口任务周期太长或波特率低 | 使用数据追踪 | 调整任务周期或提高波特率 |
| 程序运行过程中偶尔发送失败 | 串口被其他任务同时访问 | 查看错误代码 | 避免多个地方同时调用同一串口功能块,加互斥逻辑 |
| 使用 CX-Programmer 在线连接时串口不通 | 串口已分配给无协议通信 | 检查通信设置 | 改用以太网连接,或临时切换通信模式 |
| Sysmac Studio 中找不到串口设置项 | CPU 型号不支持本体串口,或未插入 CJ1W-SCU 模块 | 检查硬件配置 | 使用带串口的型号,或添加通信单元 |
10.1 关于欧姆龙 NJ 系列不同型号的差异
不支持的 CPU 型号如果尝试用本体串口调试,其实是做不到的。比如 NJ301、NJ101 这类 CPU 没有本体串口,必须通过扩展 CJ 系列串行通信单元。NJ501 系列部分型号带本体 RS-232C,但 RJ 型或一些特殊配置可能存在差异,更稳妥的做法是查看系统手册或在 Sysmac Studio 的硬件配置中确认是否存在串口设置页。
NX1P2 本体带一个 RS-232C 串口,它的配置方式和 NJ501 基本类似,也支持无协议串口通信。NX7 系列配置方式相同,但需要根据具体型号确认是否是 RJ 型号,RJ 型号没有串口,通常以 EtherCAT 和 Ethernet/IP 为主。
11. 最佳实践与使用建议
11.1 先搭测试环境,不直接上现场设备
第一次做 NJ501 无协议串口通信发送时,建议先用 USB 转串口模块连接电脑,用串口调试助手看发送结果。不要直接连接扫码枪或其它仪表,否则一旦报文格式错误,设备不会响应,程序问题还是接线问题都很难区分。用串口调试助手的好处是能看到十六进制的原始字节,能给后续协议排错提供依据。
11.2 把发送帧内容做成变量,方便在线修改
不要把所有帧直接写死在功能块内部,尽量通过 IN 变量传入。这样在调试时,可以从 HMI 或 Sysmac Studio 在线修改发送值。
一个实用的功能块输入设计:
VAR_INPUT bExecute : BOOL; abyData : ARRAY[0..63] OF BYTE; udiLen : UDINT; END_VAR数组长度不要盲目设置过大,太大浪费内存,太小会导致越界。
11.3 做好错误记录
生产环境中,串口瞬间失败可能不影响大局,但如果设备长期运行,失败次数多了会影响生产节拍。这时可以在 PLC 里设计一个 FIFO 错误记录,每次发送失败都记录错误代码和时间戳。这样发生故障时,不需要一直盯监控画面,也能知道失败发生前后的过程。
Sysmac Studio 本身支持控制器错误日志,但用户自定义通信错误不会自动写入。实际项目中,常用自建数组存放最近 100 条错误记录,并把最新记录映射到 HMI 报警画面。
11.4 与 HMI 配合调试
使用 HMI(如欧姆龙 NB、NA 系列),可以设计一个简单画面:
- 一个输入框:填写待发送数据。
- 一个按钮:触发发送。
- 一个指示灯:发送完成。
- 一个显示框:查看错误代码。
这样现场调试时,不需要打开 Sysmac Studio,只需要在触摸屏上操作即可测试串口通信。但要注意:触摸屏输入的字符串要按字符转成字节数组后,才能传给发送功能块。如果使用的是十六进制输入,还需要做字符串到十六进制字节的转换。
有些项目直接用 HMI 的宏指令在触摸屏侧完成字符串到字节的转换,再把结果写到 PLC。这个过程会增加 HMI 脚本维护量,但对 PLC 程序简洁度有帮助。具体要看现场习惯。
11.5 发送数据与接收数据分别用独立缓冲区
如果后续要扩展扫码枪接收功能,接收缓冲区与发送缓冲区必须分开定义,否则互相覆盖后很难排查。变量命名也建议带前缀,例如bSendTrigger、bRecvDone、abSendFrame、abRecvFrame。
11.6 重视设备厂商协议文档
扫码枪或仪表的通信协议文档是项目能否成功的关键。常见需要确认的信息包括:
- 指令帧格式。
- 触发指令是十六进制还是 ASCII 字符串。
- 指令发送后设备响应时间。
- 设备返回帧的结束符。
- 波特率、停止位、校验位。
- 是否需要 CRC 校验。
如果厂商文件只提到“通过电脑串口助手可以发送7E 00 08 01 00 02 01 AB CD触发”,那你在 NJ501 中实现的就是这串十六进制数据的字节数组组装和发送。
12. 关于欧姆龙 Sysmac Studio 与常见疑问
做 NJ501 通信开发,必须熟悉 Sysmac Studio 的基本操作。这里把最容易困惑的几个点集中回答。
12.1 Sysmac Studio 在哪里下载
欧姆龙官方的软件下载通常需要通过授权经销商或欧姆龙官网技术支持页面。搜索“欧姆龙 sysmacstudio 在哪可以下载”时,会看到很多第三方网盘分享,这类下载来源不一定安全,不推荐直接使用。安装时,建议从官方渠道获取并核对版本信息。没有正规授权时,也可以和欧姆龙技术支持联系,申请试用版本。本文不提供任何非官方下载地址。
12.2 升级包安装步骤
Sysmac Studio 升级包的安装步骤一般是:
- 关闭正在运行的项目,退出 Sysmac Studio。
- 运行基础安装包,完成基础版安装。
- 运行升级包安装程序。
- 按提示完成注册和环境更新。
- 重启电脑。
不要在项目文件打开时执行升级包,否则可能导致文件损坏。升级完成后,最好重新编译一次项目。
12.3 ST 语言与梯形图的取舍
本案例使用 ST 语言开发功能块,因为字节数组处理和循环赋值在 ST 中更直观。如果有梯形图基础,也可以把发送触发逻辑做成梯形图,只是字节数组的初始化会比较繁琐。更合理的结构是:
- 梯形图负责设备动作和流程控制。
- ST 功能块负责串口底层打包和调用。
- 全局变量作为两者之间的桥梁。
12.4 Sysmac Studio 版本与 CPU 单元版本
Sysmac Studio 项目和 CPU 的“单元版本”必须兼容。如果软件版本较老,可能无法识别较新的 NJ501 CPU,或功能块库缺少某些系统函数。在项目属性里可以设置目标 CPU 版本,编译前先确认目标版本与实物一致。如果 PLC 报单元版本不匹配,可以选择重新上载项目,或使用软件里的版本切换功能。
12.5 NJ501 与 NX1P2 的无协议串口发送
NX1P2 本体没有那么多轴,但在串口通信配置上与 NJ501 非常接近。它的本体串口也可以用同样的思路实现无协议发送。NX1P2 的串口没有五类以太网口那样的高速通道,只能作为普通串口使用。如果你的项目要求低成本且只有几个轴,NX1P2 会比 NJ501 更有性价比。
13. 具体工程接线参考与安全提醒
使用 RS-232C 连接时,需要注意:
- 发对收、收对发、地连地。
- 如果插座是公头母头不同,需要准备对应的转接线。
- 长距离通信建议使用 RS-422A/485,而不是 RS-232C。
- RS-232C 电平不适合长距离传输,一般不超过 15 米。
- 串口线要远离动力线和变频器输出线,避免干扰。
RS-422A/485 的情况:
- RS-422A 是 4 线制,发送和接收分开,支持全双工。
- RS-485 是 2 线制,半双工通信。
- NJ501 本体串口一般不直接支持 RS-485,需要用 CJ1W-SCU41-V1 等串行通信单元或外接 RS-232C 转 RS-485 转换器。
- 通信距离越远,波特率要适当降低,保证信号质量。
- 总线上如果连接多个设备,要配置终端电阻。
在调试期间,串口线制作方法:
PLC 端(9针公头) 电脑端(USB转串口) 2 RXD <------------- 3 TXD 3 TXD -------------> 2 RXD 5 GND ---------------- 5 GND如果只测试发送,不涉及接收,那么 PLC 端 3 脚接电脑端的 2 脚,5 脚接 5 脚,2 脚可以不接或接电脑端的 3 脚。
14. 总结与下一步
欧姆龙 NJ501 实现无协议串口通信发送,核心考验其实是两件事:第一,你能不能接受“标准库没有直接提供无协议发送功能块”这个事实,并用底层系统函数去封装一个;第二,你能不能把字节数组、触发信号、串口参数、任务配置这几件事配合好。
值得优先验证的功能是:发送一串固定十六进制字节到串口调试助手,看是否原样收到。如果这一步通了,后续对接扫码枪只是帧格式不同而已。
容易踩的坑主要有三个:
- 串口被配置成编程口,导致无协议数据实际没有在串口上发出。
- 功能块调用方式和系统库版本不匹配,编译能过但运行时无动作。
- 触发信号没有做上升沿处理,导致数据只是赋值了,但发送功能块没有被有效执行。
如果想继续扩展,下一步可以做扫码枪触发读取并解析条码,再配合 HMI 做一个手动测试画面。项目稳定后,可以把发送功能块、接收功能块和超时状态机封装成一个完整通信库,复制到其它 NJ/NX 项目中复用。
这个案例的整体价值在于:当欧姆龙 NJ501 面对非标串口设备时,不需要额外购买专用协议网关,只需要用 Sysmac Studio 开发一个底层字节发送功能块,就能兼容很多现场设备。建议做设备集成的工程师收藏备用。