package com.ruoyi.web.controller.tool; import com.intelligt.modbus.jlibmodbus.master.ModbusMaster; import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory; import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters; import com.ruoyi.common.core.domain.R; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.net.InetAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Api(tags = "modbus测试") @RestController @RequestMapping("/base") public class ModbusExample { @ApiOperation(value = "抓取700号段寄存器数据") @GetMapping(value = "/test") public R>> test() { // 1. 设置 TCP 参数 TcpParameters tcpParameters = new TcpParameters(); try { // 这里的 IP 保持你之前的配置,端口 502 tcpParameters.setHost(InetAddress.getByName("192.168.40.138")); tcpParameters.setKeepAlive(true); tcpParameters.setPort(502); // 2. 创建 Master 实例 ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters); // master.setConnectTimeout(3000); // 设置3秒超时 try { if (!master.isConnected()) { master.connect(); } // --- 关键参数修改区 (匹配你的 Modbus Poll 截图) --- int slaveId = 1; // Slave ID: 1 int offset = 700; // Address: 700 (对应 PLC 40701) int quantity = 50; // Quantity: 30 // ---------------------------------------------- // 3. 读取保持寄存器 int[] registerValues = master.readHoldingRegisters(slaveId, offset, quantity); // 4. 解析并封装为 JSON 格式 (List) List> dataList = new ArrayList<>(); for (int i = 0; i < registerValues.length; i++) { Map item = new HashMap<>(); int currentAddress = offset + i; int rawValue = registerValues[i]; item.put("address", currentAddress); // 寄存器物理地址 item.put("value", rawValue); // 寄存器原始数值 // 这里可以根据业务增加转换逻辑,例如: // if(currentAddress == 700) item.put("comment", "设备运行状态"); dataList.add(item); } // 5. 返回带数据的成功响应 return R.ok(dataList); } catch (Exception e) { e.printStackTrace(); return R.fail("Modbus 读取异常: " + e.getMessage()); } finally { // 必须断开连接,否则下次请求可能因为连接数占满而失败 master.disconnect(); } } catch (Exception e) { e.printStackTrace(); return R.fail("网络配置异常: " + e.getMessage()); } } // 假设 regs[10] = 50880, regs[11] = 45 (这里假设 711 是高位) public static float registersToFloat(int low, int high) { // 1. 将两个 16 位整数合成一个 32 位整数 int combined = (high << 16) | (low & 0xFFFF); // 2. 将 32 位整数按 IEEE 754 标准转为浮点数 return Float.intBitsToFloat(combined); } private static float parseModbusFloat(int reg1, int reg2) { // 尝试 CDAB 顺序 (这是大多数 HMI 如 Delta/台达 屏幕常用的顺序) int bits = (reg1 << 16) | (reg2 & 0xFFFF); // 如果结果还是不对,试着把上面这行换成 ABCD: // int bits = (reg2 << 16) | (reg1 & 0xFFFF); // int bits = ((reg1 & 0xFF) << 24) | ((reg1 >> 8) << 16) | ((reg2 & 0xFF) << 8) | (reg2 >> 8); return Float.intBitsToFloat(bits); } public static void main(String[] args) { // 调用示例 float value = parseModbusFloat(50880, 45); // float value = parseModbusFloat(45, 50880); System.out.println("解析后的真实数值: " + value); } }