通过modbus4j读写字符串到PLC

本项目使用modbus4j-3.0.3.jar实现于PLC通讯。
实现与PLC连接并完成读写基本数据类型通讯测试不再赘述,本人参考了云逸的博客https://www.cnblogs.com/ioufev/p/10831289.html
直接进入主题,读写字符串
写入字符串
/**
     * 测试程序
     *
     * @param slaveId
     * @param offset
     * @param dataType
     * @param value
     * @return
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public static boolean writeStrToPlc(int slaveId, int startOffset, String value) throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        // 获取master
        ModbusMaster tcpMaster = getMaster();
        short[] sdata = SetString(value);
        // 创建请求对象
        WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);
        // 发送请求并获取响应对象
        ModbusResponse response = tcpMaster.send(request);
        if (response.isException()) {
//            log.error(response.getExceptionMessage());
            return false;
        } else {
            return true;
        }
    }
工具类方法 setString()主要进行了一下数据类型转换
public static short[] SetString(String value) {
        byte[] bytesTemp = value.getBytes(StandardCharsets.UTF_8);
        byte[] bytes;
        if (bytesTemp.length % 2 > 0) {
            bytes = Arrays.copyOf(bytesTemp, bytesTemp.length + 1);
        } else {
            bytes = bytesTemp;
        }
        return bytesToShort(bytes);
    }

    /**
     * Byte数组转short数组
     *
     * @param bytes
     * @return
     */
    public static short[] bytesToShort(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        short[] shorts = new short[bytes.length / 2];
        ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
        return shorts;

    }

读取字符串
/**
     *
     * @param slaveId
     * @param offset
     * @param dataType
     * @return
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public static String readHoldingRegisters(int slaveId, int offset, int dataType, int num)
            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        // 03 Holding Register类型数据读取
        short[] data = new short[num];
        for (int i = 0; i < num; i++) {
            data[i] = readHoldingRegister(slaveId, offset + i, dataType).shortValue();
        }
        try {
            return GetString(data, 0, num);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(Modbus4jReadUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

工具类方法getString()  类型转换
        /**
         * 
         * @param src
         * @param start
         * @param len
         * @return 
         */
        public static String GetString(short[] src, int start, int len) throws UnsupportedEncodingException
        {
            short[] temp = new short[len];
            for (int i = 0; i < len; i++)
            {
                temp[i] = src[i + start];
            }
            byte[] bytesTemp = shorts2Bytes(temp);
            for (int i = 0; i < bytesTemp.length; i++) {
                byte b = bytesTemp[i];
            }
            String str = new String(bytesTemp, "UTF-8");
            return str;
        }
        /**
         * 
         * @param data
         * @return 
         */
        public static byte [] shorts2Bytes(short [] data){
            byte[] byteValue = new byte[data.length * 2];
            for (int i = 0; i < data.length; i++) {
                byteValue[i * 2] = (byte) (data[i] & 0xff);
                byteValue[i * 2 + 1] = (byte) ((data[i] & 0xff00) >> 8);
            }
            return byteValue;
        }
PLC本身并不直接支持字符串类型数据。这里只能将字符串进行转换后进行存储,读的时候也是一样,通过读入一段连续的寄存器地址数据,再转成字符串
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Modbus TCP协议本身不支持直接读写字符串,但是可以通过拆分字符串成多个寄存器的方式实现字符串读写。 具体实现方法如下: 1. 将字符串按照指定编码(如UTF-8)进行编码,得到字节数组。 2. 将字节数组拆分成多个16位的整数,作为寄存器的值写入设备。 3. 取寄存器值时,将多个16位的整数进行合并,得到字节数组,然后将字节数组按照指定编码转换为字符串。 下面是一个示例代码,演示如何将字符串写入Modbus TCP设备的寄存器,并从设备的寄存器中字符串: ``` using System.Text; using NModbus; // 将字符串写入设备的寄存器 string str = "hello world"; byte[] bytes = Encoding.UTF8.GetBytes(str); ushort[] registers = new ushort[bytes.Length / 2 + 1]; for (int i = 0; i < bytes.Length; i += 2) { registers[i / 2] = (ushort)(bytes[i] << 8 | bytes[i + 1]); } modbusMaster.WriteMultipleRegisters(1, 0, registers); // 从设备的寄存器中字符串 ushort[] readRegisters = modbusMaster.ReadHoldingRegisters(1, 0, bytes.Length / 2 + 1); byte[] readBytes = new byte[bytes.Length]; for (int i = 0; i < bytes.Length; i += 2) { readBytes[i] = (byte)(readRegisters[i / 2] >> 8); readBytes[i + 1] = (byte)readRegisters[i / 2]; } string readStr = Encoding.UTF8.GetString(readBytes); ``` 上面的代码将字符串按照UTF-8编码写入设备的寄存器,然后从设备的寄存器中字符串并将其转换为字符串类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值