NJ501 是欧姆龙 NJ 系列里很多人拿来当“运动控制器”用的型号,EtherCAT 轴控、EtherNet/IP 联网都熟。可真到了产线上,反倒是被一批最基础的串口设备卡住:扫码枪只发 ASCII 字符串,称重仪表定时吐一行重量,老式测试台返回十六进制帧,电平就是 RS-232C,协议就是“没有协议”。
这种场景不能靠 Modbus-RTU 硬凑,也不能因为对方不支持总线就换设备,正确做法是让 NJ501 走无协议串口通信,把原始字节收进来,再自己解析。这篇不讲 EtherCAT,只讲一件事:欧姆龙 NJ501 怎么做无协议串口的数据接收。
先说三个判断:
- 这是一项纯软件加配置的工作,不依赖额外总线模块,项目核心在 Sysmac Studio 的串口参数设置和接收程序结构。
- 适合 9600/19200/38400/115200 这类常规波特率下的可变长或固定长帧接收,数据帧怎么结束,由你配置的“结束条件”决定。
- 实际调试时需要串口调试助手或真实从站设备配合,最好通过 Ethernet 口在线监控,避免同一个 RS-232C 口既当通信口又当编程口。
文章会按“应用边界 → 硬件准备 → Sysmac 设置 → 接收程序 → 在线调试 → 帧解析 → 排错清单”的顺序展开。你不需要记住所有截图位置,只要手里有一台 NJ501 和一套 Sysmac Studio,按这个流程走一遍,大部分无协议接收项目都能套上。
1. 核心能力速览
| 项目 | 说明 |
|---|---|
| 控制器 | 欧姆龙 NJ501 系列机器自动化控制器 |
| 编程软件 | Sysmac Studio |
| 通信模式 | 无协议串口通信(Non-protocol) |
| 常用物理接口 | CPU 内置 RS-232C、扩展串行通信单元 |
| 接收对象 | 扫码枪、仪表、单片机板卡、上位机下发的原始字节 |
| 数据形式 | ASCII 字符串或十六进制帧 |
| 接收完成条件 | 固定字节数、终止字符(如 CR/LF)等 |
| 后续处理 | 帧校验、ASCII 转数值、状态机解析、缓存转发 |
| 是否需要额外授权 | 不需要,使用系统自带串口功能 |
| 典型门槛 | 熟悉 Sysmac Studio 基础操作,能完成在线连接与下载 |
这套能力的核心价值不是“串口能通”,而是“把不可控的字节流变成可控的帧数据”。真正花时间的不是通信参数,而是接收触发条件怎么设置、缓冲数据怎么及时取走、断帧粘帧怎么处理。
2. 适用场景与使用边界
无协议串口通信的典型场景有这几类:
- 扫码枪读取条码后,通过 RS-232C 把条码内容发给 PLC。
- 称重仪表按固定周期输出一行 ASCII 数据,PLC 需要截取重量字段。
- 检测设备返回十六进制帧,PLC 负责判断状态字。
- 老式数控机床、视觉控制器、单片机控制板需要和 NJ 系列做原始数据交换。
这些设备有一个共同特点:不跑 Modbus,不跑 HostLink,也不支持 EtherNet/IP。它们只负责“把数据发出来”,能不能被正确接收,完全看接收端配置。
也要说清楚不适合什么场景:
- 对实时性要求极高的运动控制联动,不要靠串口做主通道。串口天然是低速异步通道,数据拥塞和延迟都不可控。
- 一次通信需要几十种命令交互、还要带复杂状态管理时,不要硬写无协议。可以考虑 Modbus-RTU 或 HostLink,它们自带协议栈,省去大量解析工作。
- 长距离传输超过 15 米左右,RS-232C 电平不稳定,应改用 RS-422/RS-485 或加转换器。
关于安全和合规,工业现场必须注意:
1. 接线、下载程序、在线修改参数前,应确保设备处于安全状态。 2. 串口接收到的数据不要直接用于轴位置、速度、力矩等安全相关控制,除非程序做了完整校验和权限管理。 3. 涉及设备厂家私有协议、版权固件或未公开报文时,应先获得授权,再做解析与转发。 4. 不要在生产设备上直接验证未完成的解析逻辑,建议先离线模拟或旁路测试。这一段不是套话。无协议通信意味着 PLC 不判断数据内容是否合理,全由你的梯形图或 ST 程序负责。一旦把错误的数据当成有效测量值用,设备误动作的风险会明显上升。
3. 环境准备与前置条件
做 NJ501 无协议串口接收,需要准备以下内容。
3.1 硬件清单
| 硬件 | 作用 |
|---|---|
| NJ501 CPU | 接收数据并执行解析逻辑 |
| 串口设备 | 扫码枪、仪表或 PC 串口调试助手 |
| RS-232C 通信线 | PLC 与外部设备连接 |
| USB 转串口 / PCI 串口卡 | PC 连接外部设备侧或 PLC 侧 |
| 网线 | NJ501 通过 EtherNet/IP 口连接 Sysmac Studio 在线调试 |
如果确认 NJ501 CPU 自带 RS-232C 口,可以直接使用。对于不带串口的型号,一般通过 CJ 单元适配器扩展串行通信单元,不同型号的扩展方式不同。最稳妥的办法是打开硬件手册确认本机 CPU 的串口位置和通信单元型号。
3.2 连接关系规划
无协议接收调试时,建议把“编程通道”和“数据通道”分开:
PC 1: Sysmac Studio 通过 Ethernet 连接 NJ501,用于下载程序和监视变量。 PC 2: 串口调试助手通过 USB 转 RS-232C 连接 PLC 的 RS-232C 口,模拟外部设备发送数据。如果现场已经接了真实设备,就不需要 PC 2。用真实设备发数据测试更可靠,但问题定位速度会慢一些,因为你看不到 PLC 到底收到什么字节。两种方式可以结合:
先用 PC 串口助手模拟发送,验证配置和程序;再切换成真实设备做最终通信验证。3.3 软件准备
| 软件 | 用途 |
|---|---|
| Sysmac Studio | 项目开发、参数设置、程序编写、在线监视 |
| 串口调试助手 / 串口终端 | 发送测试帧,查看回显 |
| 欧姆龙 NJ 系列相关手册 | 确认指令参数、缓冲区和错误代码 |
不需要额外安装通信库,Sysmac Studio 内部已经集成了无协议串口通信需要用到的系统指令和功能块。只是不同版本的软件在指令助记符和库组织上会略有差异,实际开发前建议先打开软件里的指令帮助核对一次。
4. Sysmac Studio 中的无协议串口参数设置
进入 Sysmac Studio 后,无协议通信的设置位置在控制器的“内置串行端口设置”中。用文字描述就是:
配置和设置 → 控制器设置 → 内置串口设置在这个页面里,核心要改的是两部分:通信格式,以及接收完成条件。
4.1 通信格式设置
通信格式必须与外部设备完全一致。常见的参数项如下:
| 参数 | 推荐设置 | 说明 |
|---|---|---|
| 串行通信模式 | 无协议 | 不使用 Modbus/HostLink |
| 波特率 | 9600 / 19200 / 38400 / 115200 | 与外部设备一致 |
| 数据长度 | 8 bit | 多数设备默认 |
| 停止位 | 1 bit | 与设备一致 |
| 校验位 | None / Even / Odd | 与设备一致 |
| 流控 | None | 不启用 RTS/CTS 时保持关闭 |
如果外部设备说明书没有明确写帧格式,先用串口助手连接设备抓包,确认波特率、停止位和校验位,再写入 PLC。不能凭感觉猜。
4.2 接收完成条件设置
无协议通信的难点不在“收字节”,而在“怎么知道一帧数据收完了”。Sysmac Studio 中一般可以配置接收完成条件,常见有两种:
| 方式 | 适用场景 | 优缺点 |
|---|---|---|
| 接收字节数固定 | 协议固定长度,例如 8 字节一帧 | 简单可靠,但无法处理变长帧 |
| 终止字符 | 数据以 CR、LF 或 CR+LF 结束 | 适合 ASCII 文本帧,但设备必须带结束符 |
比如扫码枪默认很多是在条码内容后面补CR或CR+LF,这时可以把接收完成条件设置为“终止字符”。设备发送内容ABC123加回车,PLC 收到回车就认为一帧数据已经结束,然后触发后面的接收程序。
如果外部设备每帧固定返回 16 个字节,则优先采用“接收字节数”方式。它不依赖特殊字符,只要数量到了就触发。
需要提醒一点:接收完成条件只是告诉系统“这一帧收完了”,并不等于你把数据读回用户程序了。缓冲区里的数据还要由接收指令或功能块取走,否则下一帧进来后可能产生覆盖或遗留问题。
4.3 保存设置并传送到 PLC
参数修改完成后,需要执行“传送到控制器”操作。串口参数通常必须在控制器复位后才会完全生效。
操作顺序建议:
1. 项目离线修改。 2. 保存项目。 3. 连接控制器。 4. 传送到控制器。 5. 复位控制器。 6. 复位后确认设置生效。如果控制器在线修改不允许直接改写串口模式,就先把 CPU 切到编程模式或停止模式。具体操作以当前 Sysmac Studio 软件提示为准。
5. 接收程序设计思路
无协议接收的经典逻辑包含四个状态:
等待接收完成标志 → 读取串口缓冲区 → 解析数据帧 → 复位标志并进入下一轮不要试图在主任务里一边做运动控制、一边用密集轮询去等串口数据。NJ 系列本身是多任务架构,建议单独建一个通信任务,周期可以设置得比主任务稍松,比如 10ms 到 50ms,根据现场数据量定。
核心判断条件如下:
| 信号 | 含义 | 程序处理 |
|---|---|---|
| 接收完成标志 | 系统认为一帧已结束 | 触发读取缓冲区动作 |
| 接收数据长度 | 实际收到多少个字节 | 决定解析范围 |
| 状态字 / 错误代码 | 通信端口是否有异常 | 记录日志并复位 |
| 用户数据数组 | 从缓冲区复制出来的原始数据 | 送入解析函数 |
下面是一个结构化文本风格的逻辑示意。注意不是完整编译程序,只是把接收逻辑表达清楚,实际变量名需要根据你的工程调整。
// 伪代码:串口接收主逻辑 IF bRecvComplete THEN // 1. 把当前接收缓冲区的数据复制到用户数组 FOR i := 0 TO uRecvLen - 1 DO uFrame[i] := RawBuffer[i]; END_FOR; // 2. 记录当前帧长度 uFrameLen := uRecvLen; // 3. 置位帧就绪标志,交给解析程序 bFrameReady := TRUE; // 4. 清理接收完成标志,允许继续接收下一帧 bRecvComplete := FALSE; END_IF;实际项目中,读取缓冲区这一步通常不是直接写RawBuffer[i],而是调用系统提供的串口接收指令或功能块,把内置端口接收缓冲区的内容搬运到用户指定地址。指令名称在不同 Sysmac Studio 版本中可能不同,建议直接打开 Sysmac Studio 的指令帮助,搜索以下关键字:
Serial Receive Recv RXD 无协议找到“接收数据”相关的指令或功能块后,按 F1 查看参数说明,用“源端口 / 目标数组 / 接收长度”的方式调用。
6. 接收程序的解析层处理
把原始字节从串口缓冲区读出来之后,下一个问题是:这些字节到底代表什么?
6.1 ASCII 字符串帧解析
条码、仪表读数、设备状态信息,很多都直接以 ASCII 字符发送。比如收到:
ABCD1234\r\n其中\r是回车符,\n是换行符,PLC 需要把有效字符ABCD1234截取出来。如果不需要换行符,可以按字节索引截取,从第 0 字节取到最后一个有效字符,或者遇到0x0D、0x0A就结束。
6.2 十六进制帧解析
检测设备常使用十六进制帧,例如一帧 7 字节:
AA 01 10 00 12 23 FE这串数据通常包含帧头、命令码、数据字段和校验字节。解析时先找帧头AA,再按固定位置取数据,最后校验FE。
6.3 BCC 校验逻辑示意
很多无协议设备不用 Modbus 自带的 CRC,而是自己定义 BCC(异或校验)。以下用 ST 写一个简化思路:
FUNCTION F_BccCheck : BOOL VAR_INPUT uFrame : ARRAY OF BYTE; uLen : UINT; END_VAR VAR i : UINT; bcc : BYTE; END_VAR bcc := 0; FOR i := 0 TO uLen - 2 DO bcc := bcc XOR uFrame[i]; END_FOR; IF bcc = uFrame[uLen - 1] THEN F_BccCheck := TRUE; ELSE F_BccCheck := FALSE; END_IF;这是一个比较典型的帧尾校验写法。具体数组类型、长度变量和寻址方式,要按 Sysmac Studio 实际支持的语法微调。重点是理解校验思想:发送端把所有数据字节做异或,得到校验字节放在帧尾;接收端重新计算异或,和最后一字节比较。一致则认为帧有效,不一致要丢弃或请求重发。
6.4 多字段数据提取
对于像称重仪表输出ST,+001.234kg\r\n这种字符串,收到后不能直接拿数组往数值变量里放。先把有效字符提取出来,再定位到数值部分,用一个字符一个字符判断的方式组成临时字符串,最后转换成浮点数。这一步在 NJ 系列上可以用字符串处理指令,但更稳妥的是自己写一个状态机式解析,逐字节处理,避免依赖系统和设备定义的差异。
7. 在线调试与变量监视
无协议通信调试时,Sysmac Studio 的在线监视非常关键。建议打开以下变量:
| 变量 | 监视目的 |
|---|---|
| 接收完成标志 | 确认 PLC 是否认为一帧已结束 |
| 接收长度变量 | 判断设备是否真的发过来数据 |
| 用户数据数组 | 查看收到的原始内容 |
| 状态字 | 检查端口异常和溢出情况 |
当你用 PC 串口助手发送一帧数据后,正常顺序应该是:
串口助手发送 → 接收完成标志由 OFF 变 ON → 接收长度更新 → 用户数据数组出现内容如果接收完成标志一直不变化,先检查通信参数,再看外部设备是否真的把数据发出去了。
调试期间最容易犯的错误是只盯 Watch 窗口,不关注数据更新速度。串口数据是异步到达的,手动刷新监视可能看不到一瞬间的置位。可以配合 Sysmac Studio 的数据跟踪功能,把接收完成标志和接收长度变量加入跟踪,触发条件设为接收完成标志上升沿。这样即使数据一闪而过,也能抓到。
实测速度参考要说明:不同外围设备发送周期差异很大。有的扫码枪是触发一次只回一帧,有的仪表每 100ms 就发一行。对于高频数据发送,建议在真实设备接入前先确认程序单帧处理耗时,如果处理逻辑太重,会出现缓冲区新数据覆盖旧数据的情况。
8. 用串口调试助手模拟发送
在没有真实设备的情况下,用 PC 串口助手模拟是最快的验证方式。连接方式如下:
PC (USB转RS-232C) → RS-232C线缆 → NJ501 内置 RS-232C 口PC 端用 Python 也可以完成同样的发送测试。下面是一个简化脚本,模拟外部设备定时发送一帧十六进制数据:
import serial import time ser = serial.Serial( port="COM5", # 按实际串口号修改 baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1 ) frame = bytes([0xAA, 0x01, 0x10, 0x00, 0x12, 0x23, 0xFE]) try: while True: ser.write(frame) print("send:", frame.hex(" ")) time.sleep(1) except KeyboardInterrupt: pass finally: ser.close()如果你要测试 ASCII 数据,把 frame 换成:
frame = b"ABCD1234\r\n"发送后回到 Sysmac Studio 监视窗口看用户数据数组,确认收到的十六进制内容与发送内容一致。
注意:用 PC 串口助手模拟时,要把自己当成“外部设备”。NJ501 作为接收方,PC 只发不收也可以。如果测试双方都是只发不收,必须确认接线中的发送和接收引脚交叉正确,否则 PC 发出的数据根本到不了 PLC。
9. 接口 API 与批量数据采集的扩展思路
无协议串口通信本身不涉及上层 API,它做的是把外部设备原始数据引到 PLC 内部。但在实际工程项目中,数据往往会继续往上层传递。
常见扩展方向是:NJ501 接收完数据并完成解析后,把结果写入内部变量,再通过 EtherNet/IP、OPC UA 或 Socket 服务让上位机读取。上位机拿到数据后可以写入数据库、做看板显示或者参与工艺统计。
如果要做批量采集,建议在 PLC 内先建立一组环形缓冲区:
接收完成 → 解析成功 → 数据写入 FIFO → 上位机定期读取 → 清除已读数据FIFO 的好处是避免上下位机速度不匹配导致数据丢失。
同样要提醒:上位机通过网口读取 PLC 数据时,必须做好访问权限控制,不要默认开放所有读写变量。尤其在工业现场,任意写入可能触发设备动作,需要严格限定可写变量范围。
10. 资源占用与实时性观察
NJ501 的串口接收通常不会产生特别高的 CPU 占用,但不代表可以随意写代码。
以下几个因素会直接影响性能:
| 因素 | 影响 |
|---|---|
| 接收任务周期 | 周期越短,响应越快,但 CPU 占用越高 |
| 数据解析复杂度 | 大量字符串转换和循环会拉长任务执行时间 |
| 接收数据频率 | 高频数据会造成缓冲区频繁变化 |
| 缓冲区大小设置 | 过小可能丢帧,过大会积累旧数据 |
| 串口波特率 | 波特率越高,单位时间到达的字节越多 |
建议把通信任务和运动控制任务分开。如果 NJ501 本身要做多轴插补或高速定位,串口解析不要放在同一个高速任务里。低速任务里完成字节接收,再通过事件或标志通知主任务,这样能避免串口处理拖累运动控制。
对于长时间无人值守运行,要在程序里增加看门狗式逻辑。比如设备规定每秒发送一帧数据,如果超过 3 秒没有新的接收完成标志,就要记录通信超时并输出告警。这样即使外部设备掉线,PLC 侧也能第一时间发现。
11. 常见问题与排查方法
无协议串口接收的问题绝大多数出现在接线、通信参数和接收完成条件三个环节。可以参考下表排查。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 完全收不到数据 | 接线错误,收发引脚不对 | 检查 PLC 和设备的 TX、RX、GND 连接 | 交叉连接或按设备手册重新接线 |
| 完全收不到数据 | 波特率、校验位不一致 | 在串口助手中先抓包确认设备 |