Перейти к содержанию

Интеграция ODRFID-M/N/E через AT-команды

Практическая интеграция USB-считывателей ODRFID-M, ODRFID-N и ODRFID-E со сторонним ПО через CDC: команды, ответы, режимы SCAN0–3 и примеры на Python.

ODRFID-M/N/E можно подключить к собственной программе как виртуальный последовательный порт USB CDC. Считыватель принимает текстовые AT-команды и возвращает строки с данными карты. Этот вариант подходит для 1С, учётных систем, терминалов доступа, сервисов на Python, C#, Java и любого другого ПО, которое умеет работать с COM-портом.

Если нужен только ввод UID в активное поле Excel, 1С или браузера, проще использовать режим USB HID. AT-команды нужны, когда программа должна сама получать события, различать появление и удаление карты, опрашивать несколько меток или читать память.

Подготовка

  1. В ODRFIDConfig включите USB CDC и отключите вывод как HID-клавиатура. Пока включён HID-вывод, события карты направляются в активное поле, а не в CDC-порт.
  2. Подключите считыватель и найдите его порт:
    • Windows: COM3, COM4 и т. п.;
    • Linux: обычно /dev/ttyACM0;
    • macOS: обычно /dev/cu.usbmodem....
  3. Откройте порт только в одной программе. Закройте ODRFIDKit, терминал и другие приложения, которые могли занять тот же порт.
  4. Отправьте ATI и проверьте, что ответ заканчивается строкой OK.

USB CDC принимает настройку скорости порта для совместимости с программами, но в ODRFID-M/N/E она не влияет на обмен. В примерах используется 115200 бод, 8N1.

Формат обмена

  • команда начинается с AT;
  • регистр символов важен: AT+I и AT+i — разные команды;
  • команда завершается CR, LF или CRLF; для совместимости удобно отправлять CRLF;
  • пустые строки в ответе можно пропускать;
  • успешная команда обычно заканчивается строкой OK, неверная — строкой ERROR;
  • ошибка работы с картой может дополнительно вернуть +CME ERROR: <код>, а затем ERROR;
  • в режимах автоматического сканирования события приходят без запроса, поэтому чтение порта должно работать постоянно.

Логический обмен выглядит так:

> ATI
Open Development RFID Reader 3.9m ...
S/N ...
OK

Отдельная команда AT без параметров не используется. Для проверки связи и получения версии отправляйте ATI.

Команды AT+INFO, AT+VERSION, AT+INTERVAL=..., AT+READ=... и AT+WRITE=... не поддерживаются. Используйте ATI, AT+T..., AT+R... и AT+W....

Наиболее используемые команды

КомандаНазначение
ATIверсия прошивки и серийный номер
AT+SCAN?узнать текущий режим автоматического сканирования
AT+SCAN0остановить автоматическое сканирование
AT+SCAN1события появления и удаления одной карты
AT+SCAN2одна строка данных при появлении карты, без события удаления
AT+SCAN3события появления и удаления для нескольких карт
AT+F?прочитать строку форматирования
AT+F=<формат>задать формат данных карты
AT+Pсохранить текущие настройки в энергонезависимой памяти
AT+T?прочитать интервал между опросами, мс
AT+T<мс>задать интервал между опросами
AT+iвыбрать первую найденную карту при SCAN0
AT+nвыбрать следующую HF-карту при SCAN0
AT+Iперечислить все обнаруженные карты при SCAN0
AT+Sполучить UID, SAK, число и размер блоков выбранной карты
AT+R<блок>прочитать блок выбранной HF-карты
AT+W<блок>:<HEX>записать блок выбранной HF-карты
AT+KA<12 HEX>использовать шестибайтный Key A для MIFARE Classic
AT+KB<12 HEX>использовать шестибайтный Key B для MIFARE Classic
AT+G? / AT+G=<дБ>прочитать или задать усиление HF-тракта
AT+L0 / AT+L1отключить или включить штатную светодиодную индикацию
AT+Z0 / AT+Z1отключить или включить штатный звуковой сигнал

Команды чтения и записи памяти, выбора HF-карт и настройки усиления применимы к ODRFID-N и ODRFID-M. ODRFID-E работает с метками 125 кГц и не имеет MIFARE-блоков.

Режимы SCAN0–3

Режим выбирается командой AT+SCAN<номер>. Команда AT+SCAN? возвращает, например:

> AT+SCAN?
+SCAN=1
OK

Данные после SCAN:+ и SCAN:- определяются строкой форматирования. Поэтому программа может получать не только UID, но и заранее подготовленную строку: UID в нужном порядке байтов, номер карты в десятичном виде, данные выбранного блока или постоянный префикс.

SCAN0 — ручное управление

AT+SCAN0 выключает фоновый опрос. Этот режим нужен, когда программа сама решает, когда искать карту, выбирать следующую метку, читать или записывать память.

> AT+SCAN0
OK
> AT+i
+UID=8D430BA408
OK
> AT+S
+UID=8D430BA408,BC=64,BS=16,T=0
OK

В ответах AT+i, AT+n, AT+I и AT+S после UID дописан байт SAK. В примере UID карты — 8D430BA4, а завершающий 08 — SAK. Поле T содержит числовой код типа карты.

Используйте SCAN0 для:

  • опроса по кнопке в операторской программе;
  • чтения и записи памяти MIFARE/NTAG;
  • получения разового списка меток через AT+I;
  • последовательного выбора HF-карт командами AT+i и AT+n;
  • сервисной диагностики без фоновых событий.

Большинство команд, которые непосредственно работают с выбранной картой, возвращают ERROR, если включён SCAN1, SCAN2 или SCAN3. Перед такой операцией всегда отправляйте AT+SCAN0.

SCAN1 — карта появилась или убрана

AT+SCAN1 сообщает оба изменения состояния:

> AT+SCAN1
OK

# карту поднесли
SCAN:+8D430BA4

# карту убрали
SCAN:-8D430BA4

Этот режим удобен, если приложению важно знать, находится ли карта у считывателя:

  • терминал доступа показывает карточку сотрудника, пока метка лежит на считывателе;
  • кассовое или складское ПО привязывает операцию к физически присутствующей карте;
  • интерфейс включает действия после SCAN:+ и блокирует их после SCAN:-;
  • сервис измеряет длительность присутствия метки.

Не считайте SCAN:- новой картой: это удаление той же метки, а данные после префикса повторяют строку, сохранённую при её появлении.

SCAN2 — одна запись на каждое поднесение

AT+SCAN2 выдаёт только форматированные данные при обнаружении карты:

> AT+SCAN2
OK

# карту поднесли
8D430BA4

# карту убрали — данных нет

Пока карта остаётся в поле, одинаковые строки при каждом цикле опроса не генерируются. После удаления и повторного поднесения появится новая запись.

Это самый простой режим для:

  • журнала посещений;
  • ввода UID в 1С или учётную систему через собственный COM-компонент;
  • регистрации выдачи инвентаря;
  • поиска клиента или заказа по карте;
  • фонового сервиса, которому нужно только событие чтения, без учёта удаления.

У SCAN2 нет служебного префикса. Когда он включён, любая непустая строка, которая не является ответом OK, ERROR или ответом на отправленную команду, должна рассматриваться как форматированные данные карты.

SCAN3 — несколько карт

AT+SCAN3 ведёт список карт в поле и формирует отдельные события для каждой:

> AT+SCAN3
OK

SCAN:+8D430BA4
SCAN:+04A1B2C3D4E5F6
SCAN:-8D430BA4
SCAN:-04A1B2C3D4E5F6

Список содержит до восьми карт. Режим предназначен прежде всего для HF-меток 13,56 МГц с антиколлизией. Метки 125 кГц не поддерживают антиколлизию такого уровня: если одновременно положить несколько LF-меток, рассчитывать на устойчивое чтение каждой нельзя.

SCAN3 подходит для:

  • настольной инвентаризации небольшого набора меток;
  • контроля состава комплекта;
  • интерфейса, который показывает список меток в поле в реальном времени;
  • обнаружения добавления и удаления отдельных HF-меток без повторной передачи всего списка.

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

Если AT+SCAN3 возвращает ERROR, обновите прошивку или используйте SCAN1 либо ручной опрос.

Настройка данных для стороннего ПО

Сначала задайте строку форматирования, затем включите нужный режим. Например, вывод UID в нижнем регистре HEX:

> AT+F=hU*
OK
> AT+P
OK
> AT+SCAN2
OK

Добавим постоянный префикс, чтобы принимающей программе было проще отличить карту от служебного сообщения:

> AT+F=c\ar\d:hU*
OK
> AT+P
OK
> AT+SCAN1
OK

SCAN:+card:8d430ba4
SCAN:-card:8d430ba4

Буквы a и d экранированы отдельно, потому что в строке форматирования это управляющие коды. Обратная косая черта относится только к одному следующему символу.

AT+F=..., AT+T..., AT+G=..., AT+L... и AT+Z... меняют рабочие настройки сразу. Отправьте AT+P, если они должны сохраниться после отключения питания. В ODRFID-M/N/E команда AT+F= принимает до 31 байта данных формата. Указанный для других моделей лимит 57 байт к этим USB-считывателям не относится.

Типовые сценарии

Получать UID в фоне

При запуске программы:

ATI
AT+F=hU*
AT+SCAN2

Далее программа постоянно читает непустые строки из порта и добавляет UID в журнал. Настройки можно сохранить один раз командой AT+P, а при каждом подключении только проверять их через AT+F? и AT+SCAN?.

Вести список присутствующих карт

Для одной карты используйте SCAN1, для нескольких HF-карт — SCAN3. Храните множество идентификаторов:

  • SCAN:+<данные> — добавить запись;
  • SCAN:-<данные> — удалить запись;
  • после переподключения очистить локальное множество и дождаться новых событий.

Получить разовый список карт по запросу

> AT+SCAN0
OK
> AT+I
+UID=8D430BA408
+UID=04A1B2C3D4E5F608
OK

AT+I завершается OK после перечисления найденных карт. Если карт нет, приходит только OK. Этот сценарий удобен для кнопки «Обновить список» и короткой инвентаризации без постоянного потока событий.

Прочитать блок MIFARE Classic

> AT+SCAN0
OK
> AT+i
+UID=8D430BA408
OK
> AT+KAFFFFFFFFFFFF
OK
> AT+R4
+DATA 4:00112233445566778899AABBCCDDEEFF
OK

Ключ задаётся без знака =. Для Key B используйте AT+KB.... Считыватель автоматически выполняет аутентификацию нужного сектора при чтении.

Запись шестнадцатеричных данных выполняется командой вида:

AT+W4:00112233445566778899AABBCCDDEEFF

Для MIFARE Classic передаются 16 байт, для страниц Ultralight — 4 байта. Проверяйте тип карты, номер и размер блока через AT+S. Не записывайте sector trailer MIFARE Classic без проверки ключей и битов доступа: неверные данные могут закрыть сектор.

Настроить период опроса и индикацию

> AT+T?
+T20
OK
> AT+T50
OK
> AT+L0
OK
> AT+Z0
OK
> AT+P
OK

Интервал задаётся в миллисекундах без знака =. Слишком маленькое значение увеличивает нагрузку на USB и радиотракт, слишком большое добавляет заметную задержку реакции.

Для моделей N и M усиление HF-тракта задаётся в децибелах:

> AT+G=43
OK
> AT+G?
+G=43
OK

Поддерживаемые уровни — 18, 23, 33, 38, 43 и 48 дБ. Не выбирайте максимальное усиление автоматически: рядом с помехами или металлом оно может ухудшить стабильность.

Пример на Python

Установите pyserial и укажите порт своего считывателя:

python -m pip install pyserial
import serial


PORT = "/dev/ttyACM0"  # например, "COM4" в Windows


def read_line(port):
    while True:
        raw = port.readline()
        if not raw:
            return None
        line = raw.decode("ascii", errors="replace").strip()
        if line:
            return line


def command(port, text):
    port.write((text + "\r\n").encode("ascii"))
    payload = []

    while True:
        line = read_line(port)
        if line is None:
            raise TimeoutError(f"Нет ответа на {text}")
        if line == "OK":
            return payload
        if line == "ERROR":
            raise RuntimeError(f"{text}: {'; '.join(payload) or 'ERROR'}")
        payload.append(line)


with serial.Serial(PORT, 115200, timeout=1, write_timeout=1) as port:
    command(port, "AT+SCAN0")
    print(command(port, "ATI"))
    command(port, "AT+F=hU*")
    command(port, "AT+SCAN1")

    while True:
        line = read_line(port)
        if line is None:
            continue
        if line.startswith("SCAN:+"):
            print("Карта появилась:", line[6:])
        elif line.startswith("SCAN:-"):
            print("Карта убрана:", line[6:])
        else:
            print("Служебная строка:", line)

В рабочем приложении чтением порта должен заниматься один поток или одна асинхронная задача. Она распределяет строки между обработчиком событий SCAN:... и ожидающей ответа командой. Не открывайте порт отдельно для каждого запроса и не позволяйте нескольким частям программы читать его одновременно.

Что учитывать в надёжной интеграции

  • После подключения отправляйте ATI, затем проверяйте AT+SCAN? и AT+F?: настройки могли быть изменены другой программой.
  • Считайте OK и ERROR конечными строками ответа, а +CME ERROR: ... — дополнительной диагностикой.
  • Задайте тайм-аут команды, но продолжайте читать порт: события сканирования асинхронны.
  • Перед AT+i, AT+n, AT+S, AT+R... и AT+W... переходите в SCAN0.
  • После потери USB-соединения очистите список присутствующих карт. Старые события удаления уже не придут.
  • Сохраняйте настройки через AT+P только после проверки. У этой команды есть запись в энергонезависимую память, поэтому не вызывайте её для каждого считанного UID.
  • Не разбирайте UID по фиксированной длине: у HF-карт он бывает 4, 7 или 10 байт, у поддерживаемых LF-форматов — другой длины. Для потока событий удобнее заранее выбрать однозначную строку форматирования.

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

История прошивки ODRFID-M/N/E

Эта история относится к настольным USB-считывателям ODRFID-M, ODRFID-N и ODRFID-E. Она не относится к ODRFID-RS485.

3.9
  • Исправлены ошибки.
3.7
  • Добавлен режим SCAN1.
  • Данные, передаваемые в SCAN1, теперь зависят от строки форматирования.
3.6
  • Добавлена экспериментальная поддержка HID Prox II.
  • Период опроса теперь задаёт паузу между окончанием одного опроса и началом следующего.

При обновлении с версии ниже 3.6 старое значение периода, например 200 мс, следует уменьшить, например до 20 мс.