Индексирование вне связанного исключения при чтении удерживающего регистра с использованием библиотеки jamod

#java #exception

#java #исключение

Вопрос:

я реализовал мастер TCP Modbus, используя библиотеку jamod, код запрашивает регистры хранения из Modbus, считывает ответ и записывает его в файл. также он вычисляет время транзакции Вот мой код :

 public class TCPModbus_Task {
    private static ModbusTCPMaster tcp_Modbusmaster;

    public static void main(String[] args) {
        int NoOfRequests = 0;// loop variable
        int port = Modbus.DEFAULT_PORT;
        int ref = 0; //the reference; offset where to start reading from i.e. the start address.
        int count = 0; //the number of DI's to read
        int repeat = 1; //a loop for repeating the transaction
        String addr = null;
        long Avg_diff = 0;
        int reg_val = 0;
        Register[] registers = new Register[200];
        BufferedWriter output = null;
        long Avg_Time = 0;
        try {
            //Setup Parameters
            if(args.length < 3)
                System.exit(1);
            else {
                try {
                    String astr = args[0];
                    int idx = astr.indexOf(':');
                    if(idx != -1) {
                        port = Integer.parseInt(astr.substring(idx 1));
                        addr = astr.substring(0, idx);
                    }
                    ref = Integer.decode(args[1]).intValue();
                    count = Integer.decode(args[2]).intValue();
                    if (args.length == 4) {
                      repeat = Integer.parseInt(args[3]);
                    }  

                } catch (Exception ex) {
                    ex.printStackTrace();
                    System.exit(1);
                }
            }

            //ModbusTCPMaster instance ( constructor called )
            tcp_Modbusmaster = new ModbusTCPMaster(addr, port);

            //Connect to slave
            tcp_Modbusmaster.connect();

            //Create file write modbus data
            File file = new File("D:/MODbusData.txt");
            if (!file.exists()) {
                     file.createNewFile();
            }


            do {
                    Thread.sleep(1000);

                    //TimeStamp before request
                    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT 5.30"));
                    long time1 = cal.getTimeInMillis();
                    String Time1 = String.valueOf(time1);
                    System.out.println("Time1 = "   time1);         


                    //Read Modbus register (function code = 3)
                    registers = tcp_Modbusmaster.readMultipleRegisters(ref, count, 255);

                    System.out.println("Number of Modbus registers : "   registers.length);
                    System.out.println("nModbus register values : n");
                    for (int i=0; i<registers.length; i  )
                    {
                        System.out.println(registers[i].getValue());
                    }

                    //TimeStamp After response
                    Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT 5.30"));
                    long time2 = cal1.getTimeInMillis();
                    String Time2 = String.valueOf(time2);

                    System.out.println("Time2 = "   time2);
                    int diff = (int)(time2-time1);
                    String Transac_time = String.valueOf(diff);
                    System.out.println("Transacion(time2 - time1) time in ms="   diff);
                    NoOfRequests  ;
                    Avg_diff = Avg_diff   (long)diff;

                    //Writing Modbus data and transaction timing to file
                    output = new BufferedWriter(new FileWriter(file,true));

                    output.write("Time1 in ms:  "   Time1   "nr");
                    output.write("Modbus data: n");
                    for(int i=0;i<registers.length;i  )
                    {
                        reg_val = registers[i].getValue();
                        String Register_value = String.valueOf(reg_val);                                                                        
                        output.write(Register_value   " ");
                    }
                    output.write("n"   "Time2 in ms:  "   Time2   "nr");
                    output.write("Transaction time in ms:  "   Transac_time   "n");

                    //Calculating the Average Transaction Time
                    if(NoOfRequests>=repeat)
                    {
                        Avg_Time = Avg_diff/NoOfRequests;
                        String AVG_Time = String.valueOf(Avg_Time);
                        output.write("Avg Transaction time in ms:  "   AVG_Time   "nr");                          
                    }

                    output.close();

            }while(NoOfRequests < repeat);

            tcp_Modbusmaster.disconnect();



        } catch( Exception ex ) {
            ex.printStackTrace();
        }
    }
}
  

Но если я задам значение счетчика (т.Е. Количество слов (регистров) для чтения с ведомого устройства) больше 123, я хочу прочитать 200 удерживающих регистров из ведомого устройства Modbus (имеющего карту Modbus). я могу прочитать до count = 123 регистра в одном запросе без исключения.

это дает следующее исключение:

 java.lang.IndexOutOfBoundsException
    at java.io.BufferedInputStream.read(Unknown Source)
    at java.io.DataInputStream.read(Unknown Source)
    at net.aeplmm.modbus.io.ModbusTCPTransport.readResponse(ModbusTCPTransport.java:195)
    at net.aeplmm.modbus.io.ModbusTCPTransaction.execute(ModbusTCPTransaction.java:192)
    at net.aeplmm.modbus.facade.ModbusTCPMaster.readMultipleRegisters(ModbusTCPMaster.java:282)
    at com.axonet.modbus.TCPModbus_Task.main(TCPModbus_Task.java:79)
java.io.EOFException
    at java.io.DataInputStream.readUnsignedByte(Unknown Source)
    at net.aeplmm.modbus.io.BytesInputStream.readUnsignedByte(BytesInputStream.java:169)
    at net.aeplmm.modbus.io.ModbusTCPTransport.readResponse(ModbusTCPTransport.java:200)
    at net.aeplmm.modbus.io.ModbusTCPTransaction.execute(ModbusTCPTransaction.java:192)
    at net.aeplmm.modbus.facade.ModbusTCPMaster.readMultipleRegisters(ModbusTCPMaster.java:282)
    at com.axonet.modbus.TCPModbus_Task.main(TCPModbus_Task.java:79)
java.io.EOFException
    at java.io.DataInputStream.readUnsignedByte(Unknown Source)
    at net.aeplmm.modbus.io.BytesInputStream.readUnsignedByte(BytesInputStream.java:169)
    at net.aeplmm.modbus.io.ModbusTCPTransport.readResponse(ModbusTCPTransport.java:200)
    at net.aeplmm.modbus.io.ModbusTCPTransaction.execute(ModbusTCPTransaction.java:192)
    at net.aeplmm.modbus.facade.ModbusTCPMaster.readMultipleRegisters(ModbusTCPMaster.java:282)
    at com.axonet.modbus.TCPModbus_Task.main(TCPModbus_Task.java:79)
java.io.EOFException
    at java.io.DataInputStream.readUnsignedByte(Unknown Source)
    at net.aeplmm.modbus.io.BytesInputStream.readUnsignedByte(BytesInputStream.java:169)
    at net.aeplmm.modbus.io.ModbusTCPTransport.readResponse(ModbusTCPTransport.java:200)
    at net.aeplmm.modbus.io.ModbusTCPTransaction.execute(ModbusTCPTransaction.java:192)
    at net.aeplmm.modbus.facade.ModbusTCPMaster.readMultipleRegisters(ModbusTCPMaster.java:282)
    at com.axonet.modbus.TCPModbus_Task.main(TCPModbus_Task.java:79)
net.aeplmm.modbus.ModbusIOException: Executing transaction failed (tried 3 times)
    at net.aeplmm.modbus.io.ModbusTCPTransaction.execute(ModbusTCPTransaction.java:197)
    at net.aeplmm.modbus.facade.ModbusTCPMaster.readMultipleRegisters(ModbusTCPMaster.java:282)
    at com.axonet.modbus.TCPModbus_Task.main(TCPModbus_Task.java:79)
  

Было бы полезно, если у кого-нибудь есть какие-либо предложения.

Комментарии:

1. Я использовал класс ModbusTCPMaster для реализации TCP modbus master.

2. Что, если вы прочитаете это дважды? Сначала 100 регистров, а затем регистры из 100-200.

3. Пахнет ошибкой Modbus , она не должна позволять низкоуровневому IndexOutOfBoundException доступу к вызывающему. Это все еще не означает, что ваш код не виноват, просто библиотека должна выдавать более значимое сообщение об ошибке.

4. @jure: это решение, но на самом деле мне нужно выполнить одну транзакцию за 10 мс. сейчас это занимает около 10 мс. если я прочитаю дважды, время транзакции увеличится

5. @Marko Topolnik: по Modbus. вы имеете в виду библиотеку jamod. верно? вы подразумеваете, что в коде есть какая-то ошибка??