ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

欧姆龙NJ501无协议串口接收实战:从硬件配置到ST代码解析

欧姆龙NJ501无协议串口接收实战:从硬件配置到ST代码解析 做自动化项目时很多设备并不支持 Modbus、Profibus 这类标准总线协议而是只提供一个最朴素的串口通电、接线、发一串 ASCII 字符再收一串 ASCII 字符。扫码枪、工业称重仪表、老式传感器、单片机扩展板甚至一些检测仪器基本都是这种通信方式。欧姆龙 NJ501 作为 NJ 系列机器自动化控制器性能强、支持 EtherCAT 和 EtherNet/IP但不少工程师第一次用它去对接串口设备时会发现在 Sysmac Studio 里找不到类似 CJ/CP 系列那种直观的串口发送接收指令网上资料又零散很容易卡在“不知道从哪里开始配置”这一步。这篇文章我围绕 NJ501 做无协议串口通信接收整理一套从硬件准备、Sysmac Studio 工程配置、通信参数设置、ST 语言接收程序到常见问题排查的完整流程适合正在调试扫码枪、仪表数据的电气工程师也适合刚开始学习 NJ/NX 系列 PLC 编程的自动化新人。1. 无协议串口通信的底层概念1.1 什么是无协议串口通信无协议串口通信英文常写作 No-protocol Communication也有资料叫它“自由协议通信”或“原始数据通信”。它不等于“没有通信格式”而是指 PLC 不运行 Modbus、CompoWay/F、Host Link 等现成的应用层协议直接通过串口把原始字节发送出去或接收进来。底层的数据帧格式仍然是标准的 UART 异步串行通信也就是我们常说的起始位、数据位、停止位、校验位这些内容。举个例子一台扫码枪通过 RS-232 接口连接到 PLC扫码成功后扫码枪会主动向外发送一串字符比如STX 0 2 3 4 5 6 7 8 9 ETX CR LF这一串字符没有经过 Modbus 封装也没有 CRC 校验只是一串可读的 ASCII 码。PLC 要做的就是把这串字符完整收下来然后自己判断帧头帧尾、提取有效数据。这种模式非常适合“设备厂商已经定义好透传帧格式”的场景。1.2 NJ501 为什么需要单独学习串口通信很多初学者以前接触过欧姆龙 CP1H、CJ2M 系列习惯在 CX-One / CX-Programmer 里编程里面串口发送、接收指令非常直接比如 RXD、TXD 这类指令。但 NJ501 属于 NJ/NX 系列编程软件是 Sysmac Studio编程语言以 IEC 61131-3 标准的结构化文本 ST、梯形图 LD 为主整个项目组织方式和传统 CJ/CP 系列差别很大。NJ501 的 CPU 本体并不像部分小型 PLC 那样自带标准 RS-232C 接口它通常需要通过欧姆龙官方支持的扩展方式连接串行通信单元例如 CJ 系列串行通信单元具体能不能扩展、支持哪些单元要查阅该型号 NJ501 的硬件手册。一般来说常见的做法是给 NJ501 扩展一块带 RS-232C 或 RS-422A/485 端口的串行通信单元然后在 Sysmac Studio 里添加对应单元把端口配置为无协议模式再用程序读取接收缓冲。因此NJ501 的无协议串口通信并不是“拉两根线就能收发数据”它至少涉及三个环节硬件单元的安装与接线、Sysmac Studio 中单元与端口参数的配置、PLC 程序中接收指令和数据处理逻辑的编写。任何一个环节理解不到位数据都到不了你的业务逻辑里。1.3 典型应用场景无协议串口通信在实际项目里出现频率很高常见的场景有三类第一类是扫码设备数据采集。生产线上的条码扫描器把读取到的二维码或一维码内容通过 RS-232 发送给 PLCPLC 根据条码结果决定产品放行还是拦截。这类设备大多支持自定义输出格式最简单的就是“数据 CRLF”。第二类是仪表数据读取。称重仪表、温控表、流量计等设备通常支持串口输出但很多低端仪表只提供简单的 ASCII 帧并不支持标准 Modbus。PLC 通过无协议接收方式读取仪表主动上报的数据并解析出重量、温度等数值。第三类是 PLC 与单片机、嵌入式设备之间的透传。比如视觉控制器、AGV 调度板、传感器采集板它们往往由嵌入式工程师自定义帧结构PLC 只需要按帧格式收发即可。这种场景下无协议通信是唯一可行的对接方式。掌握 NJ501 无协议串口接收本质上就是掌握“原始字节流的接收、缓存、解析”这一套通用能力。以后无论换成什么串口设备只要帧格式明确都能用同样思路实现。2. 硬件清单与接线准备2.1 一套最小实验硬件在开始写程序前首先要把硬件准备齐。我这里给出一套典型配置你可以根据手头设备灵活调整。硬件说明NJ501 系列 CPU本文示例以 NJ501 系列为对象具体型号以你手上的 CPU 铭牌为准串行通信单元例如欧姆龙 CJ1W-SCU31-V1 等 RS-232C 单元或带 RS-422A/485 的型号按 NJ501 支持的扩展方式接入串口设备可以是扫码枪、仪表也可以是 USB 转串口模块加串口调试助手RS-232C 通信线注意 2、3 脚交叉连接5 脚共地24V 直流电源给 PLC 和串口单元供电Sysmac Studio欧姆龙 NJ/NX 系列编程软件USB 或以太网线用于连接 PLC 进行在线调试这里需要特别强调一下不同型号、不同批次 NJ501 的扩展能力可能有差异串行通信单元的安装位置和连接方式请务必以欧姆龙官方硬件手册为准。视频讲解中我建议把实物图和手册中的扩展配置图放在一起展示避免观众照着一个不确定的接法操作。如果手头没有真实串口设备最方便的做法是准备一个 USB 转 RS-232C 模块在电脑上运行串口调试助手来模拟设备发送数据。这样可以在没有扫码枪、仪表的情况下完整验证 PLC 接收逻辑。2.2 RS-232C 接线中的常见误区RS-232C 是点对点通信最常见的接线方式是 2-3 交叉、3-2 交叉、5-5 直连也就是我们常说的“TX 对 RXRX 对 TXGND 对 GND”。有些设备接口上标注的 DTE、DCE 概念会让新手犯迷糊。简单说PLC 串口和电脑串口通常都按 DTE 设备设计但很多扫码枪、仪表也把自己定义为 DTE当两个 DTE 设备直接相连时就无法通信。稳妥的做法是先查两侧设备的引脚定义用万用表测量确认哪一针是发送、哪一针是接收如果使用成品线缆优先选择交叉线通信不稳定时检查 GND 是否已经共地。2.3 安全与测试注意事项接线和调试过程中要注意安全尤其是生产设备或带隔离的通信端口。请遵循以下原则断电状态下进行接线避免热插拔损坏串口芯片确认 PLC、PC、串口设备的电源地电位一致防止地环流损坏通信端口如果 PLC 串口与被测设备距离较远优先考虑 RS-422A/485而不是 RS-232C所有修改 PLC 通信参数和程序的操作都应该在测试环境或获得授权后进行改动前备份原工程。3. Sysmac Studio 工程新建与单元添加3.1 软件版本说明Sysmac Studio 是欧姆龙 NJ/NX 系列统一的编程软件能够完成 PLC 程序编写、运动控制、视觉、安全等配置。不同版本的 Sysmac Studio 界面布局会有细微差异但基本设计思想一致。如果你是第一次使用建议安装后先做一遍“新建工程、在线连接、下载程序”的最小实验先跑通工具链再进入串口通信调试。本文不指定具体 Sysmac Studio 版本配置路径以常见版本为例。安装软件后如果找不到某些选项可以使用软件右上角的搜索框直接输入“串行通信”“无协议”等关键词。另外补充一句很多初学者会把 Sysmac Studio 和 CX-One 混在一起。CP1H、CJ2M 等传统 PLC 使用 CX-One / CX-Programmer而 NJ501、NX1P2、NX701 等新型控制器使用 Sysmac Studio。两侧的程序结构和指令体系并不完全通用。如果你之前只会 CX-One学习 NJ501 时建议先熟悉 Sysmac Studio 的项目树、变量表和 POU 概念。3.2 新建 NJ501 工程启动 Sysmac Studio 后按照下面步骤新建一个 NJ501 工程。第一步点击“新建工程”输入工程名称和保存路径。第二步选择设备类型。如果使用模拟器就选择模拟器如果连接真实 PLC则需要选择对应的 NJ501 CPU 型号。选择时要注意 CPU 单元版本版本号会影响可用指令和功能。第三步进入主界面后左侧会有一个多级项目树类似下面这样新工程 └─ 配置和设置 ├─ EtherCAT ├─ EtherNet/IP ├─ 串行通信单元 └─ ... └─ 编程 ├─ POUs │ ├─ 程序 │ │ ├─ PRG_MAIN │ │ └─ ... │ └─ 功能块 └─ 全局变量这里“串行通信单元”是否出现取决于你是否已经正确添加了硬件单元以及工程配置中是否启用了 CJ 单元扩展等功能。如果找不到这个节点先回到控制器设置确认外设扩展配置是否正确。3.3 添加串行通信单元在真实硬件上把串行通信单元安装到 NJ501 支持的扩展位置后Sysmac Studio 中通常需要提前在设备配置里添加对应单元程序才能访问该单元的串口。添加单元的通用方法是在项目树的“配置和设置”下找到与单元扩展相关的节点右键选择“添加单元”然后在型号列表中选择你实际安装的串行通信单元型号。需要注意单元型号必须与实物一致否则下载配置时可能报单元编号不匹配单元编号要参考硬件本体上的旋转开关或配置软件的分配结果添加完成后建议先执行一次“核对单元配置”确认软件配置与实际硬件型号、单元号完全对应。在视频讲解中这里值得作为重点演示先把实物串口单元拍清楚再把软件中添加单元的操作录下来两边对照观众就不容易在“单元号对不对”这个问题上卡住。4. 无协议串口通信参数配置4.1 通信端口基本参数添加上串行通信单元后在项目树中找到对应的串口设置页面将通信模式设置为“无协议”也就是 No-protocol然后配置通信参数。常见的参数包括参数示例值说明通信模式无协议不使用 Modbus-RTU不启用 Host Link波特率9600 bps必须与对端设备一致数据位8常用 8 位数据位停止位1 或 2必须与对端设备一致校验方式None / Even / Odd必须与对端设备一致接收缓冲区大小128 或 256 字节根据设备上报帧长度设置这里最核心的一句话是通信参数必须与对端设备完全一致否则连接正常但数据全是乱码甚至完全不能触发接收。不要理所当然认为扫码枪默认就是 9600 8 N 1。很多工业扫码枪出厂是 115200 甚至更高波特率仪表也有各自约定。开始调试前先阅读设备手册用串口调试助手连接一次确认设备正常发送数据再配置 PLC。4.2 接收结束条件与帧格式无协议通信中PLC 必须要知道“一帧数据什么时候结束”。如果 PLC 只知道一直收数据不知道何时该停止程序就很难把连续的数据流分隔成帧。接收结束条件的常见思路有三种第一种是按字节数结束也就是固定帧长。每次接收固定长度字节后认为一帧接收完成适合上位机或控制器发送定长报文的情况。第二种是按结束码结束。当接收缓冲区中出现指定结束码比如 CR LF、ETX、CR 等则认为一帧数据接收完成。第三种是间隔时间结束也就是接收空闲超时。当串口在一段时间内没有收到新字节时认为本次数据帧结束。实际设备中比较常见的是“结束码 超时”组合。以扫码枪为例如果扫码枪配置输出格式为数据内容 CR LF那么 PLC 可以把 CR LF也就是十六进制0D 0A设置为接收结束码。设备每发一帧PLC 收到 0D 0A 就产生一个接收完成事件。程序收到接收完成标志后再从接收缓冲区里取走这一帧数据。有些设备没有固定结束码比如只发一段不定长文本后停止这时要用间隔结束或手动根据业务逻辑判断帧是否结束。4.3 与设备帧格式匹配的配置流程在正式开始程序编写前建议按下列步骤梳理设备帧格式并记录在测试文档中确定数据内容长度范围确定帧头字符例如 STX、冒号、设备地址等确定帧尾字符例如 ETX、CR、CR LF确认校验字段是否启用例如异或校验、LRC 校验确认每次上报是主动发送还是需要 PLC 先发送请求指令。下面用一个扫码枪例子来演示帧头 数据 帧尾 STX(0x02) 0123456789 ETX(0x03) CR LF在这个例子中PLC 接收到的有效条码数据是 ASCII 字符“0123456789”。实际报文里还包含 STX、ETX、回车换行等控制字。如果我们需要在触摸屏上显示条码就需要在程序里去掉帧头帧尾只保留数字内容。这种“去头去尾”的操作看似简单但在帧长度可变时格外考验编程能力后面我会给出完整的 ST 示例。5. 创建全局变量与编写接收程序5.1 变量设计思路无协议串口通信程序可以拆成两部分底层串口接收和上层业务数据处理。底层负责调用 Sysmac Studio 提供的串行通信指令把串口单元收到的原始数据搬运到程序缓冲区上层负责识别帧头帧尾、拷贝有效数据、给出完成标志。我建议在全局变量表中建立下面这些变量变量名数据类型用途SerialPortNoWORD使用的串口端口号1 或 2具体以单元端口为准RX_DataARRAY[0..127] OF BYTE原始接收缓冲区RX_DataLenWORD当前接收到的有效长度RX_DoneBOOL接收完成标志RX_BusyBOOL接收忙标志RX_ErrorBOOL接收错误标志RX_ErrorIDWORD错误代码FrameBufferARRAY[0..127] OF BYTE业务解析缓冲区FrameLenWORD解析后的有效帧长度DataReadyBOOL数据准备完成标志用于通知主程序为什么要建立两套缓冲区原因很简单Sysmac Studio 的底层串口接收指令可能会在很短的扫描周期内被反复触发如果直接把设备字节马上交给业务逻辑可能出现“数据还没收完整程序已经开始处理”的错误。用底层缓冲区和业务缓冲区隔离可以保证数据处理时拿到的是一帧完整数据。5.2 Sysmac Studio 中的串行通信指令关于指令名称需要说明一下不同版本的 Sysmac Studio甚至不同单元类型对无协议串行通信指令的封装可能不完全相同常见做法是通过“串行通信指令”或“Sysmac 库”中的功能块访问单元端口。本文给出的是一种通用调用思路你可以打开 Sysmac Studio 的指令帮助使用 F1 搜索指令名例如 SerialSend、SerialReceive再对照帮助确认参数顺序。在编写代码前打开 Sysmac Studio 的“指令”窗口找到“串行通信”分类把相关指令拖到 ST 编辑器中软件会自动生成完整的调用结构。这是最准确、最不容易出错的用法比自己手工敲函数名要安全很多。下面我以结构化文本 ST 为例写出一种典型的带调用示意。请把它当成“理解逻辑的伪代码”来看具体参数请以软件自动生成后的代码为准// 文件路径POUs / 程序 / PRG_SerialReceive // 功能在无协议模式下从串口单元接收一帧原始数据 SerialReceive( Execute : bExecuteReceive, PortNo : SerialPortNo, ReceiveBuffer : RX_Data, ReceiveSize RX_DataLen, Done RX_Done, Busy RX_Busy, Error RX_Error, ErrorID RX_ErrorID );这里标注的 RX_Done 是“接收完成”标志它由底层指令在满足接收结束条件后置位。下一段程序应该等待 RX_Done 变 TRUE再把 RX_Data 中的数据复制到业务缓冲区。如果你使用的软件版本指令名不相符建议先查看帮助手册中的指令列表。学习视频里可以专门演示“F1 搜索指令”这个方法让观众学会独立查询而不是死记某个函数名。5.3 使用接收完成标志搬运数据当 RX_Done 变成 TRUE说明串口单元已经按我们配置的结束条件收到了一帧数据。此时程序要把 RX_Data 中有效长度的数据复制到 FrameBuffer 中并触发 DataReady 标志。下面是一段 ST 示例// 文件路径POUs / 程序 / PRG_SerialReceive // 功能把底层接收缓冲区的数据复制到业务缓冲区 IF RX_Done THEN // 防止上一帧数据还没被业务逻辑取走就覆盖 IF NOT DataReady THEN // 清空业务缓冲区 FOR i : 0 TO FRAME_SIZE - 1 DO FrameBuffer[i] : 16#00; END_FOR; // 拷贝有效数据注意防止越界 IF RX_DataLen FRAME_SIZE THEN FrameLen : RX_DataLen; FOR i : 0 TO RX_DataLen - 1 DO FrameBuffer[i] : RX_Data[i]; END_FOR; ELSE // 如果数据超过缓冲区可以只取前 FRAME_SIZE 字节 FrameLen : FRAME_SIZE; FOR i : 0 TO FRAME_SIZE - 1 DO FrameBuffer[i] : RX_Data[i]; END_FOR; END_IF; // 通知业务程序新数据已经就绪 DataReady : TRUE; END_IF; END_IF;这段代码里有几个细节值得注意。首先是防止越界。接收缓冲区长度是固定值例如 128 字节如果设备一次发来 200 字节不做长度判断直接复制就会越界访问。因此复制前要与缓冲区大小做比较超出部分可以丢弃或者只保留前半段。其次是 DataReady 锁存。如果上一帧数据还没有被业务逻辑取走新的接收完成事件不应该直接覆盖 FrameBuffer。正确做法是等业务逻辑处理完后把 DataReady 复位为 FALSE然后才能接收下一帧。这种做法有点像“双缓冲”或“握手协议”能避免数据覆盖。5.4 帧解析去掉帧头帧尾提取有效数据很多设备上报的帧包含帧头、帧尾、ASCII 控制字符为了在触摸屏或上位机中显示需要提取出有效业务内容。以 STX 数据 ETX CR LF 为例解析逻辑是先找到 STX 和 ETX 的位置然后取中间部分。下面是一个简单的 ST 解析示例用于把原始帧中两个指定标志之间的数据提取出来// 文件路径POUs / 功能块 / FB_ParseFrame // 功能在 FrameBuffer 中查找包头包尾并提取有效负载 IF DataReady THEN DataReady : FALSE; // 查找帧头 STX 0x02 nHeadIndex : -1; FOR i : 0 TO FrameLen - 1 DO IF FrameBuffer[i] 16#02 THEN nHeadIndex : i; EXIT; END_IF; END_FOR; // 查找帧尾 ETX 0x03 nTailIndex : -1; FOR i : nHeadIndex 1 TO FrameLen - 1 DO IF FrameBuffer[i] 16#03 THEN nTailIndex : i; EXIT; END_IF; END_FOR; // 如果帧头帧尾都存在提取中间数据 IF (nHeadIndex 0) AND (nTailIndex nHeadIndex) THEN PayloadLen : nTailIndex - nHeadIndex - 1; FOR i : 0 TO PayloadLen - 1 DO Payload[i] : FrameBuffer[nHeadIndex 1 i]; END_FOR; ParseOK : TRUE; ELSE ParseOK : FALSE; END_IF; END_IF;这种方式适合数据帧格式简单、固定的情况。如果设备帧中还包含校验、地址码、长度字段则可以把这段逻辑扩展成一个完整的状态机例如“等待帧头—接收长度—接收数据—校验帧尾”。5.5 在 PRG_MAIN 中组织完整调用为了让程序结构清晰建议把“底层接收”和“业务解析”分别放在不同的 POU 里然后在主程序中按顺序调用。比如// 文件路径POUs / 程序 / PRG_MAIN // 功能主程序调用接收和解析逻辑 PRG_SerialReceive(); FB_ParseFrame_Instance(DataReady : DataReady, FrameBuffer : FrameBuffer, FrameLen : FrameLen, Payload : Payload, PayloadLen PayloadLen, ParseOK ParseOK);使用功能块时需要先声明一个功能块实例例如 FB_ParseFrame_Instance。如果不做实例化直接在程序中调用 FB_ParseFrame 这种写法是不能执行的这一点和函数调用不同初学者容易报错。整体数据流可以用下面这个简化流程来描述串口设备发送数据 ↓ 串行通信单元硬件接收 ↓ Sysmac Studio 串口指令接收 ↓ 接收完成标志 RX_Done ↓ 搬运到业务缓冲区 FrameBuffer ↓ 解析帧头帧尾提取 Payload ↓ 更新显示或参与逻辑控制很多项目调试不顺利是因为中间某一步断掉了。比如串口单元收到数据了但 RX_Done 没有变化或者 RX_Done 变化了但 FrameBuffer 很快被下一帧覆盖。沿着这个流程图逐段排查会快很多。6. 完整的扫码枪无协议接收示例6.1 场景描述假设现场有一台扫码枪通过 RS-232C 连接到 NJ501 扩展的串行通信单元。扫码枪参数配置如下项目参数波特率9600数据位8停止位1校验None输出帧格式STX 条码数据 ETX CR LF条码数据变长 ASCII 字符串最长 32 字节当扫码枪扫码成功时PLC 希望能够把条码数据解析出来并置位一个“扫码完成”信号让后续工位知道当前产品条码已经读取成功。6.2 全局变量声明下面是全局变量表中需要声明的变量可以在 Sysmac Studio 的“全局变量”页面直接输入。变量名数据类型初始值注释bExecRecvBOOLFALSE串口接收执行触发wPortNoWORD1串口端口号arrRawDataARRAY[0..127] OF BYTE0底层接收缓冲区wRawLenWORD0底层接收长度bRcvDoneBOOLFALSE底层接收完成bRcvBusyBOOLFALSE底层接收忙bRcvErrorBOOLFALSE底层接收错误wRcvErrorIDWORD0底层接收错误代码arrFrameARRAY[0..127] OF BYTE0业务帧缓冲区wFrameLenWORD0业务帧长度bDataReadyBOOLFALSE帧数据就绪arrPayloadARRAY[0..63] OF BYTE0解析出的条码负载wPayloadLenWORD0条码负载长度bParseOKBOOLFALSE帧解析成功bScanOKBOOLFALSE扫码完成通知后续逻辑iLoopINT0循环变量6.3 主程序 ST 示例下面这段程序把前面几个小节的内容整合到一个精简示例中适合验证整个接收链路的正确性。请注意指令名称和参数以当前 Sysmac Studio 版本自动生成为准// 文件路径POUs / 程序 / PRG_MAIN // 功能NJ501 无协议串口接收完整示例 // 1. 轮询执行底层接收 IF bExecRecv FALSE THEN bExecRecv : TRUE; END_IF; SerialReceive( Execute : bExecRecv, PortNo : wPortNo, ReceiveBuffer : arrRawData, ReceiveSize wRawLen, Done bRcvDone, Busy bRcvBusy, Error bRcvError, ErrorID wRcvErrorID ); // 2. 当底层接收完成并且业务缓冲区空闲时搬运数据 IF bRcvDone AND (NOT bDataReady) THEN bExecRecv : FALSE; // 清空业务帧缓冲区 FOR iLoop : 0 TO 127 DO arrFrame[iLoop] : 16#00; END_FOR; // 拷贝原始数据长度限定在 128 字节以内 IF wRawLen 128 THEN wFrameLen : wRawLen; FOR iLoop : 0 TO wRawLen - 1 DO arrFrame[iLoop] : arrRawData[iLoop]; END_FOR; END_IF; bDataReady : TRUE; END_IF; // 3. 数据就绪后进行帧解析 IF bDataReady THEN bDataReady : FALSE; bScanOK : FALSE; // 查找帧头 STX 0x02 nHeadIdx : -1; FOR iLoop : 0 TO wFrameLen - 1 DO IF arrFrame[iLoop] 16#02 THEN nHeadIdx : iLoop; EXIT; END_IF; END_FOR; // 查找帧尾 ETX 0x03 nTailIdx : -1; FOR iLoop : nHeadIdx 1 TO wFrameLen - 1 DO IF arrFrame[iLoop] 16#03 THEN nTailIdx : iLoop; EXIT; END_IF; END_FOR; // 判断是否为合法帧 IF (nHeadIdx 0) AND (nTailIdx nHeadIdx) THEN wPayloadLen : nTailIdx - nHeadIdx - 1; IF wPayloadLen 64 THEN wPayloadLen : 64; END_IF; FOR iLoop : 0 TO wPayloadLen - 1 DO arrPayload[iLoop] : arrFrame[nHeadIdx 1 iLoop]; END_FOR; bParseOK : TRUE; bScanOK : TRUE; ELSE bParseOK : FALSE; bScanOK : FALSE; END_IF; END_IF;这段程序虽然不长但是已经包含了一个串口接收项目最基本的骨架底层接收、数据搬运、帧解析、完成标志。实际工程项目中我们还需要在这个基础上增加错误处理、超时处理、设备状态监控等逻辑。6.4 在触摸屏或上位机中显示条码条码数据最终通常要显示到触摸屏或传给上位机。由于触摸屏变量一般使用字符串类型而 PLC 里我们存的是 BYTE 数组因此需要一个把 ASCII 数组转成字符串的过程。Sysmac Studio 中可以采用直接赋值的方式也可以写一个小功能块把每个字节转为对应的字符后拼接。最简单的思路是定义一个 STRING 类型的全局变量然后在程序里把 arrPayload 中的每个 BYTE 转为字符后写入字符串。需要注意欧姆龙 STRING 类型和标准 C 语言字符串的差异长度声明要充足。在视频讲解里可以专门演示如何在触摸屏组态软件中建立字符串变量并与 PLC 变量关联。这样观众能看到“扫码枪扫一下屏幕立刻显示条码内容”的完整效果。7. 运行结果验证与视频讲解思路7.1 用串口调试助手模拟扫码枪在没有真实扫码枪的情况下推荐在电脑上使用串口调试助手来模拟。把 USB 转 RS-232C 模块与 PLC 串口连接好打开串口调试助手设置相同的波特率、数据位、停止位、校验位。手动发送测试帧时可以选择 HEX 方式也可以选择 ASCII 方式。例如用 ASCII 方式发送STX 0 1 2 3 4 5 6 7 8 9 ETX CR LF如果你用的是图形化串口助手常常无法直接输入 STX、ETX 这些控制字符这时可以切换为 HEX 格式发送对应数据为02 30 31 32 33 34 35 36 37 38 39 03 0D 0A其中0x30到0x39正好是 ASCII 字符0到9的十六进制编码。7.2 如何判断接收是否成功程序下载并运行后在 Sysmac Studio 中打开“监视”窗口观察下面几个变量的变化发送数据前bRcvDone 应该为 FALSEwRawLen 为 0串口助手发送完一帧后bRcvDone 会变为 TRUEwRawLen 应该是实际收到的字节数如果配置了结束码 CR LF那么这一帧的字节数应该是 14也就是 STX 10 个数字 ETX CR LFwFrameLen 应该与 wRawLen 一致bParseOK 和 bScanOK 会变为 TRUEarrPayload 的前 10 个字节被解析成0x30到0x39。如果 bRcvDone 一直是 FALSE说明底层没有接收到数据优先检查接线、端口号、通信参数。如果 bRcvDone 是 TRUE 但 bParseOK 为 FALSE说明收到数据但是帧格式不匹配需要检查帧头 STX 和帧尾 ETX 是否与设备实际输出一致。7.3 视频讲解的操作顺序建议如果这个项目要拍成视频教程我建议按下面的顺序组织内容观众跟着操作不容易走偏先展示硬件接线图强调串口交叉接法新建工程添加串行通信单元配置端口波特率、数据位、停止位、校验位设置接收结束码解释为什么需要结束码通过串口调试助手发送一帧固定数据演示 PLC 的底层接收编写 ST 接收程序和帧解析程序在线监视变量变化对比发送数据和接收数据模拟异常比如波特率不一致导致的乱码再演示排查过程。这样的顺序符合“先通硬件、再通参数、最后通程序”的调试原则。很多初学者习惯先写程序再调参数结果一上来就是乱码容易丧失信心。视频里建议把“先让 PLC 在串口助手里能看到数据”作为第一个里程碑只要底层通了后面处理只是逻辑问题。8. 无协议串口接收常见问题排查8.1 高频问题对照表我把 NJ501 无协议通信接收最常遇到的问题整理成了表格方便你调试时对照。问题现象常见原因解决思路PLC 始终收不到数据串口接线错误、TX/RX 未交叉检查 2、3 脚是否交叉GND 是否共地数据收到但全是乱码波特率、数据位、校验设置不一致用串口调试助手确认设备实际参数接收完成标志不触发没有正确设置结束码或结束码与设备不一致根据设备帧格式配置 CR、LF、ETX 等结束码数据帧粘连在一起一帧结束后下一帧很快到达程序来不及处理使用 DataReady 握手、双缓冲或空闲超时结束程序运行时报数组越界未对接收长度做边界判断复制前检查长度是否超过缓冲区容量扫码枪扫一次收到多条数据设备输出配置里包含了前缀后缀在设备端关闭不需要的前缀后缀或程序过滤Sysmac Studio 在线连接失败IP 地址冲突、驱动未安装、固件版本过低检查网络参数重新安装对应 USB 驱动串口单元添加后软件识别不了单元型号选择错误或单元号冲突核对硬件型号拨码与软件配置重新上电8.2 排查流程建议遇到“无协议接收不到”问题时我建议按下面顺序排查不要一上来就怀疑程序第一步用万用表确认接线。串口通信线是否接反、是否虚接、是否共地这是最高频的问题。第二步用串口调试助手直连设备确认设备本身在上电后有没有数据发送。很多仪表需要收到请求命令才会上报不是主动发送这时先用 PC 串口助手发送请求看有没有回包。第三步检查 PLC 串口单元端口配置。通信参数、无协议模式、结束码设置是否正确。第四步检查 Sysmac Studio 程序中的端口号。串行通信单元有两个端口时端口号是否选对。第五步用 Sysmac Studio 在线监视底层接收长度和完成标志。如果底层确实没有动作问题大概率在硬件接线或者串口单元配置上如果底层已经完成接收只是解析不对问题在帧解析逻辑上。这几步可以把问题范围逐步缩小到物理层、参数层或程序层避免反复盲改。9. 最佳实践与工程建议9.1 程序结构建议无协议串口接收程序在工程中不建议全部堆在主程序里。更合理的结构是PRG_MAIN主程序负责整体调用PRG_Rcv底层串口接收循环负责调用接收指令FB_ParseFrame功能块负责帧解析FB_ProtocolDeal功能块负责根据设备业务处理数据。这样当以后更换不同品牌扫码枪时只需要修改 FB_ParseFrame 或设备参数不需要改动底层接收。串口接收部分在原理上是通用的设备差异主要体现在帧格式和通信参数上把这两类差异隔离到不同模块里能显著提高代码复用性。9.2 通信参数配置管理生产现场往往会遇到多种设备每台设备都有不同的波特率、帧格式。建议在程序中用结构体把“设备通信参数”封装起来并用系统变量或 HMI 画面上的“配方”功能进行切换。这样设备换型时不需要修改 PLC 程序只要切换配方或写入对应参数即可。例如可以建立一个配置结构体TYPE ST_SerialConfig : STRUCT BaudRate : DWORD; // 波特率 DataBits : WORD; // 数据位 StopBits : WORD; // 停止位 Parity : WORD; // 校验方式 EndCode1 : BYTE; // 结束码1 EndCode2 : BYTE; // 结束码2 END_STRUCT END_TYPESysmac Studio 中很多串口参数采用枚举或数值方式设置实现配方切换时要了解参数编码规则或者通过帮助手册确认。9.3 数据安全与异常处理无协议串口通信对物理链路非常敏感现场干扰可能导致数据中间丢字节或多字节。程序层面至少要做三件事第一帧校验。如果设备没有内置 CRC可以在允许的情况下在设备端增加和校验或 LRC 校验PLC 收到后主动校验避免把错数据直接用于控制。第二接收超时。当程序发出读取请求后如果设备长时间不回复应该在 PLC 里做一个定时器超时后给出报警避免设备无响应时产线一直等待。第三断线判断。生产项目里还需要监控“设备是否在持续通信”。可以统计单位时间内收到的帧数如果长时间没有数据说明通信链路可能断开应该触发报警信息。9.4 从串口调试到设备联调的注意事项从串口助手切换到真实设备时很多工程师会遇到“串口助手上正常一接设备就异常”的情况。常见原因如下USB 转串口模块的电平特性和真实设备不一致带负载能力弱真实设备通信线太长、屏蔽层未接地导致信号质量下降设备默认不是主动上报需要 PLC 先发送握手命令设备内部有通信时序要求两次请求之间需要延时现场其他变频器、电机干扰导致数据帧被破坏。解决思路是尽量缩短通信线长度使用带屏蔽的通信电缆并且把屏蔽层单端接地。对于干扰严重的环境优先使用 RS-422A/485 而不是 RS-232C因为 RS-232C 的抗干扰能力通常较弱。10. 小结与下一步学习建议通过这套流程我把 NJ501 无协议串口通信接收的完整链路拆解了一遍从无协议通信的概念、硬件扩展和接线到 Sysmac Studio 中串行通信单元的添加、端口参数和结束码配置再到 ST 语言里的接收触发、数据搬运、帧解析和在线验证。只要把“物理层通—参数层通—程序层通”这条主线走通哪怕换一套设备调试思路也能直接复用。接下来你可以从几个方向继续深入第一学习 RS-422A/485 无协议收发。RS-485 支持多站点通信但需要在程序中处理收发方向切换和从站地址过滤这和 RS-232C 点对点接收有区别。第二学习 Sysmac Studio 中的数据结构和字符串处理。条码解析、仪表数值转换、UTF-8/ASCII 转换都是串口通信后处理的高频需求。第三多看欧姆龙官方指令手册和示例库。官方网站提供了 NJ/NX 系列程序示例搜索串行通信相关样例比自己摸索效率高得多。在实际项目中请务必把本文提到的帧长度边界、完成标志握手、通信超时处理都加上。串口通信虽然 API 看似简单但真正的可靠性往往体现在边界处理和异常恢复上。如果你正在录制视频讲解可以把“用串口助手模拟设备”和“真实扫码枪联调”分成两集前者讲清原理后者贴近现场这样观众看完既懂逻辑又会排错。
返回列表