Перейти к содержанию
ODNFC-RS485 Modbus — руководство

ODNFC-RS485 Modbus — руководство

NFC/RFID считыватель-контроллер с интерфейсом RS485 Modbus: подключение, карта регистров, тестирование через mbpoll, исполнение «комбо» 13,56 МГц + 125 кГц, веб-интерфейс, встроенный код, восстановление и обновление.

ODNFC-RS485 — NFC/RFID считыватель-контроллер с интерфейсом RS485 и протоколом Modbus RTU. Подключается в сеть RS485 как ведомое устройство; при необходимости можно реализовать другой протокол на базе RS485. Прошивка — Lua, логику работы можно изменить во встроенном редакторе кода.

Для интеграции со СКУД по другому протоколу см. руководство по OSDP. Modbus RTU и OSDP используют один порт RS485 и одновременно не работают.

ODNFC-RS485 Modbus

Быстрый маршрут

НужноРаздел
Подключить A/B, питание, замок и кнопку«Подключение»
Прочитать UID из ПЛК или ПК«Карта регистров Modbus»
Проверить устройство без своей программы«Тестирование через mbpoll»
Подстроить карту регистров под существующий контроллер«Интеграция»
Изменить локальную логику«Встроенный код»
Восстановить устройство«Восстановление устройства»

Пример внедрения в существующую СКУД

  1. Подключите один считыватель короткой линией RS485 и оставьте адрес 1.
  2. Прочитайте тестовую карту через mbpoll или ПЛК.
  3. Проверьте команды «разрешено» и «запрещено» без подключённого замка.
  4. Подключите замок через подходящую схему питания и проверьте ручное управление.
  5. Только после этого добавляйте остальные устройства на шину и назначайте им уникальные адреса.

Такой порядок отделяет ошибки линии RS485 от ошибок адресации, логики и силовой части замка.

Ключевые возможности

  • Поддерживаемые метки. Метки 13,56 МГц: MIFARE Classic 1K/4K/Mini, MIFARE Ultralight, Ultralight Nano, NTAG 213/215/216, S50/S70 — полная поддержка; Ultralight C — только чтение UID. Во встроенной Lua-программе для меток 125 кГц доступны UID EM-Marine EM4100 и HID ProxCard II, распознавание T55xx-копий, а для подготовленных ATA5577 — Trace ID и ротация токена. Может стоять один интерфейс или оба одновременно.
  • Работа по RS485 Modbus. Устройство — ведомое в сети Modbus. Одновременно можно использовать Wi-Fi (не основной интерфейс). Есть встроенный веб-интерфейс для настройки.
  • Совместимые бесконтактные карты — идентификатор, который отдаёт физическая карта. Мобильный кошелёк может выдавать отдельное и меняющееся значение, а обычный пропуск в Apple Wallet или Google Wallet не становится совместимой NFC-картой автоматически. Подробнее — в статье «Телефон как пропуск».
  • Изменяемая логика во встроенном редакторе.
  • Дискретный вход и выход — вход для кнопки и выход для управления замком. Проверьте допустимый ток, напряжение и защиту индуктивной нагрузки.
  • Управляемая индикация — звуковой излучатель и RGB-светодиод; можно подключить адресную ленту и создавать собственные эффекты. Оценка «до 64 светодиодов» приблизительная: допустимые количество и яркость определяются током ленты и возможностями внутреннего преобразователя.
  • Локальное хранение данных — автономная работа или синхронизация с сервером.

Лицевая панель покрыта тонкой защитной транспортировочной плёнкой (это не царапины). Удалите её перед установкой.

Подключение

Назначение выводов:

  • A, B — линии RS485;
  • GND — «земля»;
  • IN — сигнальный входной контакт;
  • OUT+ — «+» исполнительного устройства / замка (напряжение равно напряжению питания);
  • OUT− — «−» исполнительного устройства / замка;
  • +12V — питание, допустимо 7–24 В.

Группа отверстий «GND, OUT, +5» на плате служит для разъёма адресной ленты вместо встроенных светодиодов. При запуске контакты GND-OUT выполняют функцию HARD RESET.

Подключение ODNFC-RS485

Настройки порта по умолчанию: 115200 8N1, адрес устройства: 1.

Карта регистров Modbus

Согласно спецификации Modbus, регистры хранения занимают адреса 40001–49999, но передаваемый адрес относительный (0 для 40001, 1 для 40002 и т. д.). Здесь используются относительные адреса (с нуля).

Стандартная программа исполнения «комбо» использует следующую карту:

АдресаНаправлениеНазначение
0x00..0x03чтениеUID метки 13,56 МГц, до 8 байт
0x04..0x06чтениеUID EM-Marine 125 кГц, 5 байт и нулевое дополнение
0xF0записькоманда замку и индикации
0xF1записькод однократного включения web/Wi-Fi AP
0xF2записьновый адрес ведомого Modbus

UID упакован по два байта на регистр в порядке чтения метки. Например, четырёхбайтный UID занимает регистры 0x00 и 0x01, а семибайтный UID MIFARE Ultralight 34772FC11139E7 представлен как [0x3477, 0x2FC1, 0x1139, 0xE700].

Регистры UID работают как очередь события: после успешного чтения затронутые регистры обнуляются, а при следующем обнаружении метки заполняются снова. Считыватели 13,56 МГц и 125 кГц опрашиваются по очереди, поэтому отдельный опрос может вернуть нули даже при постоянно приложенных метках. Читайте одним запросом диапазон 0x00..0x06, обрабатывайте ненулевые области независимо и не считайте нулевой ответ потерей связи.

Команды регистра 0xF0:

  • 1 — открыть замок, включить положительную световую и звуковую индикацию;
  • 2 — закрыть замок, включить отрицательную световую и звуковую индикацию;
  • 3 — закрыть замок без изменения индикации.

Для включения веб-интерфейса запишите в 0xF1 последние два байта MAC-адреса устройства как 16-битное число. Неверный или нулевой код игнорируется. Команда также игнорируется, если веб-интерфейс отключён настройкой sys_web или уже был запущен.

Регистр 0xF2 принимает только адреса 1..247. При корректном значении устройство сначала закрывает замок, сохраняет новый адрес и перезагружается. Значения вне диапазона регистрируются в отладочной консоли и не применяются.

Поведение устройства можно изменить во встроенном редакторе кода.

Тестирование через mbpoll

Для работы используем кроссплатформенную утилиту mbpoll.

Для первичной проверки используйте преобразователь USB–RS485 с надёжным драйвером и гальванической развязкой. Нестабильный адаптер может выглядеть как ошибка считывателя или линии.

# Чтение метки
mbpoll -m rtu -a 1 -r 0 -0 -c 7 -t 4:hex -b 115200 -P none -l 500 -o 0.5 /dev/ttyUSB0

# Разрешено
mbpoll -R -m rtu -a 1 -r 240 -0 -b 115200 -P none -1 -o 0.5 /dev/ttyUSB0 1
# Запрещено
mbpoll -R -m rtu -a 1 -r 240 -0 -b 115200 -P none -1 -o 0.5 /dev/ttyUSB0 2
# Закрыть замок
mbpoll -R -m rtu -a 1 -r 240 -0 -b 115200 -P none -1 -o 0.5 /dev/ttyUSB0 3

# Включить web (значение зависит от s/n)
mbpoll -R -m rtu -a 1 -r 241 -0 -b 115200 -P none -1 -o 0.5 /dev/ttyUSB0 0x3709
# Сменить адрес с 1 на 2
mbpoll -R -m rtu -a 1 -r 242 -0 -b 115200 -P none -1 -o 0.5 /dev/ttyUSB0 2

Чтение UID по Modbus

Преобразование UID в напечатанный номер

На карте бывает напечатан номер, не совпадающий с UID. В общем руководстве «UID и номер карты: форматы, Wiegand и преобразование» приведены прямой и обратный порядок байтов, десятичные варианты, Wiegand 26 и другие профили, формулы для таблиц и примеры для Lua и MicroPython.

Исполнение «комбо» (два интерфейса)

Укладка данных «комбо» в регистры

Когда активны оба интерфейса (13,56 МГц и 125 кГц), данные метки 125 кГц укладываются начиная с регистра 4 — читать нужно вдвое больше регистров. При включённом чтении HID добавляется ещё 4 регистра. Форматы передачи и упаковку в регистры можно изменить под логику вашего контроллера.

Чтение меньшего диапазона регистров не отключает физический считыватель: стандартная Lua-программа всё равно чередует оба интерфейса. Если один из них не установлен или не нужен, удалите соответствующий вызов mfrc522.scan() или emmarine.uid() из программы и уберите чередование.

Веб-интерфейс

Веб-интерфейс нужен только для изменения кода или настроек, недоступных по Modbus. Чтобы его включить, запишите в регистр 0xF1 два последних байта серийного номера — устройство поднимет Wi-Fi-сеть вида odnfc-[s/n].

Основной экран показывает состояние соединения, время работы, доступную память и сообщения программы.

Экран настроек меняет основные настройки. Часть из них (Формат, Тип ключа, Ключ, Получатель) предназначена для пользовательской программы. Пароль и отключение веб-интерфейса ограничивают доступ в общей сети (пароль передаётся в открытом виде). HTTPS работает с самоподписанными сертификатами — медленнее и с ручным подтверждением в браузере. WebSocket REPL открывает удалённый доступ (IDE lua.unitx.pro и плагин VS Code).

Редактор кода позволяет менять файл usercode.lua, который загружается автоматически. Для больших проектов используйте консоль, онлайн-среду или плагин VS Code.

Экран файлов показывает дополнительные файлы каталога /public. Здесь их можно загрузить, скачать, обновить или удалить. Системные файлы веб-интерфейса и автозапуска защищены от операций через этот список.

Экран системы показывает модель устройства, версию прошивки и серийный номер. На этом же экране загружается файл обновления .ufl или .dfu; во время записи не отключайте питание.

Технические характеристики

  1. Дальность считывания: до 6–10 см (зависит от качества метки).
  2. Габариты: 120 × 76 × 22 мм.
  3. Проводные интерфейсы: RS485.
  4. Беспроводные интерфейсы: Wi-Fi.
  5. Индикация: RGB-светодиод, звуковой излучатель.
  6. Вход: один канал (3 В, подтянут к «1»).
  7. Выход: один канал (макс. 1 А), напряжение равно напряжению питания.
  8. Крепление: четыре отверстия M3.

Интеграция

Стандартная прошивка реализует базовые функции Modbus-считывателя: устройство передаёт данные последней метки через заданную карту регистров и принимает несколько команд управления. Карту регистров и логику работы можно изменить.

Прикладная логика ODNFC-RS485 программируется на Lua. Например, можно:

  • подстроить адреса регистров и формат данных под уже существующий контроллер или ПЛК, не меняя программу верхнего уровня;
  • читать и записывать нужные блоки или сектора совместимых меток, а результат размещать в выбранных регистрах;
  • добавить собственные области регистров для команд, состояния входа и выхода, диагностических и служебных данных;
  • фильтровать метки непосредственно в считывателе и передавать контроллеру только нужные события;
  • использовать встроенную базу данных для локальной проверки прав и автономного управления доступом;
  • объединить работу с метками, замком, кнопкой, индикацией, базой данных и Modbus в одной программе.

Код можно изменить во встроенном редакторе: например, добавить регистры, изменить правила доступа или формат данных.

Встроенный код (исполнение «комбо»)

Этот код установлен в исполнении «комбо» и доступен во встроенном редакторе. Конкретная версия может отличаться в зависимости от исполнения и прошивки. Скачать исходник usercode.lua.

local get, set = Settings.get, Settings.set
local setregs, setregs8 = modbus.setregs, modbus.setregs8
local getvalues, sleepms = modbus.getregsvalues, thread.sleepms

local lock_pin = pio.GPIO16
pio.pin.setdir(pio.OUTPUT, lock_pin)

local function lock() pio.pin.setval(1, lock_pin) end
local function unlock() pio.pin.setval(0, lock_pin) end

lock()

local leds = indication.RGBLeds.new { ledPin = pio.GPIO32 }
local snd = indication.Sound.new(pio.GPIO21)
local wdt_on = get("sys_wdt") == "on"

local parity = get("rs485_parity")
parity = parity == "EVEN" and 2 or parity == "ODD" and 3 or 0

modbus.rtu.init(
  tonumber(get("rs485_addr")), nil, nil, nil, nil,
  tonumber(get("rs485_baudrate")), parity
)

-- Карта регистров:
--   0..3 — HF UID, максимум 8 байт;
--   4..6 — EM-Marine UID, 5 байт;
--   F0   — управление: разрешено/запрещено;
--   F1   — код включения web/AP;
--   F2   — новый Modbus-адрес.

local function set_hf_uid(...)
  if select("#", ...) > 8 then
    eprint("MFRC522: 10-byte UID does not fit registers 0..3")
    return
  end
  -- Очищаем старый хвост 7-байтного UID.
  setregs(0, 0, 0, 0, 0)
  setregs8(0, ...)
end

local web_started = false
local mac = cpu.getmac(0, 1)
local web_code = mac and tonumber(mac:sub(-4), 16)

local function start_web(code)
  if web_started or not web_code or code ~= web_code then return end

  if get("sys_web") ~= "on" then
    eprint("Web interface is disabled by sys_web")
    return
  end

  pcall(net.wf.stop)

  local ok, err = pcall(function()
    net.wf.setup(
      net.wf.mode.AP, get("net_ssid"), get("net_password"),
      net.wf.powersave.NONE, 4, false
    )
    net.wf.start()
  end)
  if not ok then
    eprint("Web interface start failed: " .. tostring(err))
    return
  end
  web_started = true
end

leds:start()
snd:start()

local em_reader = emmarine.new()
local scan_mfrc = true

local function iteration()
  local ok, err

  if scan_mfrc then
    ok, err = mfrc522.scan(nil, nil, nil, nil, 0, set_hf_uid)
  else
    ok, err = emmarine.uid(em_reader, setregs8, 4)
  end

  scan_mfrc = not scan_mfrc

  if ok == false then
    eprint((scan_mfrc and "EM-Marine: " or "MFRC522: ") .. tostring(err))
  end

  local action, web_pwd, new_addr = getvalues(0xf0, 3, true)

  if action == 1 then
    unlock()
    leds:ok()
    snd:ok()
  elseif action == 2 then
    lock()
    leds:err()
    snd:err()
  elseif action == 3 then
    lock()
  end

  if web_pwd and web_pwd ~= 0 then
    start_web(web_pwd)
  end

  if new_addr and new_addr ~= 0 then
    if new_addr >= 1 and new_addr <= 247 then
      lock()
      set("rs485_addr", tostring(new_addr))
      os.exit()
    else
      eprint("Invalid Modbus address: " .. tostring(new_addr))
    end
  end
end

while true do
  if wdt_on then cpu.watchdog.reset() end

  local ok, err = pcall(iteration)

  if not ok then
    local message = tostring(err)

    if message:find("interrupted!", 1, true) then
      error(err, 0)
    end
    eprint("Main loop: " .. message)
    sleepms(250)
  else
    sleepms(100)
  end
end

Восстановление устройства

  1. Выключите устройство.
  2. Замкните контакты HARD RESET или RECV на плате (зависит от ревизии).
  3. Включите устройство, удерживая контакты замкнутыми.
  4. Подождите несколько секунд (затем контакты можно разомкнуть).
  5. Устройство создаст Wi-Fi-точку доступа OD-[серийный номер] без пароля.
  6. Через веб-сервер и telnet измените настройки или программу. Wi-Fi IP-адрес: 192.168.4.1.

Обновление устройства

  1. Откройте вкладку «Настройки», отключите сторожевой таймер и перезагрузите устройство.
  2. Откройте вкладку «Система», нажмите «Из файла» и выберите прошивку.
  3. Нажмите «Загрузить» — устройство перезагрузится.
  4. Убедитесь, что отображается нужная версия прошивки.

Дополнительные материалы

История обновлений 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 теперь распространяется отдельно.