This is the sixth day of my participation in the More text Challenge. For details, see more text Challenge
The business scenario
Recently, I was working on a project to interact with hardware devices, and the problem I encountered was how to calculate the correct communication instructions
Specific service requirements are as follows:
- Device communication based on Modbus protocol
- It can read the content returned by the device and parse out the data information
plan
Interested brothers can understand the origin of the agreement under Baidu, here no longer repeat
In general, it is the calculation or parsing of data through agreed specifications
Meaning that
Let’s look at an example write: 01 05 00 0B FF 00
Explain the meaning of each location:
- 01: indicates the address of the slave server
- 05: function code
- 00 0B: Register or coil address
- FF 00: data is written
Here’s another read example: 01 03 04 00 26 25 A0
Explain the meaning of each location:
- 01: indicates the address of the slave server
- 03: Function code
- 04: indicates the number of bytes read
- 00 26 25 A0: the value to be read
Through format analysis, we can see that the third and fourth bits are the most important ones, namely functional code. Modbus has the following types:
- 01: Reads the state of one or more coils
- 05: writes to a single coil
- 15: write multiple coils
- 03: Read single or multiple hold registers
- 06: Write a single hold register
- 16: Writes multiple hold registers
Once you know all the functional code, start writing it
To send data
coil
The instructions for the coil are fixed, as in the example mentioned earlier
The start switch coil address is 000B, so our instruction should be: address of slave machine + function code + coil address +FF 00, that is, 01 05 000B FF 00
FF 00 The hexadecimal value is 1. That is, the switch is powered on
Hold register
public class Device {
private static final String SET_DISTANCE_COMMAND = '0110004200020';
private static final int HEX_STEP = 2;
public void setDistance(Integer distance) throws IOException {
String value = Integer.toHexString(Float.floatToIntBits(Float.parseFloat(String.valueOf(distance))));
intlength = value.length() / HEX_STEP; String message = SET_DISTANCE_COMMAND + length + value.toUpperCase(); send(message); }}Copy the code
The general steps are as follows:
- First observe and summarize the instruction prefix, for example
01 10 00 42 00 02 0
In front of,01 00 42 10
Without further ado,00 02
This means that two hold registers have to be written, because the data content is 32 bits, and the last 0 is actually0x
, where x represents the length of the data, for example, the actual data is42 48 00 00
X = 4 - Converts the actual data to a hexadecimal value string
- Figure out the length of the data
- Splicing the command and sending it
Note that the Modbus is transmitted on the big end. That is, if the data is 00 00 20 41, write 41 20 00 00
Receive data
Reading coil state
public class Device {
private static final int POSITION_BEGIN_INDEX = 4;
private static final int POSITION_END_INDEX = 6;
private static final int POSITION_DATA_BEGIN_INDEX = 6;
/** * Read data **@paramRes Returns the value *@returnInteger data */
private Integer readData(String res) {
int length = Integer.parseInt(res.substring(POSITION_BEGIN_INDEX, POSITION_END_INDEX)) * HEX_STEP;
return newBigInteger(res.substring(POSITION_DATA_BEGIN_INDEX, POSITION_DATA_BEGIN_INDEX + length), HEX).intValue() / HEX_MULTIPLE; }}Copy the code
The general steps are as follows:
- Read the length of the returned data
- Read data content based on the length of the data
- Converts hexadecimal data contents to integer types