1 控制类 


import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * plc控制
 * 
 */
@RestController
@RequestMapping("/plc")
@Api(tags = "plc控制")
public class ModBusController
{
    @Autowired
    private ModbusTcpManage modbusTcpManage;

    @Autowired
    private DataReadSerTask dataReadSerTask;
   

    @GetMapping("/findHexData")
    public AjaxResult findHexData(@RequestParam(name = "slaveId")Integer slaveId,
                          @RequestParam(name = "startAddress")Integer startAddress,
                           @RequestParam(name = "numberOfRegisters")Integer numberOfRegisters)
    {
        String hexData = modbusTcpManage.findHexData(slaveId, startAddress, numberOfRegisters);
        return success(hexData);
    }


    @GetMapping("/findData")
    public AjaxResult findData(@RequestParam(name = "slaveId")Integer slaveId,
                                  @RequestParam(name = "startAddress")Integer startAddress,
                                  @RequestParam(name = "numberOfRegisters")Integer numberOfRegisters)
    {
        Float data = modbusTcpManage.findData(slaveId, startAddress, numberOfRegisters);
        return success(data);
    }

    @GetMapping("/writeData")
    public AjaxResult writeData(@RequestParam(name = "slaveId")Integer slaveId,
                               @RequestParam(name = "startAddress")Integer startAddress,
                               @RequestParam(name = "value")Integer value)
    {
        Boolean aBoolean = modbusTcpManage.writeData(slaveId, startAddress, value);
        return success(aBoolean);
    }

}

2  ModbusTcpManage

import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;

@Component
@Slf4j
public class ModbusTcpManage {

    private String host = "192.168.10.15";    //plc设置的ip地址
    private int port = 502;                   //plc设置的端口
    private ModbusMaster master = null;
    public Float findData(Integer slaveId,Integer startAddress,Integer numberOfRegisters)        
    {
        if(master == null){
            master = getMaster();
        }

        //没有连接,获取连接
        if(!master.isConnected()){
            try {
                master.connect();
            } catch (ModbusIOException e) {
               log.info("ModbusMaster连接失败",e.getMessage());
            }
        }

        try {
            //读取寄存器值
            int[] registers = master.readHoldingRegisters(slaveId, startAddress, numberOfRegisters);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < registers.length; i++) {
                //转换16进制
                String s = Integer.toHexString(registers[i]);
                //不足4位补足4位
                while (s.length()<4){
                    s = "0"+s;
                }
                sb.append(s);
                log.info("寄存器地址 " + (startAddress + i) + ": " + s);
            }
            log.info("读取到的数据十六进制值是: " + sb);

            return hexToFloat(sb.toString());
        } catch (ModbusProtocolException e) {
            log.error("ModbusProtocolException"+e.getMessage());
        } catch (ModbusNumberException e) {
            log.error("ModbusNumberException"+e.getMessage());
        } catch (ModbusIOException e) {
            log.error("ModbusIOException"+e.getMessage());
        }finally{
            if(!master.isConnected()){
                try {
                    master.disconnect();
                } catch (Exception e) {
                    log.error("断开连接失败: " + e.getMessage());
                }
            }
        }

        return null;
    }

    private ModbusMaster getMaster() {


        try {
            TcpParameters tcpParameters = new TcpParameters();
            InetAddress byName = InetAddress.getByName(host);
            tcpParameters.setHost(byName);
            tcpParameters.setPort(port);
            tcpParameters.setKeepAlive(true);
            master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);

        } catch (UnknownHostException e) {
            log.error("ModbusMaster初始化失败"+e.getMessage());
        }

        return master;

    }

    public float hexToFloat(String hexString) {
        byte[] bytes = new byte[4];
        for (int i = 0; i < hexString.length()/2; i++) {
            String substring = hexString.substring(i * 2, (i * 2) + 2);
            System.out.println(substring);
            bytes[i] = (byte) Integer.parseInt(hexString.substring(i*2, (i*2)+2), 16); // 将每两位16进制数转换为字节
        }
        return ByteBuffer.wrap(bytes).getFloat(); // 将字节数组转换为浮点数
    }


    public String findHexData(Integer slaveId,Integer startAddress,Integer numberOfRegisters){
        if(master == null){
            master = getMaster();
        }

        if(!master.isConnected()){
            try {
                master.connect();
            } catch (ModbusIOException e) {
                log.info("ModbusMaster连接失败",e.getMessage());
            }
        }

        try {
            int[] registers = master.readHoldingRegisters(slaveId, startAddress, numberOfRegisters);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < registers.length; i++) {
                String s = Integer.toHexString(registers[i]);
                while (s.length()<4){
                    s = "0"+s;
                }
                sb.append(s);
                log.info("寄存器地址 " + (startAddress + i) + ": " + s);
            }
            log.info("读取到的数据十六进制值是: " + sb);

           return sb.toString();
        } catch (ModbusProtocolException e) {
            log.error("ModbusProtocolException"+e.getMessage());
        } catch (ModbusNumberException e) {
            log.error("ModbusNumberException"+e.getMessage());
        } catch (ModbusIOException e) {
            log.error("ModbusIOException"+e.getMessage());
        }finally{
            if(!master.isConnected()){
                try {
                    master.disconnect();
                } catch (Exception e) {
                    log.error("断开连接失败: " + e.getMessage());
                }
            }
        }


        return null;
    }


    public Boolean writeData(Integer slaveId,Integer startAddress,Integer value){
        if(master == null){
            master = getMaster();
        }

        if(!master.isConnected()){
            try {
                master.connect();
            } catch (ModbusIOException e) {
                log.info("ModbusMaster连接失败",e.getMessage());
            }
        }

        try {
            master.writeSingleRegister(slaveId, startAddress, value);
            return true;
        } catch (ModbusProtocolException e) {
            log.error("ModbusProtocolException:write"+e.getMessage());
        } catch (ModbusNumberException e) {
            log.error("ModbusNumberException:write"+e.getMessage());
        } catch (ModbusIOException e) {
            log.error("ModbusIOException:write"+e.getMessage());
        }finally{
            if(!master.isConnected()){
                try {
                    master.disconnect();
                } catch (Exception e) {
                    log.error("断开连接失败: " + e.getMessage());
                }
            }
        }

        return false;
    }
}

3 plc一个寄存器是2个字节,所以处理数据的时候要注意

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐