UHF RFID 读取器程序
使用 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
对象返回给父对象。 完整的源代码可从上面的下载链接获得。