Modbus: 1. Java使用Modbus读取Slave端数据(TCP)
最近手上接了个Unity3D的项目,这个项目需要和真机联动,和真机联动我们需要通过Modbus协议。所以Modbus这一块的就我来实现,因为项目最好会打包为android的,所以就用java来做,看了下java中还真有不少相关的库,最后决定用Jamod这个库,地址:Jamod
在使用的过程中发现,Jamod再封装某些对象的时候都是单例的,比如说我想在一台电脑上模拟出一个Slave端出来,但是这个库限定了在同一台电脑的同一个程序中只能模拟出一个,如果我想模拟多个就需要弄出多个程序出来,这显然不符合实际情况,所以我重新了这个库里面的大概整个TCP这一块的代码,修改成可以在一个程序中实例化出多个监听器出来并且可以再同一个程序中绑定同一个ip下的多个端口,这样就可以做到再同一个程序中模拟出多个Slave来,
因为这个项目需要再一个程序里面模拟出Slave端和Master端(无语啊), 所以这里会写的比较多,也会写的比较详细,首先会讲如何读取真机设备上的数据。至于有关Modbus协议的问题我这里不做说明,不明白的可以自己去看资料,再我写这个随笔的时候,我还没有收到modbus的真机,所以所有的测试我都是基于模拟器来的,如果到时候有出入我会在修改随笔,下面开始记录,
模拟器我用的是这一组,这个不错提供了Master端和Slave端,地址,可以根据自己的需求下载相关的模拟器,这里先记录读取Slave端数据,所以这里要下载Slave模拟器,
这个软件只有windows版本的,所以我是在虚拟机里面使用的,下载之后,直接安装就行了,这个Slave和Pull端都需要注册码,试用30天,
下面开始介绍Java方面的代码,
因为项目的需要,所以我把这块代码单独出来了,这样可以打包成jar文件,这块代码我放到了github上面,地址:https://github.com/Dn9x/dn-modbus
这里说明下,因为项目的需要和需求,所以我这里处理的比较复杂,但是读取Slave上面数据的代码其实是很简单的,都在ModbusUtil类中,
如果你只是简单的使用,那么你完全只看这一个文件就够了,其他的不用看,因为这里我也是只介绍这些,其他的不说明,
如果你需要读取Slave设备上面的数据,Slave设备上的数据分四种类型,模拟器中是这样的:
我个人的理解就是:
- 可以读写的布尔类型(0x)
- 只能读的布尔类型(1x)
- 只能读的数字类型(3x)
- 可以读写的数字类型(4x)
jamod也提供了操作每种不同类型使用不同的类,这里我列个表
- 可以读写的布尔类型(0x) 请求类:ReadCoilsRequest 响应类:ReadCoilsResponse
- 只能读的布尔类型(1x) 请求类:ReadInputDiscretesRequest 响应类:ReadInputDiscretesResponse
- 只能读的数字类型(3x) 请求类:ReadInputRegistersRequest 响应类:ReadInputRegistersResponse
- 可以读写的数字类型(4x) 请求类:ReadMultipleRegistersRequest 响应类:ReadMultipleRegistersResponse
写入的类都是对应的,但是只有可以写入的才有对应的类,这四个读取的类在使用的时候基本都是一致的,不管哪种再读取的时候三个值一定非常重要,一个是SlaveId, 这里设置的值:
一定要和模拟器上的对应,
如果不对应是会抛异常的。
第二个是每个寄存器对应的地址也一定要对应,这里:
和这里对应
至于程序中制定的ip和端口就比较好处理,ip就用模拟器所在机器的ip就行了,端口默认是502,你也可以修改,jamod也提供了默认端口,
1 Modbus.DEFAULT_PORT;
端口指定:
模拟器方面:
这样就可以读取到模拟器上面的值了,读取的时候,模拟器的连接一定要打开,这样才能读取到值,
因为我的项目中是程序只对应控制器,每个控制器下有很多的寄存器,所以我的模拟器里面就开了很多的寄存器,SlaveId都是3,只是寄存器的地址和类型不同,
如:
设置完成之后,打开模拟器上面的连接,上面红色的"No connection"就会消失了。
我这里记录的有点乱,不过我记录这些都是为了方便我自己随时可以查看,并且主要我还都是看代码方面,如果有不明白的可以随时看代码。