Отправка 0xFF и вычисление CRC с байтами со знаком - WriteSingleCoil и ModBUS, Java и Android -

ОТРЕДАКТИРОВАННЫЕ И ПОДДЕРЖИВАЕМЫЕ (ниже)

Я использую Java для Android, пытаясь отправить байт 255 (0xFF в функции WriteSingleCoil) на серверное устройство ModBUS.

Устройство не работает, я не знаю, из-за того, что я не могу интерпретировать подписанный байт -1, или из-за того, что я неправильно вычисляю CRC. Я не знаю, как вычислить CRC для отрицательных байтов.

Подводя итог: я не знаю, как отправить функцию 05 Write Single Coil со значением 0xFF для включения катушки с Java на сервер ModBUS.

Кто-нибудь может мне помочь?

РЕШЕНИЕ:

"iIndex = ucCRCLo ^ b: подобные операции должны быть записаны как iIndex = (ucCRCLo ^ b) & 0xff, потому что & будет приводить ucCRCLo, b и результат к int, который составляет 32 бита, а короткий - 16, поэтому у вас будет много дополнительных бит установлен на 1 "

Этот ответ мне помог. Большое спасибо TheDayOfcondor

Но также моей огромной проблемой была обычная проблема в Java со знаковыми байтами. Моя функция вычисления CRC делает это правильно для беззнаковых байтов, но выдает ошибки, если я передаю внутри подписанные байты. Уловка для работы с байтами для связи ModBUS - это работа во всем приложении с шортами в качестве байтов для диапазона 0-255, даже с вычислением trames и CRC. И только на последнем шаге, при отправке трама на сервер ModBUS, снова преобразовать их в байты. Это работает.

Надеюсь, это поможет кому-то в будущем.

ОБЪЯСНЕНИЕ ПРОБЛЕМЫ:

Я пытаюсь установить катушку на ModBUS с функцией 05, это объясняет функцию:

Запрос

Я пытаюсь включить катушку по адресу 1:

Этот шестнадцатеричный: 0A 05 00 01 ff 00 DC 81

Этот байтовый массив: 10 5 0 1 255 0 220 129

10: Адрес ведомого (10 = 0A шестнадцатеричный)

05: Функциональный код (Force Single Coil)

0001: Адрес данных катушки. (катушка # 1 = 01 шестигранник)

FF00: статус для записи (FF00 = ON, 0000 = OFF)

DC81: CRC (циклический контроль избыточности) для проверки ошибок.

Дело в том, что Java использует байты со знаком, поэтому я не могу поместить 255 в свой массив байтов. Я понимаю, что должен поставить -1, но тогда я не могу правильно вычислить CRC, потому что у меня есть несколько предварительно вычисленных массивов байтов для получения CRC, но функция отправляет отрицательный индекс.

Итак: я не знаю, правильно ли я поступаю, пытаясь отправить -1, есть ли у меня альтернатива для отправки 255, ни как вычислить CRC для -1.

Это функция для вычисления CRC:

public short[] GenerateCRC (byte[] pMsg) {
    short ucCRCHi = 0xFF;
    short ucCRCLo = 0xFF;
    int iIndex;

    for (byte b : pMsg)
    {
        iIndex = ucCRCLo ^ b;

        try {
            ucCRCLo = (short)(ucCRCHi ^ aucCRCHi[ ( iIndex ) ]);
            ucCRCHi = aucCRCLo[ ( iIndex ) ];
        } catch (Exception e) {
            Log.e(LOGTAG, "GenerateCRC: " + e.toString(), e);
            e.printStackTrace();
        }
    }

        short[]result= new short[2];
        result0]= ucCRCHi;
        result1]= ucCRCLo;

        return result;
}

person Esinor I.D.    schedule 05.11.2012    source источник


Ответы (1)


Вопрос не очень ясен - однако наиболее распространенная проблема, связанная с байтами, заключается в том, что в Java нет беззнаковых байтов, а логические операции всегда находятся между int

Лучший способ работать с байтами - использовать целые числа и каждую операцию выполнять с 0xff. Также используйте >>> для сдвига вправо (это версия без знака)

Пример:

byte b = (byte) (255 & 0xff) // дает вам «беззнаковый байт»

byte b = (byte) ((b ‹---------------- 2) 0xff) // сдвиг влево должен быть усечен

Если вы разместите свой код для расчета CRC, я могу посмотреть на него

Лучший способ определить массив байтов без использования отрицательных чисел выглядит следующим образом:

byte[]={ (byte)0xff, (byte)0xff, (byte)0xff };
person thedayofcondor    schedule 05.11.2012
comment
Привет. Большое спасибо за помощь. И извините за то, что было не так ясно, я постараюсь объяснить подробно. Я отредактировал сообщение, чтобы дать больше информации. - person Esinor I.D.; 05.11.2012
comment
iIndex = ucCRCLo ^ b: подобные операции должны быть записаны как iIndex = (ucCRCLo ^ b) & 0xff, потому что & будет приводить ucCRCLo, b и результат к int, который составляет 32 бита, а короткий - 16, поэтому у вас будет много дополнительные биты установлены на 1 - person thedayofcondor; 05.11.2012
comment
Ok! Еще раз спасибо за помощь. Функция вычисления CRC запущена, но мне по-прежнему не удается связаться с сервером ModBUS. Но я думаю, что проблема внутри сервера, который не может управлять подписанными байтами. Поэтому я буду искать альтернативу установке значений ON. Большое спасибо. - person Esinor I.D.; 05.11.2012
comment
Как вы общаетесь с устройством MODBus? Последовательный, сетевой или что? Есть ли у вас какое-нибудь работающее программное обеспечение для связи с ним? Если да, существует множество инструментов для сниффинга. - person thedayofcondor; 05.11.2012
comment
Я разрабатываю новое программное обеспечение, подключающееся по TCP. Для тестирования я отправляю вычисленные массивы байтов с помощью Hercules, и у меня нет ответа, когда я отправляю отрицательные байты, поэтому я предполагаю, что сервер не управляет ими. Я ищу альтернативу, я попробую использовать другую функцию ModBUS, WriteMultipleCoils, чтобы установить их все вместе, надеясь, что отрицательные байты не понадобятся. - person Esinor I.D.; 05.11.2012
comment
Привет парень! Я решил свою глупую проблему. Это была обычная проблема Java со знаковыми байтами. Моя функция вычисления CRC делает это правильно для беззнаковых байтов, но выдает ошибки, если я передаю внутри подписанные байты. Уловка для работы с байтами для связи ModBUS - это работа во всем приложении с шортами в качестве байтов для диапазона 0-255, даже с вычислением trames и CRC. И только на последнем шаге, при отправке трама на сервер ModBUS, снова преобразовать их в байты. Это работает. Большое спасибо за вашу помощь, это было действительно полезно; Благодарю. - person Esinor I.D.; 09.11.2012
comment
Добро пожаловать! Я могу понять, насколько это неприятно - я использую Java для взаимодействия с множеством низкоуровневых устройств и научился этому! - person thedayofcondor; 09.11.2012