author
Sheng Sheng Hu
Reasons for recommendation
The concept and characteristics of modbus protocol and the arrangement of java implementation have certain reference significance for entry.
Introduction to Modbus Protocol
Modbus is a communication protocol, which is a general language mainly used in electronic controllers. Modbus supports a variety of electrical interfaces, such as RS232, RS485, TCP/IP, etc. Most MODBUS device communication is connected through serial port or TCP/IP.
In general, MODBUS is the Master-slave architecture, that is, the communication node is the Master, and other slave nodes that use Modbus protocol to participate in communication (up to 247, the address range is 1-247, and node 0 is the broadcast address). Each slave device has a unique address. There can only be one Master node on the bus.
Introduction to Modbus register
All data is stored in registers, which can refer to physical registers or a memory area. Modbus divides the register into four parts according to the data type and their reading and writing characteristics, as follows.
Modbus message structure
Introduction to Modbus function code
The function code is composed of 1 byte, so the value range is 1-255. Common function codes are as follows:
01: read coil status
02: read input status
03: read hold register
04: read input register
05: forced single coil
06: Prefabricated single register
15: Forced multi coil
17: Report slave device ID
22: Mask write register
23: read / write register
Modbus TCP message structure
Transmission ID: Transaction Identifier. Occupy 2 bytes. Mark the transmission process of a Modbus query / response, which can be set to 0 and + 1 for each communication; It is generated by the client (master station equipment), and the value is copied when answering.
Protocol Identifier: Protocol Identifier. Occupy 2 bytes. The Modbus protocol is 0x00. Generated by the client and copied when answering.
Byte Length: Length. Occupy 2 bytes. The upper 4 bits are set to 0X00, so the subsequent bytes must be within 256 bytes; The number of subsequent bits of the record; Generated by the client (master station equipment) and regenerated when answering.
Unit Identifier: Unit Identifier. Occupy 1 byte. Used to identify slave devices. Generated by the client and copied when answering.
Device address: the address number of the slave device
CRC verification: used to confirm the integrity and correctness of received messages
Java code implementation
There are many open source modbos toolkits on the Internet, such as modbus4j, jamod, etc. Jamod is selected here, taking Modbus RTU communication as an example
maven depends on the following. At the same time, rxtxcomm jar,rxtxParallel.dll,rxtxSerial.dll three files, used to achieve serial communication
<!-- https://mvnrepository.com/artifact/net.wimpi/jamod --> <dependency> <groupId>net.wimpi</groupId> <artifactId>jamod</artifactId> <version>1.2</version> </dependency>
Create connection with serial port
public class ModBusConnection { public static SerialConnection getSerialConnection() throws Exception { SerialParameters parameters = new SerialParameters(); // Serial port name parameters.setPortName("COM2"); // Baud rate parameters.setBaudRate(9600); // Data bit 8 bits parameters.setDatabits(SerialPort.DATABITS_8); // Stop bit 2 bits parameters.setStopbits(SerialPort.STOPBITS_2); // No parity bit parameters.setParity(SerialPort.PARITY_NONE); // rtu mode, replacing the default ascii mode parameters.setEncoding("rtu"); SerialConnection connection = new SerialConnection(parameters); connection.open(); return connection; } }
Create request fetching tool class
public class ModBusUtil { /** * Read / write boolean type function code 01 * @param connection con * @param param param * @return BitVector */ public static BitVector readCoils(SerialConnection connection, ModBusRequest param) throws Exception { ReadCoilsRequest request = new ReadCoilsRequest(param.getAddressNo(), param.getWordCount()); request.setUnitID(param.getSlaveId()); ReadCoilsResponse response = (ReadCoilsResponse) getResponse(connection, request); return response.getCoils(); } /** * Read only boolean type function code 02 * @param connection con * @param param param * @return BitVector */ public static BitVector readInputDiscretes(SerialConnection connection, ModBusRequest param) throws Exception { ReadInputDiscretesRequest request = new ReadInputDiscretesRequest(param.getAddressNo(), param.getWordCount()); request.setUnitID(param.getSlaveId()); ReadInputDiscretesResponse response = (ReadInputDiscretesResponse) getResponse(connection, request); return response.getDiscretes(); } /** * Reading and writing int type function code 03 * @param connection con * @param param param * @return InputRegister */ public static InputRegister[] readMultipleRegisters(SerialConnection connection, ModBusRequest param) throws Exception { ReadMultipleRegistersRequest request = new ReadMultipleRegistersRequest(param.getAddressNo(), param.getWordCount()); request.setUnitID(param.getSlaveId()); ReadMultipleRegistersResponse response = (ReadMultipleRegistersResponse) getResponse(connection, request); return response.getRegisters(); } /** * Read only int type function code 04 * @param connection con * @param param param * @return InputRegister */ public static InputRegister[] readInputRegisters(SerialConnection connection, ModBusRequest param) throws Exception { // Register address number attribute data quantity ReadInputRegistersRequest request = new ReadInputRegistersRequest(param.getAddressNo(), param.getWordCount()); // Slave device number request.setUnitID(param.getSlaveId()); ReadInputRegistersResponse response = (ReadInputRegistersResponse) getResponse(connection, request); return response.getRegisters(); } /** * Get response * @param connection con * @param request req * @return ModbusResponse */ private static ModbusResponse getResponse(SerialConnection connection, ModbusRequest request) throws Exception { ModbusSerialTransaction transaction = new ModbusSerialTransaction(connection); transaction.setRequest(request); transaction.execute(); return transaction.getResponse(); } }
main method test class
public class SerialPortTest { public static void main(String[] args) throws Exception { SerialConnection connection = ModBusConnection.getSerialConnection(); ModBusRequest param = new ModBusRequest(); // Slave device id number param.setSlaveId(1); // function 01 is used for the register address number. addressNo=0 indicates that the register address is 00001 param.setAddressNo(0); // Number of read data param.setWordCount(1); InputRegister[] registers = ModBusUtil.readInputRegisters(connection, param); for (InputRegister register : registers) { System.out.println(register.getValue()); } connection.close(); } }