CAT CI-V интерфейс для ICOM IC-820 на Arduino

Дмитрий DarkByte Москин

Мой блог, да.
logo

CAT CI-V интерфейс для ICOM IC-820 на Arduino

Опубликовано 30.08.2016 автором Дмитрий Москин
Для подключения внешних устройств к трансиверу ICOM IC-820 потребовалось разобраться с протоколом CI-V. Сначала попытался найти рабочую программу для CAT интерфейса под Windows, но оказалось, что 9 программ из 10 не смогли установить связь с данным трансивером, хотя его поддержку заявляли. Когда я уже начал грешить на CAT адаптер, заработала программа CI-V Commander.



Из доступного функционала в программе обнаружилась возможность смотреть и менять текущую частоту и вид модуляции основного приёмника. Конечно же хотелось бы чуть большего, как минимум иметь возможность видеть все те параметры, которые доступны на дисплее трансивера, и кроме того получать сырые данные о излучаемой и принимаемой мощности, а также иметь возможность включать и блокировать передачу.

Но ничего этого CAT интерфейс IC-820 не умеет. Но для начала интересно было просто получить текущую частоту с целью определить активный в данный момент диапазон. В случае с Yaesu эта задача решается проще, за счёт наличия в разъёме ACC/CAT пинов Band A-B-C-D, а в данном трансивере единственная возможность получить подобную информацию - подключиться к CAT.

В отличии от CAT других производителей, интерфейс CI-V работает в полудуплексном режиме на скоростях 1200/4800/9600/19200 бод и позволяет на одну линию подключить до 225 устройств, из которых одно устройство будет контроллером. Из готовых реализаций под Atmega получилось найти код от UA0LTB, из него стало примерно понятно, как устроен протокол, но код работал медленно и не совсем корректно.

На подбор настроек (скорость порта и его адрес в шине CAT) трансивера код мог затратить до 10 минут, а текущая частота и модуляция запрашивались в бесконечном цикле создавая лишнюю нагрузку на контроллер, CAT линию и сам трансивер. Кроме того, ответы IC-820 оказались отличными от шаблонов "правильных" ответов, забитых в код, поэтому код и вовсе не смог найти трансивер.

В простейшем случае можно рассмотреть протокол на основе команды запроса частоты и модуляции:
>FE FE 42 E0 03 FD
<FE FE E0 42 03 00 00 60 45 01 FD
>FE FE 42 E0 04 FD
<FE FE E0 42 04 05 01 FD


Каждый пакет начинается с двух стартовых байтов 0xFE и оканчивается байтом 0xFD. Следом за стартовыми байтами идут два байта адресации, первый указывает адрес источника пакета, второй - адрес получателя. В данном случае 0x42 - адрес трансивера, а 0xE0 - фиксированный адрес контроллера, кроме того, адрес получателя может быть 0x00 - что означает широковещательный запрос, адресуемый всем. После адреса указывается код команды: 0x03 для запроса частоты, 0x04 для запроса модуляции.

Команда может состоять больше, чем из одного байта. Например, для запроса показаний S-метра передаётся 0x15 0x02, это актуально для более новых моделей, например, IC-910, в IC-820 такого функционала нет. Ответ на команду имеет тот же формат, но после кода команды следует фиксированное количество байт результата выполнения команды. Например, частота просто пишется в ASCII-HEX (или BCD, как его называет ICOM), 01 45 60 00 00 соответствует частоте 145.600.000. Вид модуляции указывается в первом байте порядковым номер из списка LSB, USB, AM, CW, FSK, FM, WFM, второй байт: 0x01 - Wide, 0x02 - Medium, 0x03 - Narrow.

В коде UA0LTB используется перебор скоростей и адресов трансивера для поиска нужных настроек, это занимает слишком много времени, хотя и результат сохраняется в EEPROM, что позволяет ускорить повторные включения. Но его можно значительно ускорить. Самое простое, что приходит в голову - отправить сразу пачку пакетов для всех возможных адресов в линии и только после этого читать ответ. Трансивер ответит на свой адрес и укажет его в пакете. Таким образом скорость поиска трансивера на одной скорости сократится в 225 раз.

Но кроме того, можно обойтись совсем без перебора. Если отправить запрос на широковещательный адрес 0x00, то ответят все устройства на линии, и соответственно для поиска трансивера потребуется отправлять в линию в 225 раз меньше данных, что позволяет отказаться от использования EEPROM и искать трансивер при каждом включении.

Кроме того, нет необходимости постоянно спрашивать у трансивера текущую частоту и модуляцию, ибо при их изменении он сам об этом сообщает отправкой широковещательного пакета. При смене местами main и sub приёмника трансивер отправит сразу два пакета, об изменении частоты и модуляции, даже если модуляция осталась прежней. Пакет ответа будет отличаться от подобного запроса только адресом (0x00, вместо 0xE0) и кодом команды (0x00 для частоты, и 0x01 для модуляции), например:
<FE FE 00 42 00 <00 00 56 45 01> FD 
<FE FE 00 42 01 <00 01> FD


В написанном мною коде не учтены некоторые особенности протокола, о которых можно прочитать в мануале по ICOM CI-V. Это будет актуально при адаптации кода под различные трансиверы, а также расширении функционала поддерживаемых команд. В случае с IC-820 поддерживаемых команд не так много, да и для решения моей задачи они не нужны. По умолчанию у IC-820 адрес 0x42, но его можно изменить в настройках.

Код можно скачать по ссылке icom-ic820-cat.ino. Это просто тестовый код, который общается с трансивером и выводит в UART информацию о частоте и модуляции. Его можно использовать и изменять без каких-либо ограничений. Кроме библиотек Serial и SoftwareSerial ничего больше от Arduino в коде не используется, поэтому его легко переделать под Atmel AVR Studio.