ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

欧姆龙NJ501无协议串口通信发送实战:Sysmac Studio到ST配置全解析

2026/9/5 6:17:19 拓冰建站 浏览量
欧姆龙NJ501无协议串口通信发送实战:Sysmac Studio到ST配置全解析 在调试欧姆龙 NJ501 的运动控制项目时我遇到过比较常见的需求设备需要把“当前工位完成、产品合格/不合格”等信息发送给第三方串口显示屏或打印机。这类第三方设备很多只支持 RS-232 串口而且协议并不标准厂家往往只留下一句话“你就把字符按无协议发过来我这边直接显示。”这句话听起来简单实际动手时却踩了不少坑。NJ501 属于欧姆龙 NJ 系列机器自动化控制器它的编程环境和老款 CP1H/CJ2M 有很大区别。很多从 CX-Programmer 转过来的工程师第一次在 Sysmac Studio 里找串口发送指令时都会愣住熟悉的 TXD、RXD、MOV 到哪儿去了为什么“发送”变成了一个功能块本文就是基于视频讲解内容整理的文字版围绕“欧姆龙 NJ501 实现无协议串口通信发送”这个主题从概念、硬件配置、Sysmac Studio 设置、ST 语言代码到串口调试助手验证完整走一遍发送流程。新手可以根据文章搭建出第一个能收发字节的 NJ501 串口工程老工程师也可以直接跳到第 4 节看指令调用逻辑和第 6 节排错清单。1. 无协议串口通信是什么1.1 什么是“无协议”通信串口通信底层只有两件事发送方把字节放到 TX 引脚接收方从 RX 引脚读字节。至于字节怎么分组、哪些是地址、哪些是功能码、哪些是校验这些是“协议”层要处理的问题。常见的 Modbus RTU、HostLink、自由协议等都属于协议通信。通信双方必须按照协议规定组装报文例如 Modbus 报文一般是“从站地址 功能码 数据 CRC”PLC 侧的通信功能块会帮你自动打包和解析。而无协议通信英文常写作 No Protocol 或 Non-protocol指的是串口工作在一种“透明传输”模式PLC 应用程序往发送缓存区里放什么字节串口就发送什么字节接收时收到什么字节就原样放到接收缓存区里。PLC 不添加任何协议帧头、地址、校验码。这样做的好处是灵活几乎能对接任何写串口指令的设备坏处是应用层的数据帧格式需要你自己设计。比如对方设备要求“以回车换行结束一条指令”那你的 PLC 报文里就必须自己在末尾加上 CR LF否则设备不知道一条数据什么时候结束。1.2 常见应用场景无协议串口通信发送的典型场景有向串口显示屏发送状态文本比如“设备运行中”“报警过载”向标签打印机发送打印内容向称重仪表发送读取命令向第三方工控板发送触发信号或参数向老式单片机设备发送一串十六进制指令。接收场景则常见于扫码枪、读码器、串口传感器等。本文重点说“发送”但是理解发送之后接收只是换一个方向思路是相近的。1.3 CP1H/CJ2M 与 NJ501 的编程差异在讲解 NJ501 之前有必要先回应一个高频问题因为很多用欧姆龙 PLC 的人是从 CP1H 或 CJ2M 转过来的搜索时经常会问“欧姆龙 CP1H 中 MOV 指令前面加什么东西”“欧姆龙 LEN 指令怎么用”。先说结论在 CP1H/CJ2M 这类传统 PLC 里MOV 指令本身不能直接发送串口数据。常见的做法是先用 MOV 把待发送的数据移动到数据寄存器 D 区比如把#1234移动到D200然后再调用 TXD 指令由 TXD 把 D 区里的数据通过串口发送出去。如果视频里有人演示“MOV 前面加条件”通常是为了让 MOV 只在程序启动瞬间执行一次或者只在某个条件满足时刷新数据。而 NJ501 的编程体系完全不同。NJ 系列使用 Sysmac Studio编程语言遵循 IEC 61131-3 标准推荐使用 ST 语言和功能块。它没有传统意义上的“把数据搬到某个寄存器再执行发送指令”这种流程而是把一个串行发送功能块当成一个对象通过执行条件和字节数组参数完成发送。这也是很多老工程师第一次不太适应的原因。本文后面会专门用一个章节对比新旧指令习惯帮助大家快速切换思维。2. 环境准备与通信参数确认2.1 硬件准备NJ501 控制器的串口来源不同有的 CPU 本体自带 RS-232C 串行端口有的则需要通过通信单元或选件板扩展。在做软件配置之前请你先做两件事第一查看手里的 NJ501 具体型号和产品手册确认你的控制器是否有可用的串行端口。第二在 Sysmac Studio 中新建或打开工程后双击“配置和设置”中的“串行端口设置”确认系统能识别到这个串口。如果硬件没有串口又必须使用无协议串口那么就需要在硬件选型阶段加入通信扩展单元而不是后续靠软件解决。接线方面RS-232 串口通常使用三线制交叉接法PLC 的 TX 接对端设备的 RXPLC 的 RX 接对端设备的 TX两端 GND 必须共地。如果使用 DB9 接头调试可以先按“2 收、3 发、5 地”的常见定义连接具体以两端设备手册为准。调试阶段还要注意如果设备支持硬件流控 RTS/CTS而你的线缆没有接流控线那么两边都要把流控关闭否则设备会一直等待握手信号而不发送数据。2.2 Sysmac Studio 软件说明NJ501 的开发软件是 Sysmac Studio。Sysmac Studio 是欧姆龙 NJ/NX 系列的主要编程调试软件支持逻辑编程、运动控制、 EtherCAT 配置、仿真和监控。它属于授权软件需要通过欧姆龙官网或正规授权渠道获取项目中不建议使用来路不明的安装包以免出现组件缺失或版本兼容问题。安装时要注意几点第一Sysmac Studio 与 PLC 固件之间有版本匹配关系。高版本软件通常可以连接低版本固件但工程升级固件后可能无法用旧软件重新打开。第二工程文件本身也有版本概念低版本软件无法打开高版本创建的工程因此团队多人协作时尽量统一版本。第三安装路径尽量避免中文Windows 的防火墙和杀毒软件如果拦截驱动应及时放行欧姆龙相关进程否则仿真或在线连接可能异常。本文示例以视频讲解时使用的 Sysmac Studio 界面为主你本地如果版本不同会发现个别菜单名称或指令图标略有差异但核心逻辑是一致的。遇到界面差异时优先通过软件右上角的帮助菜单搜索对应功能。2.3 通信参数如何确定无协议串口通信和第三方设备能否通信成功关键在通信参数完全一致。你能在设备手册上看到一串参数例如“9600, 8, N, 1”它的完整含义是波特率9600 bps也就是每秒传输 9600 个二进制位数据位8表示每个字节用 8 个数据位表示通常选择 8校验位N即无校验停止位1表示每个字节传输结束后有 1 个停止位。“9600 8 N 1”是很多串口设备的出厂默认值但不是所有设备都如此。比如有些仪表默认是“9600 8 E 1”E 代表偶校验 Even。如果校验位不同即使波特率完全相同收到的数据也可能出现乱码或丢字节。所以在开始写 PLC 程序之前应该先用电脑串口调试助手与目标设备做一次通信测试把目标设备的参数确认下来。不要贸然认为“所有设备都默认 9600 N 8 1”。3. 在 Sysmac Studio 中配置无协议串口3.1 新建工程并添加串口设置打开 Sysmac Studio 新建工程选择对应的 NJ501 CPU 后进入工程树。无论你使用的是 NJ301、NJ501 还是 NX 系列串行端口配置入口通常都在“配置和设置”下名称类似“串行端口设置”。双击打开串行端口设置后你会看到当前控制器可用的物理串口列表。点击对应串口进入详细设置页。这里需要将通信模式从默认的 Host Link 或其他模式改成无协议也就是 No Protocol 或“无协议”模式。这一步很容易被忽略因为 Sysmac Studio 默认可能启用 Host Link而 Host Link 是欧姆龙专用的上位机链接协议并不适合直接对接第三方串口显示屏等设备。修改模式后把 2.3 节确认好的波特率、数据位、停止位、校验位分别填入。这里再强调一次参数必须和设备手册保持一致而不是“PLC 想设多少就设多少”。3.2 串口参数设置要点下面以典型的“9600, 8, N, 1”为例列出一个无协议发送常用的参数表方便你在配置时逐项核对参数项推荐设置说明通信模式无协议不使用 Host Link / Modbus 协议栈波特率9600按从站设备手册设置常见还有 4800 / 19200 / 115200数据位8大多数设备使用 8 位数据停止位1常见为 1少数设备使用 2校验位None无校验时更简单有校验按设备要求选 Even/Odd流控不使用三线制接线时务必关闭流控如果你的项目对传输速度有一定要求而设备又支持更高的波特率建议使用 115200 甚至更高。不过波特率越高对线缆质量和布线距离越敏感。调试时先用设备和 PLC 都能支持的低速率跑通再根据现场情况提高。3.3 先把 PC 串口调试助手准备好在把 PLC 接到目标设备之前建议先让 PLC 和电脑直连用串口调试助手观察 NJ501 实际发送出来的字节。这样做的好处是你可以先排除 PLC 侧的问题确认字节完全正确后再接第三方设备能省掉大量来回排查的时间。打开串口调试助手后选择对应的 COM 口号把波特率、数据位、停止位、校验位设置成与 PLC 完全相同然后打开串口。如果你的 RS-232 线缆是交叉线PLC 发送的数据会从 PLC 的 TX 引脚进入电脑串口的 RX 引脚调试助手就能收到。为了让发送内容可读性更强可以在调试助手里同时开启“文本显示”和“十六进制显示”或者直接使用十六进制显示来核对每一个字节。4. 无协议串口发送的核心指令与编程思路4.1 明确“发送内容”本质上是一串字节无协议串口发送的数据本质上是一个字节数组。比如你想发送字符串GOOD表面上这是 4 个字符底层其实是 4 个字节G对应十六进制0x47O对应十六进制0x4FO对应十六进制0x4FD对应十六进制0x44如果还想在字符串末尾加回车换行让显示屏知道“这条消息结束了”那么还要追加回车 CR 对应0x0D换行 LF 对应0x0A所以GOOD\r\n完整字节序列就是47 4F 4F 44 0D 0A同样地如果你要发送的是十六进制指令比如某仪表要求发送01 03 00 00 00 01那你就把这 6 个字节放到数组中再交给发送功能块。无协议模式下 PLC 不会替你加帧头帧尾你数组里有什么线上就发什么。4.2 在 NJ501 ST 语言中如何组织数据在 Sysmac Studio 的 ST 语言中推荐先定义发送缓冲区。例如(* 程序全局变量或局部变量 *) VAR abySendData : ARRAY[0..255] OF BYTE; (* 发送缓冲区 *) iSendSize : INT; (* 实际发送长度 *) END_VAR这个缓冲区可以反复使用。每次发送前把本次要发送的字节填入数组前 N 个元素并设置iSendSize为实际长度然后触发一次发送功能块。在 NJ 这种以功能块为单位的设计中“串口发送”被封装成一个系统功能块。在 Sysmac Studio 指令搜索框中输入关键词“Serial”或“串行发送”就能看到相关指令。不同软件版本下指令显示名称会有差异但结构上通常都有执行条件、发送数据、发送字节数、完成标志、错误标志等引脚。下面代码只展示核心调用逻辑方便理解实际组态时要先插入对应功能块实例并对照软件帮助中的引脚名称连线。(* ST 调用示意 不同 Sysmac Studio 版本的串行发送功能块名称和引脚可能不同 正式编程时请以你安装版本自带的指令帮助为准。 *) fbSerialSend_inst( Execute : bSendExecute, (* 上升沿有效 *) SendData : abySendData, (* 发送缓冲数组 *) SendSize : iSendSize, (* 本次要发送的字节数 *) Done bSendDone, (* 完成标志 *) Busy bSendBusy, (* 发送中标志 *) Error bSendError, (* 错误标志 *) ErrorID wSendErrorID (* 错误代码 *) ); IF bSendDone OR bSendError THEN bSendExecute : FALSE; (* 发送结束撤销执行条件 *) END_IF;很多初次接触 NJ 的工程师会问为什么Execute不能一直为 TRUE这要看功能块的具体设计要求。对于执行型功能块通常要求用脉冲触发而不是持续电平触发。持续为 TRUE 可能导致功能块重复启动或无法正确复位。所以在程序中最好记录触发信号的上升沿发送完成或出错后再把bSendExecute复位。后面实战示例会演示这个写法。4.3 使用梯形图还是 STNJ501 同时支持梯形图和 ST 语言选择哪一种取决于团队习惯和程序复杂度。如果只是简单发送几条固定报文用梯形图拖功能块也能完成任务。在每个扫描周期里调用同一个功能块实例触发条件用上升沿指令发送完成后把执行标志复位逻辑清晰易懂。但如果发送的报文中包含可变数据例如“当前数量12345”需要把整数转换成 ASCII 字符串或者需要做 CRC 校验那么 ST 语言会更顺手。ST 在数组处理、循环、字符串操作方面比梯形图高效得多。本文视频演示也以 ST 为主因为它在工业项目中更具扩展性。4.4 报文末尾的结束符与校验无协议通信不代表“随便发”它只是省略了“协议栈”。接收端仍然需要区分一条完整命令的边界因此工程上通常会制定自己的轻量级报文格式。最简单的做法是帧头固定使用一个特殊字节例如0xAA帧尾使用回车换行 CR LF如果对可靠性要求高再在帧尾前加一个校验字节例如异或校验 XOR。举例来说你定义一条“正常工作状态上报”指令为帧头 0xAA 状态字 0x01 保留 0x00 结束符 0x0D 0x0APLC 程序里就把发送数组依次填写为abySendData[0] : 16#AA; abySendData[1] : 16#01; abySendData[2] : 16#00; abySendData[3] : 16#0D; abySendData[4] : 16#0A; iSendSize : 5;这样接收端哪怕没有协议栈也可以根据帧头和结束符把一条完整的指令切出来。异或校验可以在 PLC 中用循环计算把计算结果填入数组。无协议模式下这些工作全部要由程序员完成这就是它比标准协议“麻烦”的地方。5. 完整实战NJ501 向串口显示屏发送 GOOD/NG 信息5.1 场景说明假设现场有一台 NJ501 控制的装配工位。视觉检测系统检测后给 PLC 一个合格信号PLC 需要把结果通过 RS-232 串口发送给第三方工位显示屏检测合格屏上显示GOOD检测不合格屏上显示NG每次检测结果只发送一次不允许周期重复发送。显示屏厂家要求的就是“无协议直接发 ASCII以回车换行结束”。5.2 定义变量在 Sysmac Studio 全局变量表中可以定义以下变量变量名数据类型用途bVisionOKBOOL视觉检测结果来自外部输入或通信数据bTriggerSendBOOL外部发送触发信号例如检测完成信号bTrigOldBOOL用于记录上一次触发信号状态做上升沿检测bSendExecuteBOOL串行发送功能块的执行条件bSendDoneBOOL发送完成标志bSendBusyBOOL发送中标志bSendErrorBOOL发送错误标志wSendErrorIDWORD发送错误代码abySendDataARRAY[0..9] OF BYTE发送缓冲数组iSendSizeINT实际发送字节数这里把abySendData定义为长度为 10 的数组是为了同时容纳 GOOD 和 NG 两种报文。发送时只发送数组前iSendSize个元素多余字节不发送。5.3 编写 ST 逻辑下面是一段可读性强、适合学习的 ST 示例程序。它演示的是“数据准备 上升沿触发 发送完成复位”的完整闭环// 获取触发信号上升沿 IF bTriggerSend AND NOT bTrigOld THEN // 根据检测结果准备报文 IF bVisionOK THEN // GOOD abySendData[0] : 16#47; // G abySendData[1] : 16#4F; // O abySendData[2] : 16#4F; // O abySendData[3] : 16#44; // D abySendData[4] : 16#0D; // CR abySendData[5] : 16#0A; // LF iSendSize : 6; ELSE // NG abySendData[0] : 16#4E; // N abySendData[1] : 16#47; // G abySendData[2] : 16#0D; // CR abySendData[3] : 16#0A; // LF iSendSize : 4; END_IF; // 数据准备完成触发一次发送 bSendExecute : TRUE; END_IF; // 调用串行发送功能块 fbSerialSend_inst( Execute : bSendExecute, SendData : abySendData, SendSize : iSendSize, Done bSendDone, Busy bSendBusy, Error bSendError, ErrorID wSendErrorID ); // 发送完成或出错后复位执行信号 IF bSendDone OR bSendError THEN bSendExecute : FALSE; bTrigOld : bTriggerSend; END_IF;这段代码有几个细节值得留意。第一bTrigOld的作用是形成边沿检测。只有bTriggerSend从 FALSE 变成 TRUE 的那个扫描周期才会准备报文并把bSendExecute置为 TRUE。这是为了避免同一个触发信号在一次高电平持续期间被反复发送。第二GOOD和NG的长度不一样所以每次发送前都要更新iSendSize。无协议功能块绝大多数都要求显式指定发送长度这个值不能乱填填多了会把数组里的无效字节一起发出去填少了报文会被截断。第三功能块的调用是每次扫描周期都要执行的但内部的发送动作由Execute引脚控制。不要在一个周期的条件分支里面“临时调用”功能块在 NJ 中功能块实例的调用必须在稳定位置通过执行条件控制动作。5.4 用串口调试助手验证将 NJ501 的串口与电脑 USB 转串口连接好后在电脑上打开串口调试助手。设置成与 PLC 一致的参数例如 9600 8 N 1。然后给 PLC 一个触发信号串口调试助手应该收到如下十六进制数据如果检测合格47 4F 4F 44 0D 0A切换到文本显示模式可以看到GOOD如果检测不合格则收到4E 47 0D 0A也就是文本NG。实际项目里第一次调试如果没有收到任何数据不要急着改程序先检查串口调试助手是否选中了正确的 COM 口号再检查 PLC 的串口发送参数是否与调试助手一致最后用万用表或串口监测工具确认 TX、RX 是否接反。串口调试是一个非常依赖“先物理后软件”的排查过程。6. 常见问题与排查思路6.1 高频问题速查表问题现象常见原因解决思路PLC 串口完全没有任何输出串口模式仍然在 Host Link串口参数不一致TX/RX 接反将串口模式改为无协议核对双方参数检查交叉接线电脑收到乱码波特率、数据位、校验位不一致重新核对参数最好逐项对比只发送一次之后必须重启或重新触发才能再次发送功能块执行信号没有复位在 Done 或 Error 后将执行条件置 FALSE发送长度不对设备收到内容不完整iSendSize设置错误确认实际字节长度不要用整个数组长度能发送字符但设备不动作缺少结束符、校验字节或指令格式不对用串口助手抓取报文和设备手册逐字节核对接第三方设备后通信不稳定RS-232 地线没共地、线缆过长、干扰大共地缩短距离使用屏蔽双绞线必要时降低波特率6.2 串口调试中的几个“反直觉”问题第一个容易踩的坑是流控。前面说过三线制接线时不能开 RTS/CTS 硬件流控。有些串口设备默认开启了硬件流控即使你的 PLC 不发送它也会因为等待对方的 CTS 信号而一直不动作。遇到这种情况先把设备端的流控关闭或者把 RTS、CTS 两针也接到对应的调试线上。第二个坑是 COM 口占用。很多工程师第一次调试时串口调试助手已经打开 COM3但 Sysmac Studio 在线监控又占用了同一条 USB 转串口。结果程序下载和串口助手无法同时工作。建议调试时准备两条独立串口通道一条用于 Sysmac Studio 在线监控一条用于与目标设备通信。或者先下载程序断开编程线之后再用串口助手测试。第三个坑是“字符串中间的空格”。有的第三方设备要求发送纯十六进制指令例如用空格分隔字节其实只是给人看的格式真正的线上数据没有空格。在数组里存放0x01和存放字符1是完全不同的效果前者是字节值 1后者是 ASCII 码 49。报文设计前一定要看清楚设备手册期望的是 ASCII 还是十六进制值。6.3 回应 CP1H 时代的经典问题既然很多读者是从 CP1H/CJ2M 转过来的这里再回应几个视频评论区反复出现的问题。“CP1H 中 MOV 指令前面加什么东西”——如果你在演示视频里看到 MOV 前面有一个常闭触点、上升沿或定时器那不是“MOV 的固定前缀”而是移动数据的条件。MOV 本身只负责把立即数或寄存器值移动到目标地址。串口发送场景里MOV 通常用于把字符常量移动到 D 区为后面的 TXD 指令准备数据。真正触发串口发送的是 TXD 指令不是 MOV。“欧姆龙 LEN 指令是干嘛的”——在传统 C 系列/CJ 系列通信编程中LEN 指令用于计算数据长度常见于 Host Link 报文组包。由于无协议串口通信缺少协议栈帮我们处理长度一些老工程师会手动计算帧长度再填入发送参数。进入 NJ/NX 时代后Sysmac Studio 的串行发送功能块允许你直接指定发送字节数你只需要用变量维护好这个长度通常不再需要像 LEN 指令那样去拼接地址区计算长度。理解了这些区别就会明白 NJ501 的无协议串口编程本质上不是“学一个指令”而是“用变量和功能块重新组织数据流”。7. 工程实践与最佳建议7.1 报文要“配置化”而不是“到处填数”无协议发送的报文中经常有会变化的部分比如数量、温度、批次号。把这些内容和固定报文混合存放时很容易出现魔法数字满天飞的问题。建议在程序中用命名清晰的变量表示报文含义例如iCurCount表示当前数量iDevTemp表示当前温度然后统一由一个报文组装功能块负责格式转换。后续要改协议格式时只改这一处即可不需要全程序搜索 16 进制常量。7.2 用状态机管理发送流程当 PLC 需要发送多条不同的报文或者同一个报文需要等待设备应答时建议不要直接用多个定时器轮询而是建立简单的发送状态机。一个发送流程可以拆成这些状态空闲状态没有发送任务时保持空闲打包状态将当前需要的数据填入发送数组并计算长度发送状态触发串行发送功能块等待完成状态等待 Done 或 Error错误处理状态记录错误代码并复位执行信号回到空闲状态。ST 中可以用CASE语句实现这个状态机也可以把每个状态写成一个独立的功能块。用状态机的好处是任何时刻程序都能明确知道自己“正在做什么”上位机监控时也更容易判断通信卡在了哪一步。7.3 通信任务放在正确的任务周期中NJ501 支持多任务有 Motion Control 任务和逻辑任务。串口通信属于逻辑控制范畴建议放在逻辑主任务中执行不要在 EtherCAT 同步中断任务里调用耗时的通信等待。另外串口通信的接收和发送都有一定时间开销发送