Інтеграція 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-зчитувача з базовою інвентаризацією та відображенням тегів: 5 днів. Розширене рішення з регіональними настройками, фільтрацією, EPC декодуванням та WMS-синхронізацією: 1–2 тижні.