#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. верно? вы подразумеваете, что в коде есть какая-то ошибка??