Hardware / IoT

RS485

Android-модуль для аппаратных POS-терминалов и киосков самообслуживания, обеспечивающий двусторонний обмен данными по промышленной шине RS485 в режиме полудуплекса. Приложение работает как ведомое устройство на общей шине: принимает запросы от ведущего контроллера, фильтрует кадры по адресу, проверяет и формирует контрольную сумму и отвечает в реальном времени. Решение поддерживает скорости передачи вплоть до 1 Мбод, гибкую настройку адреса и канала, а также автоматически адаптируется под более чем десяток аппаратных моделей терминалов на единой кодовой базе.
Android Studio Java

Задача

Требовалось организовать устойчивую связь терминала с внешним промышленным оборудованием по двухпроводной шине RS485. Специфика задачи задавала сразу несколько жестких ограничений:
  • Полудуплексный канал на одной паре проводов, где прием и передача физически разделены во времени и направление шины нужно переключать в точно выверенный момент, иначе возникают коллизии и потеря кадров.
  • Бинарный протокол на базе Modbus RTU с нестандартным вариантом расчета контрольной суммы, который требовалось воспроизвести байт в байт для совместимости с ведущим контроллером.
  • Работа поверх закрытого аппаратного SDK вендора с собственным набором каналов RS485 и режимов направления.
  • Единый код должен корректно запускаться на широком парке устройств с разной аппаратной конфигурацией без ручной перенастройки под каждую модель.

Решение

Реализована полноценная логика ведомого устройства на шине. Входящий поток данных обрабатывается через колбэк-механизм SDK в фоновом потоке, кадры разбираются и фильтруются по заголовку и адресу устройства, после чего на валидный запрос формируется ответ.
Ключевые элементы реализации:
  • Точная репликация протокольной арифметики: расчет CRC16 на рефлектированном полиноме 0xA001, последующая инверсия всех битов и перестановка байт в порядок little-endian. Это обеспечило побитовую совместимость ответа с ожиданиями ведущего контроллера.
  • Синхронное управление направлением шины. Переключение в режим передачи выполняется строго на время отправки ответа, после чего канал немедленно возвращается в режим приема, что исключает наложение сигналов на полудуплексной линии.
  • Адресная фильтрация на общей шине: устройство реагирует только на кадры, адресованные ему, и игнорирует чужой трафик, корректно работая в многоустройственной топологии.
  • Динамическое построение списка доступных каналов RS485 из констант SDK через рефлексию, без жесткого зашивания значений в код.
  • Автоматическое определение модели терминала и подстановка профиля поддерживаемой периферии, благодаря чему одна сборка покрывает весь парк устройств.

Архитектура и сложности

Самой тонкой частью стала временная диаграмма полудуплекса. Между моментом приема кадра, переключением направления и отправкой ответа нет права на ошибку: преждевременное или запоздалое переключение приводит к тому, что ведущий не видит ответ. Логика построена так, что смена режима привязана к жизненному циклу обработки конкретного кадра, а не к таймерам, что делает обмен детерминированным.
Отдельного внимания потребовала потоковая модель. Данные приходят асинхронно в фоновом потоке SDK, тогда как обновление интерфейса и индикация направления должны выполняться в UI-потоке. Разнесение этих ответственностей через корректную диспетчеризацию на главный поток убрало гонки и подвисания интерфейса при интенсивном трафике.
Управление жизненным циклом порта реализовано идемпотентно: при любой смене канала или скорости порт сначала корректно освобождается и только затем открывается заново с новыми параметрами, что исключает утечку дескрипторов и зависание шины. Поддержан полный диапазон из 11 скоростей передачи, от 9600 бод до 1 Мбод, и 8 адресов устройств на шине.
Дополнительный пласт сложности добавила работа на системном уровне с привилегированными разрешениями и закрытым вендорским SDK, поведение которого приходилось выяснять опытным путем и аккуратно оборачивать в предсказуемые сценарии.

Результат

  • Стабильный двусторонний обмен по RS485 на скоростях до 1 Мбод с корректной работой протокола контрольной суммы и нулевыми коллизиями на полудуплексной линии.
  • Единая кодовая база, без изменений работающая более чем на десяти моделях терминалов за счет автоматического определения аппаратной конфигурации.
  • Детерминированное переключение направления шины, снявшее проблему пропадания ответов, которая характерна для наивных реализаций полудуплекса.
  • Гибкая среда для интеграции и диагностики: оперативная смена адреса, канала и скорости с визуальным контролем принятых и отправленных кадров в шестнадцатеричном виде, что заметно ускорило ввод оборудования в эксплуатацию.

Стек

Java, Android SDK (minSdk 24, targetSdk 34), Gradle. Аппаратный SDK вендора POS-оборудования для доступа к RS485 и RS232. Протокол на базе Modbus RTU, расчет CRC16 (полином 0xA001). Многопоточность и колбэк-модель ввода-вывода, диспетчеризация в UI-поток, рефлексия для динамической конфигурации, работа на системном уровне с привилегированными разрешениями Android. 
Сюда Туда