分享C#做modbus开发的几个坑

发布时间 2024-01-06 16:06:38作者: 夺命大狒狒

最近接了个私活,给智能开关开发配套软件,需求是控制开关打开和关闭,读取电压、电流等信息,整体思路是很简单的,就是简单的并口收发,但实际开发过程中踩了很多坑,跟大家分享一下

软件界面镇楼


头一次听说modbus这个协议,研究了一下,这个协议是由8个16进制数组成,第一个是设备号,第二个是方法,第三、第四是寄存器地址,第五、第六是数据,第七、第八是校验位

例如这样:01 03 00 34 00 01 C5 C4

设备号就是设备的编号,可以多个设备并口并联,根据设备号向对应的设备发送指令

方法主要用03和06,03读,06写

最大的坑:当执行port.Read的时候,第一次只返回设备号,第二次才会返回一个byte数组,数组的第二个元素开始是数据,有的是两个(文档中单个地址的),有的是四个(文档中带~的,两个地址的,需要分别判断并转换为数据),我之前没发现这个问题,无论怎样都返回只有一个元素01的数组,后来写了个10次循环,看到每次从缓冲区中读出来的结果,才发现这个问题

第一个坑:文档里单位不对,写的是V,好在有破解IC卡的经验,研究了一下返回的16进制数,发现两个拼接在一起是以mV为单位的电压,例如返回00 03 AA 36,就把它们连起来,然后换成10进制就是240182mV,240.182V,电流同理,文档也是错误的,转换后是mA

发送:01 03 00 18 00 02 44 0C
第一次返回:01
第二次返回:03 00 03 AA 36 ……很长一串,只取第二、三、四、五个值

第二个坑,我之前以为直接发送01或04就可以打开、关闭开关,结果不是这么个事,需要向地址02 50中写入01才可以执行打开开关的操作,这个要仔细看文档才能找到

例如打开开关的指令是:01 06 02 50 00 01 49 A3

第三个坑:之前我老怕它失败,用的是08(强制分闸),然后发现执行08以后就不能执行01了,手工推也推不上去,看来这设备安全性还是可以的

附全套代码(为了兼容性没有使用第三方modbus库,全靠手工拼接):
https://url67.ctfile.com/f/22262267-1000041904-beb1aa?p=9963 (访问密码: 9963)