『7x24小时有问必答』
读不到数据?十有八九是这三样没对上
Modbus RTU 入门,一次讲明白
工控里最常打交道的通信协议,多半就是 Modbus RTU。温控表、电表、变频器、称重仪,随便拉一台出来,说明书后面基本都有它。
它的好处是简单,坏处是简单到很多细节手册里根本不写,全靠你自己踩。线接好了、参数也照着设了,就是读不到数,这种事几乎人人都遇到过。
这篇从零讲一遍,看完你能自己接一台设备、读出数来,也知道读不出来的时候该往哪儿查。
一、它是怎么工作的
Modbus 的规矩很像老师点名。
▲ 主站点名,被点到的才能出声
一根线上挂着好几台设备,其中一台是主站,剩下的都是从站。主站喊一声「2 号,报数」,2 号回一句,其他设备一律闭嘴。主站不喊,谁都不许说话。
所以有两件事是定死的。一是从站永远不会主动上报,你想知道什么,只能主站自己去问。二是同一时刻线上只能有一个人在说话,主站得一台台轮着问,问完这台问下一台。
这也就决定了它的速度上限。挂十台设备、每台读一次要 20 毫秒,转一圈就是 200 毫秒。想做几毫秒级的实时控制,Modbus RTU 不合适,那是 EtherCAT 那类总线的活。但用来读温度、读电量、设个转速,它足够了,而且便宜。
二、一条报文长什么样
抓包软件里看到的那一串十六进制,其实结构很简单。
▲ 一条报文四段:地址、功能码、数据、校验
第一个字节是从站地址,也就是「我要找谁」。范围是 1 到 247,同一根线上不能重号。地址 0 比较特殊,是广播,所有从站都执行但都不回话。
第二个字节是功能码,也就是「我要干什么」。是读还是写,读哪一类数据,全看这一个字节。
中间是数据段,内容随功能码变。读的时候一般是「从第几个开始、要几个」,写的时候就是要写进去的值。
最后两个字节是 CRC 校验,用来判断这条报文有没有传坏。这个不用你算,软件和芯片自动处理。要留意的是它低字节在前,跟前面那些高字节在前的字段刚好反着,自己写代码的时候容易搞错。
还有一个看不见但很重要的东西:帧和帧之间要留一段静默时间,大约 3.5 个字符的长度。设备靠这段安静来判断「上一条说完了」。所以别把两条报文贴太紧发出去,中间不留空隙的话对方会当成一条乱码。
三、数据放在四个抽屉里
一台 Modbus 设备内部,数据是分成四类存的。
▲ 四个抽屉,功能码决定动哪个
上面两个抽屉装的是开关量,一位就是一个开关,非开即关。下面两个装的是数值,一格 16 位,能表示 0 到 65535。
左边两个是可读可写的,右边两个只能读。这个区分是设计上的约定,实际做产品的时候,很多厂家干脆只用保持寄存器一类,把什么都塞进去。
所以真上手的时候,九成情况你只会用到三个功能码:03 读、06 写一个、10 写一片。剩下的知道有这回事就行。
功能码
干什么
一次最多能操作
01
读线圈(开关量,可读可写的那种)
2000 个
02
读离散输入(开关量,只读的那种)
2000 个
03
读保持寄存器(最常用)
125 个
04
读输入寄存器
125 个
05
写一个线圈
1 个
06
写一个保持寄存器
1 个
0F
写一片线圈
1968 个
10
写一片保持寄存器
123 个
  
那个「一次最多能操作多少个」也值得记一下。想一口气读 200 个寄存器是不行的,超过 125 个就得拆成两次读。有些人写程序时没注意这个上限,设备直接回一个错误码,还以为是设备有问题。
四、最坑的那个 1<o:page></o:page>
这一节单独拎出来,因为它坑过的人实在太多了。
▲ 手册上的编号和报文里的编号,差一个 1
设备手册上写「设定温度在 40001」,你在软件里填 40001,读出来是错的,甚至直接报错。正确的填法是 0。
原因是这样:4 开头的那位不是地址的一部分,它只是个标记,表示「这是保持寄存器」。后面那四位才是编号,而且是从 1 开始数的。但报文里实际传的编号是从 0 开始的。所以手册上的 40001 对应报文里的 0,40002 对应 1,永远差这么一个 1。
麻烦的是各家软件处理方式还不一样。有的软件让你直接填 40001,它自己内部换算;有的要你填 0;有的写 4x0001。碰到读出来的数不对、或者整体错位一格,先怀疑这里,改一下试试,比查半天线快多了。
五、三样东西必须对上
回到开头那个问题:接好了读不到数,一般就是这三样里有一样没对上。
●第一样是串口参数。波特率、数据位、校验位、停止位,两边必须一模一样。最常见的是 9600、8 位数据位、无校验、1 位停止位,一般写成 9600-8-N-1。但也有设备默认用偶校验,这时候两边一边 N 一边 E,就永远通不了。这一项不对,你会一个字节都收不到。
●第二样是从站地址。设备上的拨码开关或者菜单里设的那个号,得跟你在软件里填的一致。一根线上有两台设备撞号,症状是数据时对时不对,很难查,接线的时候就得记清楚。
●第三样是寄存器地址。也就是上一节说的那个 1。这一项不对的表现是能通信、有回应,但数是错的。<o:page></o:page>
排查的顺序建议倒过来:先看有没有回应。一个字节都收不到,那是第一样或者接线的问题。有回应但数不对,那是第三样。回应时有时无,先怀疑第二样和接线。
六、接到伺服上,能做到什么程度
现在的伺服驱动器,基本都带一个 485 口,跑的就是 Modbus RTU。但拿它来干什么,得分清楚。
▲ 调试配置是主力用法,运行控制只适合单轴慢速
第一种用法是当调试工具,这也是实际用得最多的。伺服面板上就那么几个按键,改一个参数要按半天,几十个参数配下来眼睛都花了。接根线用电脑改,成批改、存成文件、下次换台机器直接灌进去,省事得多。顺带还能把报警记录读出来,查历史故障。
第二种用法是当控制通道,用通信代替端子接线。伺服里一般有个参数选指令来源,改成通信之后,启停、正反转、转速给定就都从寄存器来了,DI 端子那些线可以省掉。读转速、读电流、读位置反馈也是一样。
这种用法适合单轴、动作不快的场合。比如定长送料、卷绕的张力控制、几个固定工位之间来回定位、上位机换个配方。这些活对响应的要求是几十毫秒级的,Modbus 完全应付得来。
什么时候不能用它?多轴要联动的时候。两个轴插补画个圆、龙门双驱同步、电子凸轮跟随,这些要求各轴在同一时刻拿到指令,误差在微秒级。Modbus 是一台台轮着问的,做不到。这种场合就得上 EtherCAT 那类总线。
伺服上的寄存器地址,一般是直接跟参数号对应的。比如某个参数是 P0-08,手册里会给一张表告诉你它对应哪个寄存器。这个对应规则各家自己定,换个品牌就得重新对表。<o:page></o:page>
还有一条很实际的提醒:别在程序里反复写参数。伺服的参数很多是存在 EEPROM 里的,而 EEPROM 的擦写次数是有限的,一般十万次量级。写个几百次没事,但如果你在循环里每秒写一次,一天下来就八万多次,几天就把这块芯片写废了。很多伺服会把参数分成两片地址,一片写了掉电保存,一片只改内存里的值。需要频繁改的量,比如运行中不断变化的速度给定,一定要走只改内存那一片。这条手册里通常会写,但很容易被略过。
七、RS485 那根线怎么接
Modbus RTU 基本都跑在 RS485 上,接线上有几条规矩是硬的。
●两根信号线,一般标 A 和 B,也有标 D+ D- 或者 485+ 485- 的。所有设备的 A 接 A、B 接 B,接反了不通。有些设备接反了也不会烧,改回来就好,但别赌这个。
●必须手拉手串下去,一台接一台。不能像网线那样接成星型,也不能从中间拉个分支出去。短距离低速的时候星型接法有时也能通,但一到现场干扰环境下就开始时好时坏。
●线路两头各接一个 120 欧的电阻。注意是两头,不是每台设备都接。很多设备内部自带这个电阻,用拨码开关或者跳线控制,中间的设备记得关掉。
●用带屏蔽的双绞线,屏蔽层单端接地。两头都接地反而会形成回路,引进干扰。
●别跟动力线捆在一起走。变频器输出那种线尤其要离远点,实在要交叉就垂直交叉,别平行贴着走一长段。
●距离和速度是反着来的。9600 波特率跑一千米没问题,波特率提到 115200,能稳定跑的距离就短很多。现场干扰大的时候,把波特率降下来往往比换线管用。
八、它的长处和短处
讲到这儿,可以回头整体看看这个协议了。<o:page></o:page>
▲ 长处和短处,选型时对着看
长处很好理解。硬件上就是一颗几块钱的 485 收发器,成本几乎可以忽略。生态上几乎没有不支持它的设备,PLC、触摸屏、组态软件、各种仪表,翻开手册后面基本都有 Modbus 这一节。排查也简单,报文是明文的,抓下来对着手册一个字节一个字节看就行,不像有些协议得靠专用工具才能解析。
短处也很明显。最直接的是慢,轮询制决定了设备一多,转一圈就要几百毫秒。其次是从站不能主动说话,设备报警了你得等下一轮问到它才知道,中间这段时间是瞎的。
但最要命的是第三条:寄存器映射没有统一标准。CANopen 有 CiA402 那样的行规,规定好了控制字放哪个编号、状态字放哪个编号,换个厂家的伺服,上层程序基本不用动。Modbus 没有这个东西,每家自己定一套寄存器表。所以换个品牌的设备,通信部分的程序往往要重写一遍。做过多品牌兼容的人都知道这里有多烦。
所以什么时候该用它,其实挺清楚:单轴或者少数几个轴、动作不快、要接的设备杂而多、预算有限,那就用它,省钱省事。需要多轴同步、要毫秒级响应、要设备主动上报故障,那就别硬撑,换总线。
九、还有几个容易忽略的
●读回来的数不对,看看是不是字节顺序问题。一个 32 位的数要占两个寄存器,先放高 16 位还是先放低 16 位,标准里没规定死,各家做法不一样。读出来的数大得离谱或者小得离谱,把两个寄存器调个位置试试。
●带小数的量一般是放大了存的。比如温度 25.6 度,寄存器里存的是 256,你得自己除以 10。手册里会写倍率,别漏看。<o:page></o:page>
●负数用的是补码。读出来 65535 不是六万多,是 -1。软件里数据类型选成有符号整数就正常了。
●从站回一个功能码加 0x80 的报文,那是在报错。比如你发 03 它回 83,后面跟一个错误码,告诉你是地址越界还是数量超限。这个回复是有用信息,别当成乱码丢掉。
●超时时间别设太短。有些设备处理慢,特别是要写 EEPROM 的时候,可能要几十毫秒才回。默认的超时设得太紧,会出现明明设备是好的却老是报超时。
●Modbus TCP 是同一套东西换了个跑法。数据区、功能码、寄存器地址全都一样,只是把串口换成了网线,报文头稍有不同,还去掉了 CRC。会了 RTU,TCP 基本不用重学。
整篇归纳起来就一句:主站问一句从站答一句,问的时候把从站地址、功能码、寄存器地址这三样对上,数就出来了。剩下的都是细节。
下一篇我们接着讲 EtherCAT 从站的落地方案:ESC 专用芯片和 FPGA 到底怎么选、成本和开发周期各是什么量级。欢迎关注我们,一起把这些看着唬人的技术名词一个个拆明白。
工业总线  #ModbusRTU #RS485 #工业通信 #PLC

<o:page></o:page>

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码