modbus tcp通讯 modbus4j java实现

核心依赖: modbus4j-3.0.4-SNAPSHOT.jar

  • modbus tcp slave

1.获取tcp slave 

 
  1. //springboot项目实现CommandLineRunner类和@Component注解,程序启动时就加载tcp slave

  2. @Component

  3. public class Slave implements CommandLineRunner {

  4. @Override

  5. public void run(String... args) throws Exception {

  6. createSalve();

  7. }

  8.  
  9. private void createSalve() {

  10. //创建modbus工厂

  11. ModbusFactory modbusFactory = new ModbusFactory();

  12. //创建TCP服务端

  13. final ModbusSlaveSet salve = modbusFactory.createTcpSlave(true);

  14. //向过程影像区添加数据

  15. salve.addProcessImage(Register.getModscanProcessImage(1));

  16. //获取寄存器

  17. salve.getProcessImage(1);

  18. try {

  19. salve.start();

  20. } catch (ModbusInitException e) {

  21. e.printStackTrace();

  22. }

  23. }

  24.  
  25. }

 2.创建线圈和寄存器

 
  1. public class Register {

  2. static BasicProcessImage getModscanProcessImage(int slaveId) {

  3. BasicProcessImage processImage = new BasicProcessImage(slaveId);

  4. processImage.setInvalidAddressValue(Short.MIN_VALUE);

  5. //创建可读写开关量

  6. processImage.setCoil(0, true);

  7. processImage.setCoil(1, false);

  8. processImage.setCoil(2, true);

  9. processImage.setCoil(3, false);

  10. processImage.setCoil(4, true);

  11. processImage.setCoil(5, false);

  12. processImage.setCoil(6, true);

  13. processImage.setCoil(7, true);

  14. processImage.setCoil(8, true);

  15. processImage.setCoil(9, true);

  16.  
  17. //创建只读开关量

  18. processImage.setInput(0, false);

  19. processImage.setInput(1, false);

  20. processImage.setInput(2, true);

  21. processImage.setInput(3, false);

  22. processImage.setInput(4, true);

  23. processImage.setInput(5, true);

  24. processImage.setInput(6, true);

  25. processImage.setInput(7, false);

  26. processImage.setInput(8, true);

  27. processImage.setInput(9, true);

  28.  
  29. //创建 保持寄存器

  30. processImage.setHoldingRegister(0, (short) 1);

  31. processImage.setHoldingRegister(1, (short) 10);

  32. processImage.setHoldingRegister(2, (short) 100);

  33. processImage.setHoldingRegister(3, (short) 1000);

  34. processImage.setHoldingRegister(4, (short) 10000);

  35. processImage.setHoldingRegister(5, (short) 10000);

  36. processImage.setHoldingRegister(6, (short) 10000);

  37. processImage.setHoldingRegister(7, (short) 10000);

  38. processImage.setHoldingRegister(8, (short) 10000);

  39. processImage.setHoldingRegister(9, (short) 10000);

  40.  
  41. //创建 只读寄存器

  42. processImage.setInputRegister(0, (short) 10000);

  43. processImage.setInputRegister(1, (short) 1000);

  44. processImage.setInputRegister(2, (short) 100);

  45. processImage.setInputRegister(3, (short) 10);

  46. processImage.setInputRegister(4, (short) 1);

  47. processImage.setInputRegister(5, (short) 1);

  48. processImage.setInputRegister(6, (short) 1);

  49. processImage.setInputRegister(7, (short) 1);

  50. processImage.setInputRegister(8, (short) 1);

  51. processImage.setInputRegister(9, (short) 1);

  52.  
  53. processImage.addListener(new BasicProcessImageListener());

  54. return processImage;

  55. }

  56.  
  57.  
  58. }

3.监听线圈和寄存器

 
  1. public class BasicProcessImageListener implements ProcessImageListener {

  2. @Override

  3. public void coilWrite(int offset, boolean oldValue, boolean newValue) {

  4. System.out.println("Coil at " + offset + " was set from " + oldValue + " to " + newValue);

  5. }

  6.  
  7. @Override

  8. public void holdingRegisterWrite(int offset, short oldValue, short newValue) {

  9. System.out.println("HoldRrgister at " + offset + " was set from " + oldValue + " to " + newValue);

  10. }

  11.  
  12. }

  • modbus tcp master

1.获取tcp master

 
  1. public class TcpMaster {

  2.  
  3. private static ModbusFactory modbusFactory;

  4.  
  5. static {

  6. if (modbusFactory == null) {

  7. modbusFactory = new ModbusFactory();

  8. }

  9. }

  10.  
  11. /**

  12. * 获取master

  13. *

  14. * @return master

  15. */

  16. public static ModbusMaster getMaster() {

  17. IpParameters params = new IpParameters();

  18. params.setHost("localhost");

  19. params.setPort(502);

  20. params.setEncapsulated(true);

  21. ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议

  22. try {

  23. //设置超时时间

  24. master.setTimeout(1000);

  25. //设置重连次数

  26. master.setRetries(3);

  27. //初始化

  28. master.init();

  29. } catch (ModbusInitException e) {

  30. e.printStackTrace();

  31. }

  32. return master;

  33. }

  34. }

 2.读取线圈和寄存器中的数据

 
  1. @Component

  2. public class Modbus4jReadUtils {

  3.  
  4. //获取master

  5. private static ModbusMaster master = TcpMaster.getMaster();

  6.  
  7. /**

  8. * 读(线圈)开关量数据

  9. *

  10. * @param slaveId slaveId

  11. * @param offset 位置

  12. * @return 读取值

  13. */

  14. public boolean[] readCoilStatus(int slaveId, int offset, int numberOfBits)

  15. throws ModbusTransportException, ErrorResponseException, ModbusInitException {

  16.  
  17. ReadCoilsRequest request = new ReadCoilsRequest(slaveId, offset, numberOfBits);

  18. ReadCoilsResponse response = (ReadCoilsResponse) master.send(request);

  19. boolean[] booleans = response.getBooleanData();

  20. return valueRegroup(numberOfBits, booleans);

  21. }

  22.  
  23. /**

  24. * 开关数据 读取外围设备输入的开关量

  25. */

  26. public boolean[] readInputStatus(int slaveId, int offset, int numberOfBits)

  27. throws ModbusTransportException, ErrorResponseException, ModbusInitException {

  28. ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, offset, numberOfBits);

  29. ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);

  30. boolean[] booleans = response.getBooleanData();

  31. return valueRegroup(numberOfBits, booleans);

  32. }

  33.  
  34. /**

  35. * 读取保持寄存器数据

  36. *

  37. * @param slaveId slave Id

  38. * @param offset 位置

  39. */

  40. public short[] readHoldingRegister(int slaveId, int offset, int numberOfBits)

  41. throws ModbusTransportException, ErrorResponseException, ModbusInitException {

  42. ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, offset, numberOfBits);

  43. ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);

  44. return response.getShortData();

  45. }

  46.  
  47. /**

  48. * 读取外围设备输入的数据

  49. *

  50. * @param slaveId slaveId

  51. * @param offset 位置

  52. */

  53. public short[] readInputRegisters(int slaveId, int offset, int numberOfBits)

  54. throws ModbusTransportException, ErrorResponseException, ModbusInitException {

  55.  
  56. ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, offset, numberOfBits);

  57. ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request);

  58. return response.getShortData();

  59. }

  60.  
  61. /**

  62. * 批量读取 可以批量读取不同寄存器中数据

  63. */

  64. public void batchRead() throws ModbusTransportException, ErrorResponseException, ModbusInitException {

  65.  
  66. BatchRead<Integer> batch = new BatchRead<Integer>();

  67. batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.TWO_BYTE_INT_SIGNED));

  68. batch.addLocator(1, BaseLocator.inputStatus(1, 0));

  69. batch.setContiguousRequests(true);

  70. BatchResults<Integer> results = master.send(batch);

  71. System.out.println("batchRead:" + results.getValue(0));

  72. System.out.println("batchRead:" + results.getValue(1));

  73. }

  74.  
  75. private boolean[] valueRegroup(int numberOfBits, boolean[] values) {

  76. boolean[] bs = new boolean[numberOfBits];

  77. int temp = 1;

  78. for (boolean b : values) {

  79. bs[temp - 1] = b;

  80. temp++;

  81. if (temp > numberOfBits)

  82. break;

  83. }

  84. return bs;

  85. }

  86. }

3.向线圈和寄存器中写数据

 
  1. @Component

  2. public class Modbus4jWriteUtils {

  3. // 获取Master

  4. private static ModbusMaster tcpMaster = TcpMaster.getMaster();

  5.  
  6. /**

  7. * 写单个(线圈)开关量数据

  8. *

  9. * @param slaveId slave的ID

  10. * @param writeOffset 位置

  11. * @param writeValue 值

  12. * @return 是否写入成功

  13. */

  14. public boolean writeCoil(int slaveId, int writeOffset, boolean writeValue)

  15. throws ModbusTransportException, ModbusInitException {

  16. // 创建请求

  17. WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);

  18. // 发送请求并获取响应对象

  19. WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);

  20. return !response.isException();

  21. }

  22.  
  23. /**

  24. * 写多个开关量数据(线圈)

  25. *

  26. * @param slaveId slaveId

  27. * @param startOffset 开始位置

  28. * @param bdata 写入的数据

  29. * @return 是否写入成功

  30. */

  31. public boolean writeCoils(int slaveId, int startOffset, boolean[] bdata)

  32. throws ModbusTransportException, ModbusInitException {

  33. // 创建请求

  34. WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata);

  35. // 发送请求并获取响应对象

  36. WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);

  37. return !response.isException();

  38.  
  39. }

  40.  
  41. /***

  42. * 保持寄存器写单个

  43. *

  44. * @param slaveId slaveId

  45. * @param writeOffset 开始位置

  46. * @param writeValue 写入的数据

  47. */

  48. public boolean writeRegister(int slaveId, int writeOffset, short writeValue)

  49. throws ModbusTransportException, ModbusInitException {

  50. // 创建请求对象

  51. WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);

  52. // 发送请求并获取响应对象

  53. WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request);

  54. return !response.isException();

  55.  
  56. }

  57.  
  58. /**

  59. * 保持寄存器写入多个模拟量数据

  60. *

  61. * @param slaveId modbus的slaveID

  62. * @param startOffset 起始位置偏移量值

  63. * @param sdata 写入的数据

  64. * @return 返回是否写入成功

  65. */

  66. public boolean writeRegisters(int slaveId, int startOffset, short[] sdata)

  67. throws ModbusTransportException, ModbusInitException {

  68. // 创建请求对象

  69. WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);

  70. // 发送请求并获取响应对象

  71. WriteRegistersResponse response = (WriteRegistersResponse) tcpMaster.send(request);

  72. return !response.isException();

  73. }

  74.  
  75. /**

  76. * 根据类型写数据(如:写入Float类型的模拟量、Double类型模拟量、整数类型Short、Integer、Long)

  77. *

  78. * @param value 写入值

  79. * @param dataType com.serotonin.modbus4j.code.DataType

  80. */

  81. public void writeHoldingRegister(int slaveId, int offset, Number value, int dataType)

  82. throws ModbusTransportException, ErrorResponseException, ModbusInitException {

  83. // 类型

  84. BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType);

  85. tcpMaster.setValue(locator, value);

  86. }

  87.  
  88. }

猜你喜欢

转载自blog.csdn.net/LRXmrlirixing/article/details/82190302
今日推荐