Запись в Modbus с помощью Jamod
Вопрос
Я столкнулся с любопытной ситуацией при использовании jamod для записи в modbus.Следующий код чтения работает отлично:
public static void main(String[] args) throws Exception {
InetAddress address = InetAddress.getByName("host.somewhere");
TCPMasterConnection connection = new TCPMasterConnection(address);
connection.setPort(502);
connection.connect();
ReadMultipleRegistersRequest request = new ReadMultipleRegistersRequest(0, 1);
ReadMultipleRegistersResponse response = (ReadMultipleRegistersResponse)
executeTransaction(connection, request);
}
private static ModbusResponse executeTransaction(TCPMasterConnection connection,
ModbusRequest request)
throws ModbusIOException, ModbusSlaveException, ModbusException {
ModbusTCPTransaction transaction = new ModbusTCPTransaction(connection);
transaction.setRequest(request);
transaction.execute();
return transaction.getResponse();
}
Но попытка написать подобным образом не удалась (Jamod пытается 3 раза, каждый раз встречает SocketTimeoutException и, наконец, выдает ModbusException).
public static void main(String[] args) throws Exception {
final InetAddress address = InetAddress.getByName("host.somewhere");
final TCPMasterConnection connection = new TCPMasterConnection(address);
connection.setPort(502);
connection.connect();
Register reg = new SimpleRegister(0);
WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest(0,
new Register[]{reg});
executeTransaction(connection, request);
}
Да, я знаю, что использую многорегистровые версии объектов запроса, но устройство, с которым я работаю, поддерживает только коды функций 3 и 16.
Я также написал тестер raw-socket для записи регистров, и, насколько я вижу, он работает правильно.Но было бы неплохо использовать джамод в обеих ситуациях.
Есть ли у кого-нибудь опыт использования jamod, и будет ли он достаточно любезен, чтобы сказать, что я делаю неправильно?Это происходит как с версиями jamod 1.1, так и с 1.2rc1.Или это, возможно, какая-то ситуация, специфичная для поставщика?
Решение
В конце я написал свою собственную реализацию modbus.Мне нужно было поддерживать только два разных кода функций, поэтому реализация была простой.
Хотя позже я нашел другую библиотеку Modbus с открытым исходным кодом для Java.Я кто-то еще сталкивается с той же проблемой, используя modbus4j может помочь.
Другие советы
По умолчанию запросы Modbus имеют идентификатор устройства = 0.Поэтому для запроса должен быть установлен любой другой идентификатор, например:
WriteCoilRequest writeCoilRequest = new WriteCoilRequest(ref, bool);
writeCoilRequest.setUnitID(unitid);
Потратил несколько часов, пытаясь решить ту же проблему, которую вы описали в вопросе.
Мой метод, который я написал на основе вашего вопроса, работает!
try {
ModbusTCPTransaction trans = null; // the transaction
String refe = "0";// HEX Address
int ref = Integer.parseInt(refe, 16);// Hex to int
// int count = 1; // the number Address to read
ReadMultipleRegistersRequest ainReq = new ReadMultipleRegistersRequest(
ref, count);
ReadMultipleRegistersResponse ainRes = new ReadMultipleRegistersResponse();
// 3. Start Transaction
trans = new ModbusTCPTransaction(con);
trans.setRetries(5);
trans.setReconnecting(true);
trans.setRequest(ainReq);
int k = 0;
do {
trans.execute();
ainRes = (ReadMultipleRegistersResponse) trans.getResponse();
Register reg = new SimpleRegister(ertekInt);
WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest(0,
new Register[]{reg});
System.out.println("Állított AOUT: " + request.getRegisterValue(k));
lista.add(createPlanet("AOUT",
"" + k + " " + request.getRegisterValue(k)));
k++;
} while (k < count);
} catch (ModbusIOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ModbusSlaveException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ModbusException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
У меня была аналогичная проблема: я пытался записать значение в регистр, который был определен в «задании устройства» как регистр катушки.Поэтому я использовал:
WriteCoilRequest coil_req = new WriteCoilRequest(registerReference,value2write)
и это решило проблему.Возможно, это поможет.
Пока!
Я столкнулся с этой проблемой на Android.
Поскольку эта задача может занять значительное время, поскольку она ожидает ответа от внешнего устройства, я нашел решение — выполнять запись и чтение в другом потоке.