ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PLC对接扫码支付实战:串口通信与Modbus协议全解析

PLC对接扫码支付实战:串口通信与Modbus协议全解析 先从一个真实场景说起。做自助售货机、共享洗衣房、充电桩或者无人值守道闸的朋友应该都遇到过这个需求设备已经用PLC控制得好好的电机、继电器、传感器都跑了几年了突然提了一个需求——用户扫码付款之后设备要自动启动。之前无非是投币器、刷卡器接几个IO口逻辑简单直接。现在来了个扫码支付问题就来了这东西跟PLC怎么通信它既不是干接点也不是模拟量而是要“对话”的——发指令、收状态、解析数据。我前前后后做过好几个这样的项目从最初一头雾水到后来比较熟练核心就一句话扫码支付设备本质就是一个“带串口的小电脑”PLC跟它沟通要么直接走串口收发要么走标准Modbus协议。这篇文章就把串口和Modbus这两条路怎么走、怎么踩坑、怎么把项目落地全部拆开聊透。1. 整体方案设计先把“支付盒子”和PLC之间怎么对话想清楚1.1 为什么扫码支付能跟PLC对接很多人一听“扫码支付”就紧张以为要碰小程序、微信支付宝开放平台、服务器支付回调之类的东西。确实一个完整的产品扫码支付背后要经过云端、支付网关、商家平台但这些跟PLC工程师没关系。实际落到设备端的是一个叫“支付盒子”或“扫码支付模组”的硬件。用户手机扫盒子上的二维码钱进了你的商户账户盒子自己完成跟支付平台的通信然后把“支付成功”这个结果用串口或网口吐出来。PLC要做的就是跟这个盒子对话拿到“成功”信号再去驱动电机、气缸、继电器之类的执行机构。想清楚这层关系方案就简单了。PLC面对扫码盒子不是面对支付宝而是面对一个“串口从站”设备两种典型模式模式一串口透明传输。PLC给盒子发查询指令盒子返回支付状态字符串或十六进制报文PLC自己解析。模式二Modbus通信。盒子当从站PLC当主站PLC直接读写盒子保持寄存器里的状态字就像读写一个普通Modbus仪表一样。选哪种主要看你手头的PLC型号、编程习惯以及盒子的协议支持情况。我自己的经验是如果能选Modbus优先走Modbus因为PLC侧有成熟的Modbus指令库不用自己写复杂的串口解析逻辑可靠性也高。但有些便宜的扫码盒子只提供“透传指令协议”那就只能走模式一串口自己收自己解析。1.2 硬件链路选型RS485是绕不开的真香选择扫码盒子常见的通信接口有RS232、TTL串口、RS485和网口。PLC这边真正方便的一般是RS485尤其是支持Modbus RTU的PLC基本都标配RS485口。RS485是半双工、差分的抗干扰能力强线可以拉到几百米工业现场最稳妥。两种典型的硬件链路链路方案PLC侧扫码盒子侧转换/接线适用场景方案ARS485直连自带RS485口如西门子S7-200 SMART、三菱FX3U加485-BD板盒子支持RS485A-A、B-B、GND-GND手拉手标准工业场景推荐首选方案BRS232转485只有RS232口或编程口盒子支持RS485加一个无源或有源RS232转RS485转换器老旧PLC改造、临时联调这里有第一个容易踩的坑RS485的A/B线不同厂家标注不一致有的标A、B-有的标D、D-还有的标T/R。接线之前必须查两端设备的说明书确认A对A、B对B。我遇到过因为标签差异导致A/B接反结果通信时通时不通的尴尬。1.3 为什么说Modbus是工业对接的“通用语言”Modbus协议是Modicon现在的施耐德电气1979年推出的串行通信协议现在基本是工业自动化设备的事实标准。你拿一个PLC去对接任何Modbus设备变频器、仪表、温控器、扫码盒子思路完全一样。我特别推荐在扫码支付对接里用Modbus有三个原因PLC侧指令成熟西门子有Modbus RTU主站库三菱用RS指令配合帧格式实现信捷、汇川、台达这些国产PLC基本都封装好了Modbus指令。数据含义清楚不用在字符串里找关键字读一个“寄存器地址”就能得到支付状态、订单号、金额出问题好排查。在线监控容易用Modbus Poll这类测试工具模拟主站直接和扫码盒子通信盒子有没有回数据、数据对不对不用PLC参与就能测出来。后面我建议的联调路径就是电脑串口助手先把盒子调通 → 再用Modbus Poll把寄存器含义摸清 → 最后才轮到PLC上场。2. 通信参数和报文结构串口与Modbus的底层细节2.1 串口参数必须先对齐波特率、数据位、校验位、停止位串口通信最麻烦但最基础的就是参数对齐。扫码盒子和PLC通信两端必须设置一致的波特率、数据位、校验位和停止位参数错一个都收不到数据。最常见的一组参数是波特率9600、数据位8、无校验N、停止位1简写为9600 8N1。也有用19200的具体以扫码盒子说明书为准。确认参数有两个办法看说明书很多盒子的波特率是通过拨码开关或配置软件设置的。用电脑串口调试助手“盲扫”一次性把常用波特率都试一遍看哪个能收到盒子主动上报的数据。第二个办法在实际联调中特别好用。我的习惯是第一次拿到盒子先把TXD、RXD、GND接一个USB转TTL或RS485转USB打开串口调试助手不主动发任何数据先看盒子是否有主动上发很多支付盒子扫码成功后会主动上报一条结果。如果有直接能从报文里反推出参数。这里也建议准备一个“USB转RS485”的调试工具我第一次做的时候只带了USB转TTL结果商家的盒子是RS485接口导致现场没法直接电脑调试。2.2 Modbus RTU报文结构用一条真实报文看懂数据交换Modbus RTU的报文非常简洁一条完整的报文由四部分组成从站地址1字节、功能码1字节、数据区N字节、CRC校验2字节低字节在前。以“读扫码盒子状态寄存器”为例PLC作为主站发送的请求报文可能是01 03 00 10 00 02 C5 CF拆开看01——从站地址即扫码盒子的Modbus地址通常可配置为1。03——功能码读保持寄存器。00 10——起始寄存器地址即0x0010十进制16。00 02——读取的寄存器数量即连续读2个寄存器。C5 CF——CRC16校验码。扫码盒子正常应答01 03 04 00 00 00 01 79 94拆开看01——从站地址。03——功能码。04——数据字节数4个字节。00 00——寄存器16的内容比如“支付状态字”。00 01——寄存器17的内容比如“交易结果码”0x0001可能代表交易成功。79 94——CRC。拿到这条报文PLC就知道扫码支付成功了然后去执行对应的动作。整个数据交换过程就这么朴素。2.3 CRC16校验必须理解但不用手算的环节Modbus RTU的每个报文末尾都带两个字节的CRC校验。CRC的作用是防止通信错误接收方收到报文后会自己算一遍CRC跟报文末尾的CRC对比不一致就丢弃。CRC不对最常见的原因是波特率设置错误、线路干扰、从站地址错误。计算方法是CRC16多项式0xA001初始值0xFFFF逐字节异或移位低位在前发送。写程序的时候可以直接抄标准算法不需要手算。但在联调阶段你最好会用串口调试助手自带的CRC计算功能或者网上的CRC在线计算工具。你要能手动构造一条报文这样才能排查“我发的命令格式对不对”这类问题。另外强调一个细节CRC校验错误不代表硬件坏先检查主站请求报文是不是对的。我至少有两次排查很久最后发现是报文里寄存器数量写错了CRC就变了盒子当然不响应。2.4 寄存器映射解析理解支付盒子地址表不同厂家的扫码盒子寄存器地址表略有不同但一般都包含以下几类寄存器地址举例名称说明0x0000设备型号/固件版本只读用于确认设备在线0x0010支付状态字0无交易/空闲1支付中2支付成功3失败/取消0x0011交易结果码0无1成功已扣款2用户取消3超时4余额不足等0x0012订单金额单位通常为分读出来如果是100代表1元0x0020启动扫码指令写1可以触发扫码器进入扫码模式启动后置00x0030订单号多为ASCII码字符串需要用字符串读取我做的第一个项目里盒子说明书写得极简只有一句话“状态寄存器0x100x11”。商家也没有把完整地址表发出来好在用Modbus Poll把寄存器从0x0000到0x003F扫了一遍逐个看变化才把地址表摸清楚。所以不管说明书多简陋手里有个Modbus Poll心里就有底。3. PLC侧工程实现三菱和西门子的不同打开方式3.1 三菱FX系列PLC用RS指令实现串口收发三菱FX3U/FX5U系列做串口通信最常用的是RS指令。RS指令的优点是指针自由收发缓冲区自己定义适合对接这种自定义协议或标准Modbus RTU。RS指令的基本格式RS D10 D20 D30 D40各部分的含义是D10发送数据起始地址寄存器编号D20发送数据长度要和实际发送字节数一致D30接收数据存储起始地址D40接收缓冲区长度接收最多能存多少字节使用前要通过特殊数据寄存器D8120设置通信格式波特率、数据位、校验位、停止位。比如8位数据、无校验、1位停止位、9600波特率的配置通常在D8120里填十六进制值。代码初始化时写一次即可。然后通过M8122发送请求M8123接收完成标志。一个简化的三菱PLC处理流程初始化 - 设置D8120通信格式 - 设置RS指令缓冲区 触发扫码 - 置位启动扫码寄存器例如把“启动扫码”指令写到发送缓冲区 - 置位M8122发送 - 当M8123置位时接收完成 - 解析接收缓冲区数据重点RS指令的发送长度必须实时修改。发完启动指令后要把长度改短否则之后只做接收时会把前面的旧数据重复发出去。这个坑我踩过一次现象就是盒子每隔一段时间收到一条废指令。3.2 西门子S7-200 SMART / S7-1200使用Modbus指令库西门子S7-200 SMART自带Modbus RTU主站库用起来比三菱RS指令更省心。指令里只需要配置从站地址、功能码、读写起始地址、数据长度和数据指针。S7-200 SMART的Modbus主站库典型调用MBUS_CTRL初始化主站 - Mode1使能Modbus - Baud9600 - Parity0无校验 - Timeout1000毫秒 MBUS_MSG执行单次读写 - Slave1从站地址 - RW0读或1写 - Addr40016对应协议中的保持寄存器地址0x0010 - Count2读两个寄存器 - DataPtrVB100数据存储指针S7-1200则使用MB_COMM_LOAD和MB_MASTER指令块原理一模一样只是块接口不同。用西门子库的好处是错误码很完整如果通信失败直接看MBUS_MSG的Error管脚值再去查手册基本能定位是超时、CRC错误、从站无响应还是地址越界。3.3 支付业务状态机从“扫码成功”到“设备动作”的完整逻辑硬件通信解决的是“数据通了”但真正让项目稳定运行的是PLC里的业务逻辑。我的经验是支付对接的PLC程序要设计成一个简单的状态机空闲状态设备待机显示器显示二维码。此时PLC周期读取支付状态寄存器判断是否从“无交易”变为“支付中”。等待扫码状态收到“支付中”状态后PLC可以启动一个超时计时器比如60秒超时未收到成功则回到空闲。支付成功状态收到“支付成功”结果后PLC立即置位执行机构如启动电机、打开电磁锁同时保存订单号便于追溯。结束复位状态执行完成后向盒子发送“确认完成”指令或写入寄存器清除当前订单盒子回到待机PLC回到空闲。状态机的核心好处是避免“重复发货”如果没有状态管理当PLC读到一次“成功”就执行一次动作而某些盒子会重复上报已保存的支付结果PLC上电重启后还会重放上一次状态这会导致设备没有支付就自动启动。正确的做法是执行完动作后必须向盒子写一个“已处理”标志或者读取到一个新的订单号才认为是一次新的支付。3.4 超时重试和异常保护不能省的三道防线支付对接最怕什么不是通信失败是设备中途“卡在半路上”用户钱扣了但设备没动作。我通常加三道防线发送重试Modbus请求发送后超过预设时间如500ms没收到应答重发3次。3次都失败则报警并显示“通信故障”。业务超时用户扫了码但没完成支付盒子会一直卡在“支付中”。PLC必须设一个最长支付等待时间一般60~90秒超时则复位让下一位用户继续。掉电恢复如果设备在“已扣款但未出货”阶段掉电重启PLC会重新读取盒子最近的交易记录寄存器若检测到“上一笔已成功但未确认完成”则自动恢复执行相应动作。这三道防线缺一不可。尤其第三点如果没有做用户付了钱设备断电又上电订单就丢了用户投诉和退款会让你焦头烂额。4. 联调实战从Modbus Poll到PLC全链路排障4.1 电脑直接连扫码盒子先摆脱PLC单独验证盒子我坚持联调的第一步永远是用电脑串口工具直连扫码盒子不经过PLC。操作流程准备一个USB转RS485接线转换器的A接盒子AB接盒子BGND接GND无GND就悬空试一下。电脑安装CH340或FTDI驱动打开设备管理器确认COM口号。打开Modbus Poll配置从站地址、功能码、寄存器地址、数量、波特率、校验位。点连接如果盒子正常能读到一组寄存器值。请商家在后台把支付金额设为0.01元用手机扫一次码观察Modbus Poll里状态寄存器的变化。这一步能确定的结论有盒子本身的Modbus通信是否正常。寄存器地址表是否和说明书一致。实际支付流程下状态字和结果码是怎么变的。盒子回复是实时还是轮询延迟。做过这一步后面PLC联调就只是“把电脑换成PLC”而已心理压力小很多。我遇到过一位客户项目现场一上来就PLC接盒子通信不上排查到半夜最后用电脑串口一测是盒子地址设置成了0根本不是2跟PLC一毛钱关系都没有。4.2 串口数据不透明用串口调试助手抓底层报文Modbus Poll只能懂Modbus协议但真正测试时我建议在PLC和盒子之间临时串一个RS485转USB的“监听口”用串口调试助手把所有报文抓下来。这样做的好处是能看到PLC实际发出去的报文内容。能看到盒子实际应答的报文内容。能准确判断CRC校验错误是发生在请求端还是应答端。能确认RS485总线上的信号质量有没有乱码。当然这种接线方式要小心A/B极性而且监听设备要接在主从链路中才能看到全部报文。抓到的报文跟Modbus协议对照哪里不对劲一目了然。4.3 常见问题排查表直接抄作业现象排查思路解决方法PLC收不到任何数据接线极性、波特率、从站地址先用电脑串口直连验证通信参数数据乱码波特率不一致或校验位不一致统一9600/8/N/1用串口助手观察Modbus Poll连不上从站地址错误、USB转RS485线序、盒子未上电查看盒子配置软件确认地址能读数但读出来的值不变寄存器地址不对或盒子处于待机模式扫描寄存器区段确认实际地址CRC校验错误请求帧格式有误对比标准Modbus格式逐个字节核对PLC偶尔收不到接线距离过远、RS485未接地、未加终端电阻检查屏蔽层接线必要时加120Ω终端电阻支付成功后状态字马上被清零盒子设计为主站读后清除需要轮询频率配合修改轮询间隔或改用订单号判断PLC重启后误动作收到历史订单回放增加“已处理”标记或订单号变化判断这张表是我这几年做串口对接项目的高频问题集合。每次现场去之前我都会让客户按顺序先自查一遍大概能过滤掉80%的“假故障”。4.4 关于终端电阻和屏蔽地线的两个实操建议Modbus RTU在短距离几十米内点对点通信时不接终端电阻通常也能工作。但在工业现场尤其是配电柜里有变频器、电机、开关电源这些干扰源时建议在RS485总线两端各并一个120Ω终端电阻降低信号反射。屏蔽双绞线的屏蔽层单端接地或通过电容接地不要两端同时接大地否则会形成地环路反而引入干扰。市面上很多现成的“RS485集线器”或“隔离器”如果设备之间的地电位差异大一定要加隔离否则可能烧坏串口芯片。我烧过一个扫码盒子的串口就是因为现场地和PLC的地不是同一电位。4.5 支付状态查询频率轮询间隔的选择PLC对扫码盒子的轮询频率直接影响体验和设备寿命。轮询太慢用户支付成功到设备启动间隔太长体验差轮询太快盒子应答不过来还可能被认为是恶意请求导致盒子死机。我常用的频率是200ms一次。这个间隔足够让“支付成功”在1秒内被发现同时不会给盒子和PLC带来负担。测试过有些杂牌盒子轮询频率低于100ms会偶尔无响应所以200ms是一个安全值。如果对实时性要求高可以改成“盒子主动上报PLC中断接收”模式盒子在支付成功时主动推一条数据PLC串口接收中断置位PLC程序立刻去处理。这种方式快但程序逻辑复杂一点适合对用户体验要求较高的场景。5. 工程交付的一些额外提醒5.1 文档和协议版本管理现场之魂扫码支付盒子是消费电子类产品厂商会经常更新固件、改协议。我遇到过合作商家的盒子默认固件版本和说明书不一致寄存器地址表完全对不上最后是找厂家要了最新的Modbus协议文档才搞定。建议验收项目时把这个盒子固件版本号、协议版本号写进交付文档下次维护不会一脸懵。5.2 防雷和浪涌保护如果扫码盒子装在户外例如充电桩、无人售货机RS485线缆暴露在户外建议加装RS485浪涌保护器或者选带隔离的RS485接口的盒子。雷雨天感应雷会把串口芯片打穿没有保护就只能连盒子带PLC一起返修。5.3 支付状态展示与人机交互很多PLC带触摸屏在HMI上显示“扫码中”“支付成功”“设备启动”这些状态会让用户和运维人员都舒服很多。实现起来不难把PLC里解析出来的支付状态字直接映射到HMI的动画或文本显示上。注意HMI不要直接读盒子所有数据都通过PLC转发保证数据一致性。HMI上增加一个“手动复位”按钮运维现场处理卡单时会方便很多。5.4 关于PLC程序的可维护性支付对接这种程序涉及串口数据、超时、重试、状态机逻辑比普通梯形图复杂。强烈建议把“串口收发”和“业务状态机”分成不同程序块。以后换一个不同协议的盒子只需要改串口收发块状态机完全不动。我最初把所有逻辑写在一起后来盒子换过一版改程序差点改吐。模块化设计省未来十几倍的时间。6. 串口调试与Modbus工具推荐6.1 串口调试助手怎么用到极致串口调试助手是排查串口问题的必备工具。很多人只会打开串口然后看数据实际上它的正确用法是十六进制显示/发送不要用文本模式Modbus RTU报文本身就是二进制文本模式看不到0x01这种控制字符。定时发送设置100ms或500ms定时发送一条读指令当简易轮询主站用。CRC计算选好CRC16-Modbus算法自动附加CRC发送测试报文。断帧间隔设置如果盒子主动上报长报文把断帧间隔调大避免报文被切碎。我通常的流程先用串口助手手动发一条读状态指令观察盒子是否回应正确数据。能正确回应再交给PLC程序去发。6.2 Modbus Poll主站模拟利器Modbus Poll是调试Modbus从站设备的最佳工具界面简单功能强大。关键用法配置好串口、波特率、从站地址后它可以按设定周期自动轮询。可以同时打开多个窗口监控不同寄存器区。支持直接写单个寄存器用于测试“启动扫码”等写操作。寄存器值变化时观察哪个地址在变就能快速定位状态字。这个东西唯一的问题是专业版收费但试用版足够联调使用。网上也有一些免费的替代品比如ModbusScan但使用便利性略差。我的工具箱里两个都会有。6.3 逻辑分析仪排查硬件信号的终极手段如果串口参数、协议都对但数据还是乱这时候要考虑纯物理链路问题。USB转RS485的信号完整性、线缆品质、干扰情况用示波器或逻辑分析仪看波形就能定位。逻辑分析仪比示波器便宜采样率足够看串口波形了。我印象很深的一次排查PLC和盒子距离只有3米但通信时通时断。用逻辑分析仪一看波特率是对的但波形上有毛刺信号毛刺导致误码。换了一根屏蔽双绞线之后问题彻底消失。现场环境就是如此很多问题不是“理论错”而是“物理差”。7. 最后分享一个踩过多次坑后的个人体会做PLC对接扫码支付项目技术上真的不难——串口通信和Modbus都是很成熟的老技术难的是现场那千奇百怪的干扰、那些说明书语焉不详的盒子、还有那些只顾卖货不管售后的商家。我现在接这类项目的原则是先用电脑把盒子协议摸透再谈PLC编程先解决通信链路再写业务逻辑线上参数尽量让盒子厂商配置好PLC只负责按协议收发和做状态机。很多同行喜欢上来就写程序结果被通信问题拖进去大半天其实最好的方法是按部就班把链路每一级都用工具验证一遍。这个思路不止适用于扫码支付所有串口类对接项目都可以这么干。希望这篇拆解能帮你在自己的项目里少踩几个坑。
返回列表