65.9K
CodeProject 正在变化。 阅读更多。
Home

UHF RFID 读取器程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.77/5 (9投票s)

2009年4月15日

CPOL

3分钟阅读

viewsIcon

218898

downloadIcon

16342

使用 RFID 阅读器进行 900 MHz RFID 阅读器标签识别。

引言

这是一个用于 900 MHz UHF (超高频) RFID (射频识别) 的程序。 该程序必须具有基于 InpinJ R1000 芯片组的三星 Techwin UHF 手持 RFID 阅读器 (VLAC-G1) 或 UHF 固定 RFID 阅读器 (VLAC-Alpha)。

背景

很多人都在关注 RFID。这项技术在分销行业、食品卫生、航空货运、公共图书馆等方面具有无数的可能性......

这项技术由 RFID 标签、RFID 阅读器和服务构建而成。 RFID 标签是一种非常低成本的产品。 几个月前,海力士半导体表示:“我们将制造 1 美分的 RFID 标签芯片。” RFID 阅读器比 RFID 标签更昂贵。

但是,对于任何考虑低运输成本和运输可靠性应用的分销商来说,这可能是完美的。 许多食品公司可能会考虑将其应用于食品安全。 例如,行业供应商可能会考虑从 2D 条形码技术转向 RFID 技术。

该程序对于 RF 标签识别非常有用。

RFID 标签结构

900MHz RFID 标签由一个标签芯片和一个天线组成。 该标签芯片基于用于自动数据识别规范的 ISO 18000-4 规范和用于项目级管理标签的 ISO-18000-6C 专用规范。 最新趋势是 18000-6C。 我们称这些为 Gen2 标签。

详细结构搜索 EPC Global 标准。 这些标签由 BANK 00(保留内存)、BANK 01(EPC 内存)、BANK 10(TID)和 BANK 11(用户内存)组成。

  • BANK 00(保留内存)由用于安全功能的销毁密码区域和访问密码区域组成。
  • BANK 01(EPC 内存)由 CRC-16(标签用于保护某些 R=>T, T=>R)、PC(EPC 内存区域的协议控制)和 EPC(电子产品代码)组成。
  • BANK 10(TID 内存)是 8 位 ISO/IEC 15963 分配类标识符; 对于 EPC Global,为 11100010。
  • BANK 11(用户内存)是用户规范数据存储。

如何在程序中读取 RFID 标签

该程序由 RFID 无线电 (CRFIDRadio) 和 RFID 无线电管理 (CRFIDRadioManager) 对象组成。

CRFIDRadio 对象是一个真实的命令操作器。 该对象具有用于清单命令、标签访问(Read/BlockRead/Write/BlockWrite/Lock/Kill)命令和 RFID 设置功能的一些功能。 并且,该对象调用三星 Techwin RFID 阅读器 API。

CRFIDRadioManager 对象用于管理每个 RFID 无线电对象。 并且,该对象控制 CRFIDRadio 对象以进行命令传输。

首先,您必须创建一个 CRFIDRadioManager

// Your application header file.
CRFIDRadioManager m_pRFIDRadioManager;
// Your application source file.
m_pRFIDRadioManager = new CRFIDRadioManager();

并像这样连接到 RFID 阅读器设备

m_pRFIDRadioManager->SetParnet(CWnd* Object);
if(m_pRFIDRadioManager->Connect() != RFID_STATUS_OK)
{
    // Connection fail process
}
else
{
    // Connection success process
}

此函数建立与 CRFIDRadio 对象的连接。 在这种状态下,CRFIDRadioManager 对象使用 USB、串行和 TCP/IP 接口搜索并连接您可访问的 RFID 阅读器上的 RFID 阅读器设备。 并且,SetParent 函数设置 CWnd 窗口以进行 Win32 消息返回。 此状态是完整的阅读器连接。

接下来,您将想要识别 RFID 标签。 查看 CRFIDRadioManager 中的 RunInventory 函数。 此函数将标签发送到 RFID 阅读器以进行读取命令。 它为读取命令创建一个线程。

// Your application
void CMainFrame::OnRfidRunInventory()
{
    pRFIDRadioManager->RunInventory(0, -1);
}
// CRFIDRadioManager
RFID_STATUS CRFIDRadioManager::RunInventory(int nModule, INT32 nCount)
{
    RFID_STATUS status = RFID_STATUS_OK;
    if(m_listRadio.GetCount() > 0)
    {
        POSITION pos = m_listRadio.FindIndex(nModule); // find the radio ojbect
        CRFIDRadio* pRadio = (CRFIDRadio*)m_listRadio.GetAt(pos);
        pRadio->m_nStopCountDown = nCount; // set inventory stop count
        pRadio->m_runStatus = RFID_INVENTORY;
        _oleStartDateTime = COleDateTime::GetCurrentTime();
        Radio->Create(); // create inventory thread
    }
    return status;
}

数据包参数是来自阅读器的结果信息。 基本结构是 RFID_PACKET_COMMON。 有关详细的结构信息,请参阅三星 Techwin 主页上的接口规范白皮书。

CRFIDRadioManager 使用 SetParent 函数返回父 CTagInfo 对象。

case RFID_PACKET_TYPE_18K6C_INVENTORY:
{
    RFID_PACKET_18K6C_INVENTORY *inv = 
    (RFID_PACKET_18K6C_INVENTORY *)packet;
    /* Calculate the length of the data portion of the packet */
    int length =
    /* The length of the packet beyond the common header */
    (MacToHost16(common->pkt_len)-1) * BYTES_PER_LEN_UNIT -
    /* Add back in the size of the common header */
    (common->flags >> 6);
    if(common->flags & 0x01)
        break;
    int padding_byte = (int)(common->flags & 0xC0);
    POSITION pos = m_listRadio.FindIndex(0);
    CRFIDRadio* pRadio = (CRFIDRadio*)m_listRadio.GetAt(pos);
    if(pRadio->m_runStatus != RFID_INVENTORY)
    {
        CString strTemp = TEXT("Tag ID : ");
        CTagInfo lpTagInfo;// = new CTagInfo();
        lpTagInfo.SetTagMemory(inv->inv_data);
        strTemp += lpTagInfo.GetTagString();
        theApp.m_pMainWnd->SendMessage(WM_TAG_ACCESS, (WPARAM)(LPCTSTR)strTemp, 0);
#ifdef _WIN32_WCE
        if(m_radioBeepMode == RFID_RADIO_BEEP_MODE_ENABLE)
        m_waveBox->Play(0);
#endif
        break;
    }
    // Tag Data Process
    CTagInfo* lpTagInfo = new CTagInfo();
    lpTagInfo->SetTagMemory(inv->inv_data);
    lpTagInfo->SetTagReadCount(inv->count);
    lpTagInfo->SetTagTrialCount(inv->trial_count);
    lpTagInfo->SetTagAntenna(m_nAntenna);
    lpTagInfo->SetTagChannel(m_nChannel);
    lpTagInfo->SetTagRSSI(MacToHost16(inv->rssi));
    lpTagInfo->SetTagLNAGain(MacToHost16(inv->ana_ctrl1));
    lpTagInfo->SetTagReveiveTime(COleDateTime::GetCurrentTime());
ifdef _WIN32_WCE
    if(m_radioBeepMode == RFID_RADIO_BEEP_MODE_ENABLE)
    _waveBox->Play(0);
#endif
    m_pParent->SendMessage(WM_PROCESS_TAG, (WPARAM)lpTagInfo);
    break;
}

CTagInfo 对象从 RFID 阅读器复制标签信息。 并且,CTagInfo 对象使用 ISO 18000-6C 标签类型重建 PC、EPC 和其他信息。

我确实将数据包参数类型转换为 RFID_PACKET_18K6C_INVENTORY 结构。 并且,我定义了 inv 方差。 我检查数据包长度和标志以确定正确的数据包类型。 如果数据包正确,我创建一个 CTagInfo 对象来存储标签信息。 最后,我使用 SendMessage 函数将 CTagInfo 对象返回给父对象。 完整的源代码可从上面的下载链接获得。

© . All rights reserved.