Интеграция UHF RFID-сканера (дальнего действия) в мобильное приложение

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Интеграция UHF RFID-сканера (дальнего действия) в мобильное приложение
Средний
~5 дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Интеграция UHF RFID-сканера (дальнего действия) в мобильное приложение

UHF RFID (860–960 МГц) — другой мир по сравнению с HF NFC/MIFARE. Дальность чтения 3–10 метров, массовое считывание сотен тегов в секунду, пассивные теги стоимостью $0.05–0.15 штука. Zebra RFD40, Chainway R6, Bluebird EF500 — это мобильные UHF-ридеры с BLE или USB подключением. Интеграция таких устройств в мобильное приложение имеет свои особенности: LLRP протокол, EPC C1G2 стандарт, управление мощностью антенны.

LLRP vs проприетарный SDK

LLRP (Low Level Reader Protocol, ISO 15961) — стандартный протокол управления UHF-ридерами. Поддерживают Impinj, Zebra, Alien. Позволяет использовать один код для разных ридеров. Для мобильного приложения через Wi-Fi подключение к ридеру.

Проприетарный SDK — Zebra RFID SDK, Chainway SDK. Проще в использовании, закрыт под конкретного производителя, работает по BLE или USB.

Для большинства мобильных ридеров с BLE — проприетарный SDK. LLRP — для стационарных ридеров в сети.

Zebra RFID SDK: практика

implementation("com.zebra.rfid.api3:rfid-api3:2.0.2.109")

class UhfReaderManager(private val context: Context) : RfidEventsListener {
    private var reader: RFIDReader? = null
    private val readers = Readers(context, ENUM_TRANSPORT.BLUETOOTH)

    fun connect(deviceName: String) {
        val readerDevices = readers.GetAvailableRFIDReaderList()
        val targetDevice = readerDevices?.find { it.name == deviceName } ?: return
        reader = targetDevice.RFIDReader
        reader?.connect()

        // Настройка параметров считывания
        val params = reader?.Config?.antennaConfigurations?.get(0)
        params?.transmitPowerIndex = 270  // ~30 dBm, максимальная мощность
        params?.receiveFrequency = 55     // оптимально для большинства регионов

        reader?.Config?.setAntennaConfiguration(params)

        // События
        reader?.Events?.apply {
            addEventsListener(this@UhfReaderManager)
            setHandheldEvent(true)    // кнопка триггера на ридере
            setTagReadEvent(true)
            setInventoryStartEvent(true)
            setInventoryStopEvent(true)
        }
    }

    // Запуск инвентаризации с фильтрацией по маске EPC
    fun startInventoryWithFilter(epcMask: String?) {
        val startTrigger = TriggerInfo().apply {
            startTrigger.triggerType = START_TRIGGER_TYPE.START_TRIGGER_TYPE_IMMEDIATE
        }
        val stopTrigger = TriggerInfo().apply {
            stopTrigger.triggerType = STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_DURATION
            stopTrigger.stopTriggerByDuration.duration = 5000  // 5 секунд
        }

        val tagFilter = if (epcMask != null) {
            TagFilter().apply {
                tagPattern = epcMask
                tagPatternBitCount = epcMask.length * 4
                filterAction = FILTER_ACTION.FILTER_ACTION_STATE_AWARE_FILTERING_ACTION_UNSPECIFIED
            }
        } else null

        reader?.Actions?.Inventory?.perform(startTrigger, stopTrigger, tagFilter)
    }

    override fun eventReadNotify(e: RfidReadEvents) {
        e.ReadEventData.TagData.forEach { tag ->
            onTagRead(
                epc = tag.TagID,
                rssi = tag.PeakRSSI.toInt(),
                antennaId = tag.AntennaID.toInt(),
                readCount = tag.ReadCount
            )
        }
    }

    override fun eventStatusNotify(rfidStatusEvents: RfidStatusEvents) {
        when (rfidStatusEvents.StatusEventData.statusEventType) {
            STATUS_EVENT_TYPE.INVENTORY_START_EVENT -> onInventoryStarted()
            STATUS_EVENT_TYPE.INVENTORY_STOP_EVENT -> onInventoryCompleted()
            STATUS_EVENT_TYPE.HANDHELD_TRIGGER_EVENT -> {
                val triggerType = rfidStatusEvents.StatusEventData.HandheldTriggerEventData.handheldEvent
                if (triggerType == HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_PRESSED) {
                    startInventoryWithFilter(null)
                }
            }
        }
    }
}

transmitPowerIndex = 270 — мощность в единицах ридера. У каждого производителя своя шкала. Zebra RFD40: 0–270 = 0–30 dBm. Чрезмерная мощность в закрытом складе → переотражения → ложные считывания из соседних зон.

Регулятивные ограничения частот

UHF RFID работает в разных диапазонах:

  • США/Канада (FCC): 902–928 МГц
  • Европа/Россия (ETSI): 865–868 МГц
  • Китай: 920–925 МГц

Мобильное приложение должно настраивать региональный диапазон ридера:

reader?.Config?.setRegulatoryConfig(
    RegulatoryConfig().apply {
        region = REGULATORY_REGION.REGULATORY_REGION_ETSI // или FCC, China
        enableHoppingChannels = true
    }
)

Использование FCC-диапазона в России — нарушение РЧС. Ридеры с региональными firmware-блокировками не дадут выбрать неверный регион, но проверить стоит.

Производительность: 500 тегов в секунду

UHF-ридер может читать несколько сотен тегов в секунду. Поток тегов нельзя обрабатывать на главном потоке — UI заморозится:

private val tagChannel = Channel<TagReadData>(capacity = Channel.UNLIMITED)

// В BroadcastReceiver/callback ридера — только кладём в канал
override fun eventReadNotify(e: RfidReadEvents) {
    e.ReadEventData.TagData.forEach { tag ->
        tagChannel.trySend(tag) // не блокирует, не бросает исключение
    }
}

// Обработка в отдельной корутине
fun processTagsInBackground() {
    scope.launch(Dispatchers.Default) {
        for (tag in tagChannel) {
            val epc = tag.TagID
            inventoryRepository.recordRead(epc, tag.PeakRSSI.toInt())
        }
    }
}

Сроки

Интеграция Zebra/Chainway UHF BLE-ридера с базовым inventory и отображением тегов: 5 дней. Расширенное решение с региональными настройками, фильтрацией, EPC декодированием и синхронизацией с WMS: 1–2 недели.