Запись в 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.

Я также написал тестер сырых сокетов для записи регистров, и, насколько я вижу, он работает корректно. Но было бы неплохо использовать джамод в обеих ситуациях.

Есть ли у кого-нибудь опыт использования джамода, и будет ли он достаточно любезен, чтобы сказать, что я делаю неправильно? Это происходит как с версиями jamod 1.1, так и с 1.2rc1. Или это, возможно, какая-то конкретная ситуация с поставщиком?


person Ahe    schedule 03.12.2009    source источник
comment
Сначала я бы выяснил, проблема ли это в джамоде или в устройстве. Может попробовать записать на устройство какими-то другими средствами?   -  person kgiannakakis    schedule 03.12.2009
comment
Да, я могу. Я написал тестовую программу, которая использует tcp-socket для записи на устройство. По крайней мере, в моих тестах чтение в регистр, написанный сокетом, возвращает значение, недавно записанное в него. (И я использовал случайные значения, а не только ноль :)).   -  person Ahe    schedule 03.12.2009


Ответы (5)


Запросы Modbus по умолчанию имеют unit id = 0. Таким образом, любой другой идентификатор должен быть установлен для запроса, например:

WriteCoilRequest writeCoilRequest = new WriteCoilRequest(ref, bool);
writeCoilRequest.setUnitID(unitid);

Потратил несколько часов, пытаясь решить ту же проблему, которую вы описали в вопросе.

person DH28    schedule 16.05.2017
comment
Звучит разумно. Однако я не могу проверить это, но, надеюсь, это кому-то поможет. - person Ahe; 16.05.2017

В конце концов я написал свою собственную реализацию Modbus. Мне нужно было поддерживать только 2 разных кода функций, поэтому реализация была простой.

Хотя позже я нашел другую библиотеку modbus с открытым исходным кодом для java. Если кто-то еще сталкивается с той же проблемой, может помочь modbus4j.

person Ahe    schedule 23.03.2010
comment
Мне пришлось проделать значительный объем работы над одной из старых (сейчас 2012 года...) версий джамода, чтобы заставить ее работать. Существует более новая версия (поэтому, если вы недавно не смотрели, посмотрите еще раз), которая может лучше поддерживать Modbus/TCP. - person Julie in Austin; 06.05.2012
comment
В конце концов я с отвращением опустил руки и разветвил jamod на SourceForge, чтобы создать j2mod. Это сильно исправленная версия jamod, которую я поставляю с оборудованием моей компании. Во-вторых, jamod не поддерживает большое количество сообщений Modbus, поэтому я реализовал каждое сообщение, которое смог найти. Вы можете найти мой форк на SourceForge, выполнив поиск j2mod. - person Julie in Austin; 06.08.2012

Мой метод, который я написал на основе вашего вопроса, работает!

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();
        }
person David    schedule 20.11.2013

У меня была аналогичная проблема, я пытался записать значение в регистр, который был определен в «задание устройства» как регистр катушки. Поэтому я использовал:

WriteCoilRequest coil_req = new WriteCoilRequest(registerReference,value2write)

и это решило проблему. Может это поможет.

До свидания!

person jomazz    schedule 11.02.2015
comment
Ого, ответ на вопрос пятилетней давности. Однако я боюсь, что не могу проверить ваше решение, у меня не было доступа к рассматриваемому устройству в течение многих лет. - person Ahe; 14.02.2015
comment
Я знаю, что немного запоздал с ответом, но я подумал, что это может быть полезно для кого-то еще в нашем положении;) - person jomazz; 14.02.2015

Я столкнулся с этой проблемой на Android.

Поскольку эта задача может занять значительное время, поскольку она ожидает ответа от внешнего устройства, найденное мной решение состояло в том, чтобы выполнять запись и чтение в другом потоке.

person Nestor Palomeque    schedule 19.06.2017