שילוב סורקי UHF RFID: פרוטוקולים, SDKs וביצועים

שילוב סורק UHF RFID באפליקציה ניידת תלוי לעתים קרובות בבחירת פרוטוקול ובתצורת חומרה, מה שעלול לעכב את השקת הפרויקט. אנו בונים פתרונות סוהר, ועוזרים לכם לבחור את שיטת החיבור האופטימלית—מקוראי BLE ועד מערכות נייחות. הצוות שלנו מטפל במחזור המלא, מבדיקה והתקנה ועד פריסה ותמיכה שוטפת, ומבטיח פעולה אמינה של ציודכם.

פיתוח ותמיכה בכל סוגי היישומים הניידים:

יישומים ניידים למידע ובידור
אפליקציות חדשות, משחקים, מדריכים, קטלוגים מקוונים, אפליקציות מזג אוויר, אפליקציות כושר ובריאות, אפליקציות נסיעות, אפליקציות חינוכיות, רשתות חברתיות ומסנג'רים, חידונים, בלוגים ופודקאסטים, פורומים, אגרגטורים
יישומים ניידים למסחר אלקטרוני
חנויות מקוונות, אפליקציות B2B, מרקטפלייסים, בורסות מקוונות, שירותי קאשבק, בורסות, פלטפורמות דרופשיפינג, תוכניות נאמנות, משלוחי מזון ומוצרים, מערכות תשלום.
יישומים ניידים לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, ניהול פרויקטים, כלים לצוותי מכירות, ניהול פיננסי, ניהול ייצור, ניהול לוגיסטיקה ומשלוחים, ניהול משאבי אנוש, מערכות ניטור נתונים
יישומים ניידים לשירותים אלקטרוניים
פלטפורמות מודעות מסווגות, בתי ספר מקוונים, בתי קולנוע מקוונים, פלטפורמות שירות אלקטרוניות, פלטפורמות קאשבק, אירוח וידאו, פורטלים נושאיים, פלטפורמות הזמנות ותזמון מקוונות, פלטפורמות מסחר מקוונות

אלה הם רק חלק מסוגי היישומים הניידים שאנו עובדים איתם, ולכל אחד מהם עשויים להיות מאפיינים ופונקציונליות ספציפיים משלו, המותאמים לצרכים ולמטרות הספציפיות של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
שילוב סורקי UHF RFID: פרוטוקולים, SDKs וביצועים
בינוני
~5 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

שילוב קוראי UHF RFID: מחיבור BLE ועד לייצור

UHF RFID (860–960 מגה-הרץ) קורא תגיות פסיביות במרחקים של עד 10 מטרים ומאות תגיות בשנייה. בניגוד ל-HF NFC (עד 10 ס"מ), זה חיוני למשימות מחסן. לעיתים קרובות אנו נתקלים במצבים שבהם לקוח צריך לחבר Zebra RFD40 או Chainway R6 לאפליקציה ניידת לניהול מלאי או לוגיסטיקה. נקודות הכאב האופייניות הן אי-ידיעה באיזה פרוטוקול לבחור (LLRP או SDK קנייני), כיצד לעקוף מגבלות טווח תדרים, וכיצד להימנע מאובדן ביצועים. מאמר זה חולק ניסיון קונקרטי וקוד עבור Android (Kotlin) שניתן להתאים ל-iOS ו-Flutter. נסקור טעויות נפוצות ונראה תצורות עבודה באמצעות דוגמת Zebra RFD40.

כיצד לבחור פרוטוקול: LLRP או SDK קנייני?

LLRP (Low Level Reader Protocol, תקן ISO 15961) הוא פרוטוקול אוניברסלי לשליטה בקוראי UHF. נתמך על ידי Impinj, Zebra, Alien. הוא מאפשר שימוש בקוד אחד עבור קוראים שונים אך דורש חיבור Wi-Fi לציוד נייח. LLRP אינו מתאים לקוראי BLE ניידים—כאן יש צורך ב-SDK קנייני.

SDK קנייני—Zebra RFID SDK, Chainway SDK. קל יותר לשילוב, עובד דרך BLE או USB, אך קושר אותך לספק. עם זאת, הוא נותן גישה לכפתור ההדק, ניהול צריכת חשמל, ואירועים בזמן אמת.

מאפיין LLRP SDK קנייני (Zebra)
חיבור Wi-Fi / Ethernet BLE / USB
קוראים ניידים לא כן (RFD40, TC21)
רוחב פלטפורמות כן רק לפלטפורמת ה-SDK
מורכבות גבוהה בינונית
מהירות שילוב שבוע+ 3–5 ימים

עבור קוראי UHF ניידים עם BLE, אנו תמיד ממליצים על ה-SDK הקנייני—הוא חוסך זמן ונותן שליטה מלאה על המכשיר.

Zebra RFID SDK: יישום מעשי

בואו נסתכל על שילוב Zebra RFD40 ב-Android באמצעות rfid-api3. הקוד שלהלן מציג חיבור, הגדרת עוצמה, וסינון EPC.

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)
                }
            }
        }
    }
}

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) } } } } } — עוצמה ביחידות קורא. לכל יצרן יש סולם משלו. 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 ברוסיה מפר תקנות תדרי רדיו מקומיות. קוראים מודרניים נועלים חומרתית אזור שגוי, אך אנו תמיד בודקים עמידה בדרישות לפני השקה.

ביצועים: 500 תגיות/שנייה ללא פיגור

אין לעבד את זרם התגיות על ה-thread הראשי—ממשק המשתמש יקפא. השתמשו ב-coroutines ו-channels:

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())
        }
    }
}

גישה זו מבטיחה ממשק משתמש מגיב גם בעומס שיא. ב-iOS, תוצאה דומה מושגת עם OperationQueue ו-transmitPowerIndex = 270.

תהליך השילוב

  1. ניתוח דרישות — בחירת קורא (Zebra, Chainway, Bluebird), הגדרת תרחישים (מלאי, קבלה, משלוח).
  2. הכנת SDK — השגת מפתחות, הגדרת סביבה (Android Studio, Xcode).
  3. פיתוח מודול תקשורת — חיבור BLE, טיפול באירועים, סינון.
  4. בדיקה עם תגיות אמיתיות — אימות טווח, עוצמה, הגדרות אזור.
  5. אופטימיזציית ביצועים — threads ברקע, חציצה, סנכרון שרת.
  6. פריסה ל-App Store / Google Play + TestFlight לבדיקות בטא.

מה כלול

  • חיבור והגדרה של קורא ה-UHF הנבחר
  • יישום קריאה עם סינון EPC ו-RSSI
  • טיפול באירועי הדק ומלאי
  • תמיכה בתדרים אזוריים (FCC/ETSI/סין)
  • אופטימיזציית ביצועים (threads ברקע, חציצה)
  • שילוב עם WMS/ERP שלך דרך REST או GraphQL
  • קוד מקור ותיעוד מסופקים
  • חודש תמיכה חינם לאחר המסירה

לוחות זמנים

שילוב בסיסי של קורא BLE אחד עם הצגת תגיות — מ-5 ימים. פתרון מורחב עם הגדרות אזור, סנכרון וסינון — 1–2 שבועות. נבחן את הפרויקט שלך — צור קשר לדיון בפרטים.

למה לסמוך על הניסיון שלנו

השלמנו למעלה מ-50 פרויקטים עם UHF RFID בפלטפורמות ניידות, כולל שילובים עם 1C, SAP ומערכות WMS. המהנדסים שלנו מחזיקים בהסמכות Android ו-iOS ויש להם ניסיון ברמת פרוטוקול ב-Bluetooth LE. אנו מבטיחים תמיכה לאחר המסירה — תיקונים ושיפורים בתוך חודש.