kochedykov / jlibmodbus

JLibModbus - is an implementation of the Modbus protocol v1.1b in java language. Java modbus library. It works. Welcome.
http://kochedykov.github.io/jlibmodbus/
Apache License 2.0
299 stars 128 forks source link

Why can't the slave receive data when the master station sends more than 12 bytes? #95

Closed simpleWorker22 closed 5 months ago

simpleWorker22 commented 6 months ago

here is my code : salve : package com.ztrx.liftgate.screen;

import com.intelligt.modbus.jlibmodbus.data.ModbusHoldingRegisters; import com.intelligt.modbus.jlibmodbus.exception.IllegalDataAddressException; import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException; import com.intelligt.modbus.jlibmodbus.serial.*; import com.intelligt.modbus.jlibmodbus.slave.ModbusSlave; import com.intelligt.modbus.jlibmodbus.slave.ModbusSlaveFactory; import com.ztrx.liftgate.screen.service.ModbusRTUSlaveService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean;

import javax.annotation.PostConstruct; import java.nio.charset.StandardCharsets; import java.util.logging.Logger;

@SpringBootApplication public class ScreenApplication {

private static final Logger logger = Logger.getLogger(ModbusRTUSlaveService.class.getName());
private static final int MAX_RETRIES = 3;

public static void main(String[] args) {
    SpringApplication.run(ScreenApplication.class, args);
}

@PostConstruct
public void init() {
    Thread slaveThread = new Thread(new ModbusSlaveRunnable());
    slaveThread.start();
}

private static class ModbusSlaveRunnable implements Runnable {
    private static final int SLAVE_ID = 1;

    @Override
    public void run() {
        try {
            SerialParameters slaveSerialParameters = new SerialParameters();
            SerialUtils.setSerialPortFactory(new SerialPortFactoryJSerialComm());

            slaveSerialParameters.setDevice("/dev/ttyS9"); // 修改为适合您的串口设备
            slaveSerialParameters.setParity(SerialPort.Parity.NONE);
            slaveSerialParameters.setBaudRate(SerialPort.BaudRate.BAUD_RATE_4800);
            slaveSerialParameters.setDataBits(8);
            slaveSerialParameters.setStopBits(1);

            ModbusSlave slave = ModbusSlaveFactory.createModbusSlaveRTU(slaveSerialParameters);

            slave.setServerAddress(1);
            slave.setBroadcastEnabled(true);
            slave.setReadTimeout(10000);

            ModbusHoldingRegisters holdingRegisters = new ModbusHoldingRegisters(100);
            slave.getDataHolder().setHoldingRegisters(holdingRegisters);
            System.out.println(holdingRegisters.getQuantity());

            slave.listen();

            while (true) {
                // 持续监听主站的数据
                Thread.sleep(500);
                /*int byteCount = holdingRegisters.getQuantity() * 2;
                System.out.println(byteCount);
                byte[] jsonBytes = new byte[byteCount];
                for (int i = 0; i < holdingRegisters.getQuantity(); i++) {
                    jsonBytes[i * 2] = (byte) (holdingRegisters.get(i) >> 8);
                    jsonBytes[i * 2 + 1] = (byte) (holdingRegisters.get(i) & 0xFF);
                }
                String jsonData = new String(jsonBytes, StandardCharsets.UTF_8).trim();*/
                // 在从站接收数据的地方
                int[] registers = holdingRegisters.getRegisters();
                byte[] jsonDataBytes = new byte[registers.length * 2];
                for (int i = 0; i < registers.length; i++) {
                    jsonDataBytes[i * 2] = (byte) (registers[i] >> 8);
                    jsonDataBytes[i * 2 + 1] = (byte) (registers[i] & 0xFF);
                }
                String jsonData = new String(jsonDataBytes, StandardCharsets.UTF_8).trim();
                System.out.println("receive data:" + jsonData);
                System.out.println("is listen:" + slave.isListening());
                // 在这里处理从主站接收到的数据
            }
        } catch (ModbusIOException | InterruptedException e) {
            e.printStackTrace();
        } catch (SerialPortException e) {
            throw new RuntimeException(e);
        }
    }
}

}

master : package org.example.demo;

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.msg.request.WriteMultipleRegistersRequest; import com.intelligt.modbus.jlibmodbus.serial.*;

import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets;

public class ModbusMasterDemo { final static private int SLAVE_ID = 1; public static void main(String[] args) { try { SerialParameters masterSerialParameters = new SerialParameters(); SerialUtils.setSerialPortFactory(new SerialPortFactoryJSerialComm());

        masterSerialParameters.setDevice("COM4");
        masterSerialParameters.setParity(SerialPort.Parity.NONE);
        masterSerialParameters.setBaudRate(SerialPort.BaudRate.BAUD_RATE_4800);
        masterSerialParameters.setDataBits(8);
        masterSerialParameters.setStopBits(1);
        ModbusMaster master = ModbusMasterFactory.createModbusMasterRTU(masterSerialParameters);

        master.setResponseTimeout(30000);
        master.connect();

        String jsonData = "322222222222222222222222222222222222222222222222222222233";
        byte[] jsonBytes = jsonData.getBytes(StandardCharsets.UTF_8);
        int byteCount = jsonBytes.length;
        System.out.println(byteCount);
        int registerCount = (byteCount + 1) / 2;

        ByteBuffer byteBuffer = ByteBuffer.allocate(registerCount * 2);
        byteBuffer.put(jsonBytes);
        byteBuffer.put(new byte[registerCount * 2 - byteCount]);
        byteBuffer.rewind();

        int[] registers = new int[registerCount];
        for (int i = 0; i < registerCount; i++) {
            registers[i] = byteBuffer.getShort() & 0xFFFF;
        }

        /*// 向每个从机发送相同的数据
        for (int i = 1; i < 3; i++) {
            // 向从机写入数据
            WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest();
            request.setServerAddress(i);
            request.setStartAddress(0);
            request.setRegisters(registers);

            System.out.println("start writing to slave " + i);
            master.processRequest(request);
            System.out.println("end writing to slave " + i);
            Thread.sleep(500);
        }*/
        WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest();
        request.setServerAddress(1);
        request.setStartAddress(0);
        request.setRegisters(registers);
        System.out.println(registerCount);
        System.out.println("start");
        master.processRequest(request);
        System.out.println("end");

        master.disconnect();
    } catch (ModbusProtocolException | ModbusIOException | ModbusNumberException e) {
        e.printStackTrace();
    } catch (SerialPortException e) {
        e.printStackTrace();
    }
}

}

kochedykov commented 6 months ago

Hi! I've tested your code it works if I use JSSC library. There are some problems with jSerialComm library. Could you try using JSSC? Does your application work with JSSC?