
ODNFC-RS485 OSDP — быстрый старт для интегратора
Подключение ODNFC-RS485 к контроллеру СКУД по OSDP: роли CP/PD, проверка линии, события карты, команды, защищённый канал и диагностика.
ODNFC-RS485 OSDP подключается к контроллеру СКУД по двухпроводной линии RS485 и работает в роли Peripheral Device (PD). Контроллер доступа выполняет роль Control Panel (CP): регулярно опрашивает считыватель, принимает события карты и отправляет команды выходу, световой и звуковой индикации.
Это руководство помогает сначала проверить физическую линию и обычный обмен OSDP, а затем включить защищённый канал Secure Channel (SC). Для стендовой проверки дан минимальный Python-клиент CP.
Что даёт OSDP
OSDP — специализированный протокол для связи контроллеров доступа с периферийными устройствами. Он опубликован как международный стандарт IEC 60839-11-5 и поддерживает двусторонний обмен, контроль доступности устройств и защищённый канал с шифрованием и аутентификацией.
В исполнении ODNFC-RS485 доступны:
- события чтения карты в стандартном формате OSDP;
- идентификация PD и объявление его возможностей;
- команды управления выходом, светодиодом и звуковым излучателем;
- отчёты о состоянии входов, выходов, питания и корпуса — конкретный набор зависит от установленной прикладной программы;
- OSDP Secure Channel с шифрованием и аутентификацией AES-128;
- несколько PD с разными адресами на общей линии RS485;
- изменение и расширение поведения на Lua.
OSDP или Modbus RTU
| Задача | Выбор |
|---|---|
| Подключение к контроллеру СКУД с поддержкой OSDP | OSDP |
| Стандартные события карты, команды индикации и выхода, контроль связи | OSDP |
| Нужен защищённый канал между контроллером и считывателем | OSDP + Secure Channel |
| Подключение к ПЛК, SCADA или существующей карте регистров | Modbus RTU |
| Центральная система не поддерживает роль OSDP CP | Modbus RTU или доработка системы |
OSDP не становится защищённым автоматически. До настройки Secure Channel обмен идёт без шифрования. Modbus RTU, в свою очередь, не определяет встроенную аутентификацию или шифрование вообще.
Перед началом
Подготовьте:
- ODNFC-RS485 с прикладной программой OSDP;
- источник питания 7–24 В;
- контроллер СКУД с ролью OSDP CP или преобразователь USB–RS485 для стенда;
- витую пару для A/B и общий GND;
- адрес PD, скорость линии и состояние Secure Channel;
- индивидуальный 16-байтный SCBK для штатной защищённой работы.
В примерах ниже используются адрес 101, 9600 бит/с, 8N1 и обычный незащищённый обмен. Это параметры тестового стенда, а не универсальные заводские настройки. Используйте значения, указанные для вашего устройства или согласованные при заказе.
1. Соберите стенд
Для первой проверки подключайте один считыватель и не подключайте замок:
- A считывателя к A преобразователя или контроллера;
- B к B;
- GND к общему GND;
- питание к +12V и GND; допустимый диапазон питания — 7–24 В.

Если обмена нет, один раз поменяйте A/B местами: маркировка встречается инвертированной. На длинной линии используйте шинную топологию без длинных ответвлений и согласование на концах линии. На общей шине должен быть только один CP.
2. Проверьте считыватель с ПК
Скачайте два файла в одну папку:
- osdp_cp_client.py — минимальный OSDP Control Panel;
- osdp_wire.py — формирование и разбор кадров.
Нужен Python 3 и пакет pyserial.
Linux и macOS
python3 -m venv .venv
source .venv/bin/activate
python -m pip install pyserial
Порт обычно называется /dev/ttyUSB0, /dev/ttyACM0 или
/dev/cu.usbserial-*. Посмотреть подходящие устройства можно так:
ls /dev | grep -E '^(ttyUSB|ttyACM|cu\.usb)'
Windows PowerShell
py -m venv .venv
.venv\Scripts\python -m pip install pyserial
Имя порта (COM3, COM5 и т. п.) видно в диспетчере устройств Windows.
Запуск теста
Linux/macOS:
python osdp_cp_client.py \
--port /dev/ttyUSB0 --baud 9600 --address 101 \
--output --led --polls 200
Windows:
.venv\Scripts\python osdp_cp_client.py `
--port COM5 --baud 9600 --address 101 `
--output --led --polls 200
Замените порт, адрес и скорость своими значениями. Во время опроса поднесите
карту. Перед использованием --output убедитесь, что к выходу не подключён
замок или другая нагрузка, которую нельзя кратковременно переключать.
Ожидаемый результат:
PDID— считыватель ответил своей идентификацией;PDCAP— перечислены поддерживаемые возможности;ISTATRили другой status reply — линия и прикладной обработчик работают;ACKпосле командoutputиLED— команда принята;RAWпосле поднесения карты — получено событие с данными карты.
Например:
reply PDID ...
pdid vendor=0x...... model=... version=... serial=... fw=...
reply PDCAP ...
cap fc=... level=... items=...
reply ACK
reply RAW ...
Python-клиент намеренно реализует только небольшой незащищённый набор OSDP. Он проверяет UART/RS485, адрес, кадры, CRC и базовые команды, но не проверяет Secure Channel, установку ключа, передачу файлов, несколько PD на общей линии или соответствие всему стандарту OSDP. Его нельзя использовать как CP в рабочей СКУД или как доказательство сертификации.
3. Подключите штатный контроллер СКУД
- Настройте на CP тот же адрес, скорость и формат линии.
- Убедитесь, что CP видит PD на связи и читает его идентификатор и заявленные возможности.
- Поднесите несколько карт разных типов и сверьте длину и порядок байтов идентификатора с требованиями системы.
- Проверьте команды LED, buzzer и output. ACK означает, что команда принята, но фактическую реакцию также нужно проверить на устройстве.
- Проверьте восстановление обмена после отключения и включения питания PD.
- После обычного обмена в контролируемом стенде настройте Secure Channel.
Если контроллер использует собственный профиль OSDP, заранее сверьте требуемые возможности и формат событий чтения карты. Поддержка самого протокола не означает, что обе стороны автоматически используют одинаковый набор необязательных функций.
4. Включите Secure Channel
Для штатной эксплуатации используйте отдельный случайный SCBK для каждого
устройства. Один и тот же бинарный ключ длиной 16 байт должен быть сохранён на
PD и CP. Не публикуйте ключ, не храните его в общем примере и не используйте
тестовое значение 0123456789ABCDEF на объекте.
Если ключ уже записан
Настройте обе стороны с одинаковым SCBK и включите режим обязательного
защищённого обмена. В Lua API это флаг OSDP_FLAG_ENFORCE_SECURE. После запуска
проверьте не только наличие PD на связи, но и активное состояние Secure Channel.
Первичная запись нового ключа
Выполняйте ввод в эксплуатацию только на физически контролируемом стенде:
- Запустите PD без рабочего SCBK с флагом
OSDP_FLAG_INSTALL_MODE. - На CP укажите желаемый новый 16-байтный SCBK и включите такой же режим установки.
- CP и PD временно установят канал через стандартный SCBK-D, после чего LibOSDP передаст новый ключ командой KEYSET и повторно установит канал.
- Дождитесь подтверждения, что Secure Channel активен. Сеанс на SCBK-D не считается защищённым рабочим каналом.
- Отключите режим установки и перезапустите обе стороны с новым ключом и обязательным Secure Channel.
Не сочетайте режим установки с обязательным защищённым обменом
(enforce-secure) в одной конфигурации и не оставляйте режим установки
включённым после ввода устройства в эксплуатацию. Минимальный Python-клиент из
предыдущего раздела эту процедуру не выполняет — используйте штатный CP либо
полноценную реализацию OSDP.
Несколько считывателей на одной линии
- назначьте каждому PD уникальный адрес;
- используйте одинаковую скорость и формат 8N1;
- подключайте устройства общей шиной, а не звездой;
- храните соответствие «адрес — серийный номер — место установки — SCBK»;
- проверяйте связь и Secure Channel отдельно для каждого PD;
- сначала отладьте каждое устройство на короткой одиночной линии, затем собирайте общую линию с несколькими устройствами.
В Lua-конфигурации CP все PD одной физической линии используют одинаковый
положительный channel_id, но разные OSDP-адреса. Для независимой линии нужен
другой channel_id.
Переключение между Modbus и OSDP
ODNFC-RS485 поддерживает Modbus и OSDP, поэтому протокол можно менять прикладной программой. Но один UART/RS485 нельзя одновременно занимать двумя драйверами. Перед переключением остановите текущий протокол, освободите UART и только затем запускайте другой.
Диагностика
| Симптом | Что проверить |
|---|---|
Только timeout | Питание, A/B, общий GND, порт ПК, адрес, скорость, DE/RE преобразователя |
| CRC/checksum errors | Помехи, согласование линии, ведущий mark byte 0xFF, качество USB–RS485 |
Есть PDID, но нет RAW | Прикладную программу чтения карты, формат события и время опроса |
| Команды получают NAK | Заявленные возможности, номер выхода или светодиода и допустимый код управления |
| PD периодически теряет связь | Топологию, ответвления, два CP на линии, питание и тайм-ауты |
| Secure Channel не устанавливается | Точное совпадение 16 байт SCBK, флаги, этап ввода ключа и заявленная поддержка защиты |
| После смены адреса пропала связь | Новый адрес и скорость на CP; сохранение COMSET выполняют после подтверждения команды |
Дополнительные материалы
- Кнопка, замок, реле, второй считыватель и адресная RGB-лента
- Полный API модуля OSDP в Lua
- ODNFC-RS485 Modbus: подключение и карта регистров
- Программирование ODNFC на Lua
- Описание OSDP от Security Industry Association
Для согласования адресов, SCBK и профиля команд до поставки свяжитесь с инженером UnitX.
История обновлений ODNFC на Lua
Если установлена версия ниже 1.7.0, сначала обновите её до 1.7.0, а затем до более новой версии. Перед обновлением отключите сторожевой таймер и сотрите пользовательскую программу.
1.8.2
- Улучшена работа устройства и исправлены ошибки.
- Для устройств, работающих с метками 125 кГц, добавлено обнаружение типовых клонов EM-Marine.
1.8.1
Улучшения:
- Новый веб-интерфейс.
- Улучшена работа RFID-модулей MFRC и EM-Marine.
- Улучшена работа Modbus.
- Оптимизирована работа устройства.
1.7.0
Улучшения:
- улучшена работа MFRC и EM-Marine;
- в раздел «Редактор» добавлен простой файловый менеджер;
- улучшена работа сетевых модулей;
- оптимизирована работа устройства.
Исправлена ошибка в HTTP-заголовке Content-Length, из-за которой интерфейс не
работал в некоторых операционных системах.
1.6.2
- Улучшена работа MFRC и EM-Marine.
- Улучшена библиотека Modbus.
- Оптимизирована работа устройства.
- В ODNFC-LAN-LUA добавлена регистрация обработчика успешного чтения.
1.6.1
- Добавлена запись в зашифрованные карты MIFARE Classic.
- Упрощена инициализация RFID: используются значения по умолчанию для каждой
платы, поэтому изменён вызов основного класса и больше не требуются многие
Lua-обёртки из
rfid.lua. - Добавлена функция
mfrc522.scan()— упрощённая версия базового класса для типовых операций. - Исправлены библиотеки EM-Marine и HID.
- Оптимизирована библиотека Modbus.
- Исправлена работа TCP-сервера.
1.6.0
Улучшения:
- обновлён редактор кода: устранена проблема с переводами строк в новых версиях Firefox;
- в веб-сервер добавлена поддержка HTTPS и WebSocket;
- добавлены новые классы для работы с RFID-метками;
- добавлена работа с NDEF и счётчиками Ultralight;
- добавлены встроенные библиотеки
cbor,cobs,mlib, Heatshrink иmicrotar; - расширены библиотеки
osc,net,cutils,utils,cpuиemmarine; - LuaSocket больше не входит в прошивку;
- добавлена загрузка сжатых Heatshrink-библиотек Lua;
- добавлен WebSocket REPL для отладки через веб-IDE или расширение VS Code;
- улучшена консоль: Unicode, автодополнение и история;
- расширена поддержка Modbus;
- Paho MQTT заменён собственной реализацией uMqtt;
- ускорена работа устройства и веб-интерфейса;
- выполнены другие небольшие исправления и оптимизации.
Исправлены ошибки, из-за которых после мягкой перезагрузки Wi-Fi запускался через раз, а RFID-модуль мог не инициализироваться.
1.5.0
Улучшения:
- новый интерфейс и редактор кода;
- добавлена библиотека
tinycobs; - добавлены функции
net.tcp.*; - добавлены функции
eprint,hprintиwprintдля вывода в окно «Инфо»; - трассировка ошибки загрузки теперь показывается в окне «Инфо»;
- расширены возможности Telnet, SSH отключён;
- в режиме восстановления Wi-Fi работает без пароля;
- добавлена поддержка BLE-маяков на устройствах с BLE;
- NTP запускается с задержкой 15 секунд, чтобы сеть успела установиться.
Исправлены режим статического Ethernet-адреса и установка яркости NeoPixel.
1.4.0
- Улучшен встроенный веб-сервер.
- Выполнены небольшие изменения для повышения стабильности.
- Исправлена утечка памяти при HTTP-запросах из Windows.
Известная проблема этой версии: режим статического Ethernet-адреса в настройках не работает. Для обхода проблемы в начало пользовательской программы добавляли:
net.en.setup(
net.packip(Settings.get("net_ip")),
net.packip(Settings.get("net_mask")),
net.packip(Settings.get("net_gw")),
net.packip(Settings.get("net_dns"))
)
net.en.start()
1.3.2
- В
os.df()добавлен дополнительный параметр. - Выполнены небольшие изменения для повышения стабильности.
- Исправлена утечка памяти при запросе метрики в интерфейсе.
Известная проблема этой версии: HTTP-запросы из Windows приводят к утечке памяти. После изменения настроек рекомендовалось закрыть браузер, перезагрузить устройство и не выполнять периодические HTTP-запросы.
1.3.1
- Серийный номер синхронизирован с DataMatrix на корпусе модуля, если он есть.
1.3
- Библиотека
Telegram.luaдобавлена в прошивку. - Библиотека LuaSocket теперь распространяется отдельно.