C++ 如何在C+中同时连接两个RFID读卡器+;?
我有两个RFID阅读器C++ 如何在C+中同时连接两个RFID读卡器+;?,c++,serial-port,rfid,mifare,smartcard-reader,C++,Serial Port,Rfid,Mifare,Smartcard Reader,我有两个RFID阅读器 读卡器1:port=com4和baud=9600 读卡器2:port=com9和baud=9600 我想同时连接两个RFID阅读器。然而,即使我在代码中实例化了两个读卡器,我也只能访问两个读卡器中的一个 我做了以下工作: 米法雷酮 MifareOne::MifareOne() { LoadDll(); } MifareOne::~MifareOne() { CloseComm(); CloseDll(); } bool IsLoadDLL
- 读卡器1:
和port=com4
baud=9600
- 读卡器2:
和port=com9
baud=9600
MifareOne::MifareOne()
{
LoadDll();
}
MifareOne::~MifareOne()
{
CloseComm();
CloseDll();
}
bool IsLoadDLL = false;
bool MifareOne::LoadDll()
{
if (IsLoadDLL)
return true;
// TODO: Add extra initialization here
TCHAR szBuf[MAX_PATH];
GetModuleFileName(NULL, (LPTSTR)szBuf, MAX_PATH);
sprintf(szBuf, "../../../CardReader\\MasterRD.dll");
m_hInstMaster = LoadLibrary(_T(szBuf));
if (m_hInstMaster)
{
IsLoadDLL = true;
(FARPROC&)lib_ver = GetProcAddress(m_hInstMaster, _T("lib_ver"));
(FARPROC&)des_encrypt = GetProcAddress(m_hInstMaster, _T("des_encrypt"));
(FARPROC&)des_decrypt = GetProcAddress(m_hInstMaster, _T("des_decrypt"));
(FARPROC&)rf_init_com = GetProcAddress(m_hInstMaster, _T("rf_init_com"));
(FARPROC&)rf_init_device_number = GetProcAddress(m_hInstMaster, _T("rf_init_device_number"));
(FARPROC&)rf_get_device_number = GetProcAddress(m_hInstMaster, _T("rf_get_device_number"));
(FARPROC&)rf_get_model = GetProcAddress(m_hInstMaster, _T("rf_get_model"));
(FARPROC&)rf_get_snr = GetProcAddress(m_hInstMaster, _T("rf_get_snr"));
(FARPROC&)rf_beep = GetProcAddress(m_hInstMaster, _T("rf_beep"));
(FARPROC&)rf_init_sam = GetProcAddress(m_hInstMaster, _T("rf_init_sam"));
(FARPROC&)rf_sam_rst = GetProcAddress(m_hInstMaster, _T("rf_sam_rst"));
(FARPROC&)rf_sam_cos = GetProcAddress(m_hInstMaster, _T("rf_sam_cos"));
(FARPROC&)rf_init_type = GetProcAddress(m_hInstMaster, _T("rf_init_type"));
(FARPROC&)rf_antenna_sta = GetProcAddress(m_hInstMaster, _T("rf_antenna_sta"));
(FARPROC&)rf_request = GetProcAddress(m_hInstMaster, _T("rf_request"));
(FARPROC&)rf_anticoll = GetProcAddress(m_hInstMaster, _T("rf_anticoll"));
(FARPROC&)rf_select = GetProcAddress(m_hInstMaster, _T("rf_select"));
(FARPROC&)rf_halt = GetProcAddress(m_hInstMaster, _T("rf_halt"));
(FARPROC&)rf_download_key = GetProcAddress(m_hInstMaster, _T("rf_download_key"));
(FARPROC&)rf_M1_authentication1 = GetProcAddress(m_hInstMaster, _T("rf_M1_authentication1"));
(FARPROC&)rf_M1_authentication2 = GetProcAddress(m_hInstMaster, _T("rf_M1_authentication2"));
(FARPROC&)rf_M1_read = GetProcAddress(m_hInstMaster, _T("rf_M1_read"));
(FARPROC&)rf_M1_write = GetProcAddress(m_hInstMaster, _T("rf_M1_write"));
(FARPROC&)rf_M1_initval = GetProcAddress(m_hInstMaster, _T("rf_M1_initval"));
(FARPROC&)rf_M1_readval = GetProcAddress(m_hInstMaster, _T("rf_M1_readval"));
(FARPROC&)rf_M1_decrement = GetProcAddress(m_hInstMaster, _T("rf_M1_decrement"));
(FARPROC&)rf_M1_increment = GetProcAddress(m_hInstMaster, _T("rf_M1_increment"));
(FARPROC&)rf_M1_restore = GetProcAddress(m_hInstMaster, _T("rf_M1_restore"));
(FARPROC&)rf_M1_transfer = GetProcAddress(m_hInstMaster, _T("rf_M1_transfer"));
(FARPROC&)rf_typea_rst = GetProcAddress(m_hInstMaster, _T("rf_typea_rst"));
(FARPROC&)rf_cos_command = GetProcAddress(m_hInstMaster, _T("rf_cos_command"));
(FARPROC&)rf_atqb = GetProcAddress(m_hInstMaster, _T("rf_atqb"));
(FARPROC&)rf_attrib = GetProcAddress(m_hInstMaster, _T("rf_attrib"));
(FARPROC&)rf_typeb_cos = GetProcAddress(m_hInstMaster, _T("rf_typeb_cos"));
(FARPROC&)rf_hltb = GetProcAddress(m_hInstMaster, _T("rf_hltb"));
(FARPROC&)rf_at020_check = GetProcAddress(m_hInstMaster, _T("rf_at020_check"));
(FARPROC&)rf_at020_read = GetProcAddress(m_hInstMaster, _T("rf_at020_read"));
(FARPROC&)rf_at020_write = GetProcAddress(m_hInstMaster, _T("rf_at020_write"));
(FARPROC&)rf_at020_lock = GetProcAddress(m_hInstMaster, _T("rf_at020_lock"));
(FARPROC&)rf_at020_count = GetProcAddress(m_hInstMaster, _T("rf_at020_count"));
(FARPROC&)rf_at020_deselect = GetProcAddress(m_hInstMaster, _T("rf_at020_deselect"));
(FARPROC&)rf_light = GetProcAddress(m_hInstMaster, _T("rf_light"));
(FARPROC&)rf_ClosePort = GetProcAddress(m_hInstMaster, _T("rf_ClosePort"));
(FARPROC&)rf_GetErrorMessage = GetProcAddress(m_hInstMaster, _T("rf_GetErrorMessage"));
if (NULL == lib_ver ||
NULL == des_encrypt ||
NULL == des_decrypt ||
NULL == rf_init_com ||
NULL == rf_init_device_number ||
NULL == rf_get_device_number ||
NULL == rf_get_model ||
NULL == rf_beep ||
NULL == rf_init_sam ||
NULL == rf_sam_rst ||
NULL == rf_sam_cos ||
NULL == rf_init_type ||
NULL == rf_antenna_sta ||
NULL == rf_request ||
NULL == rf_anticoll ||
NULL == rf_select ||
NULL == rf_halt ||
NULL == rf_download_key ||
NULL == rf_M1_authentication1 ||
NULL == rf_M1_authentication2 ||
NULL == rf_M1_read ||
NULL == rf_M1_write ||
NULL == rf_M1_initval ||
NULL == rf_M1_readval ||
NULL == rf_M1_decrement ||
NULL == rf_M1_increment ||
NULL == rf_M1_restore ||
NULL == rf_M1_transfer ||
NULL == rf_typea_rst ||
NULL == rf_cos_command ||
NULL == rf_atqb ||
NULL == rf_attrib ||
NULL == rf_typeb_cos ||
NULL == rf_hltb ||
NULL == rf_at020_check ||
NULL == rf_at020_read ||
NULL == rf_at020_write ||
NULL == rf_at020_lock ||
NULL == rf_at020_count ||
NULL == rf_at020_deselect ||
NULL == rf_light ||
NULL == rf_ClosePort ||
NULL == rf_GetErrorMessage)
{
return false;
}
}
else
{
int err = GetLastError();
return false;
}
return true;
}
bool MifareOne::CloseDll()
{
if(m_hInstMaster)
{
FreeLibrary(m_hInstMaster);
lib_ver = NULL;
des_encrypt = NULL;
des_decrypt = NULL;
rf_init_com = NULL;
rf_init_device_number = NULL;
rf_get_device_number = NULL;
rf_get_model = NULL;
rf_beep = NULL;
rf_init_sam = NULL;
rf_sam_rst = NULL;
rf_sam_cos = NULL;
rf_init_type = NULL;
rf_antenna_sta = NULL;
rf_request = NULL;
rf_anticoll = NULL;
rf_select = NULL;
rf_halt = NULL;
rf_download_key = NULL;
rf_M1_authentication1 = NULL;
rf_M1_authentication2 = NULL;
rf_M1_read = NULL;
rf_M1_write = NULL;
rf_M1_initval = NULL;
rf_M1_readval = NULL;
rf_M1_decrement = NULL;
rf_M1_increment = NULL;
rf_M1_restore = NULL;
rf_M1_transfer = NULL;
rf_typea_rst = NULL;
rf_cos_command = NULL;
rf_atqb = NULL;
rf_attrib = NULL;
rf_typeb_cos = NULL;
rf_hltb = NULL;
rf_at020_check = NULL;
rf_at020_read = NULL;
rf_at020_write = NULL;
rf_at020_lock = NULL;
rf_at020_count = NULL;
rf_at020_deselect = NULL;
rf_light = NULL;
rf_ClosePort = NULL;
rf_GetErrorMessage = NULL;
m_hInstMaster = NULL;
return true;
}
return false;
}
bool MifareOne::OpenComm(int com, int baud)
{
//save port and baud
mCommPort = com;
mBandRate = baud;
//open port
int state = 1;
state = rf_init_com(com, baud);
if (state != LIB_SUCCESS){
rf_ClosePort();
return false;
}
return true; // return TRUE unless you set the focus to a control
}
bool IsCloseComm = false;
void MifareOne::CloseComm()
{
if (IsCloseComm)
return;
rf_ClosePort();
IsCloseComm = true;
}
int MifareOne::Write(unsigned char* strData)
{
WORD icdev = 0x0000;
unsigned char mode = 0x60; // key A
unsigned char secnr = '\x1';
int state;
unsigned char strKey[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0 };
int nSel = 1;
state = rf_M1_authentication2(icdev, mode, (secnr / 4) * 4, strKey);
if (state){
return -1;
}
unsigned char strEncryptData[MAX_RF_BUFFER];
state = Encrypt(strEncryptData, strData, (unsigned char*)Encrypt_Key);
if (state){
return -1;
}
state = rf_M1_write(icdev, secnr, strEncryptData);
if (state){
return -1;
}
return 1;
}
int main(int argc, const char* argv[])
{
MifareOne cardReader1;
MifareOne cardReader2;
cardReader1.OpenComm(4, 9600);
cardReader2.OpenComm(9, 9600);
cardReader1.Write((unsigned char*) "testing"); // Not work
cardReader2.Request((unsigned char*) "testing"); // Work fine
}
我能想到三种可能性 首先,您使用
Request()
方法测试一个读卡器,而使用Write()
方法测试另一个读卡器。可能是Write()
不正确。尝试为两个读者使用Request()
,看看会发生什么
第二,您的COM端口错误。打开设备管理器并确定设备在哪些端口上运行。插入两个端口后,请验证您是否使用了正确的端口
第三,另一个程序,可能是您软件的旧版本,正在使用COM端口。尝试重新启动计算机或检查端口是否正在使用。读卡器DLL的界面看起来似乎一次只支持一个读卡器。这方面的一个明确迹象是,API函数不使用句柄来跟踪两个同时进行的会话 那么比如说,
cardReader1.OpenComm(4, 9600);
导致以下API调用:
state = rf_init_com(4, 9600);
state = rf_init_com(9, 9600);
其中,成功后,状态
为0。因此,没有可用于跟踪此特定rf_init_com
调用的“句柄”
所以如果你下次使用
cardReader2.OpenComm(9, 9600);
打开第二个读卡器端口。这将导致以下API调用:
state = rf_init_com(4, 9600);
state = rf_init_com(9, 9600);
由于DLL不跟踪多个连接,现在可能会发生两种情况:
MifareOne
对象都使用了OpenComm
,对这两个对象的调用将转到第二个(案例1)或第一个(案例2)读取器。具体地说,如果您查看作为
cardReader1.Write((unsigned char*) "testing");
及
cardReader2.Write((unsigned char*) "testing");
您将看到这两种方法将导致相同的API调用:
state = rf_M1_authentication2(icdev, mode, (secnr / 4) * 4, strKey);
state = rf_M1_write(icdev, secnr, strEncryptData);
因此DLL无法区分这两个读取器
因此,在我看来,DLL不是为多个读卡器设计的。您的问题是,用于访问RFID设备的DLL一次只支持访问一个设备。对
MifareOne::OpenComm
方法进行的两次调用中的每一次都在同一MasterRD.dll
中调用相同的rf_init_com
函数。rf\u init\u com
方法不会返回任何类型的句柄,您可以使用这些句柄来区分多个连接,因此您的MifareOne::Write
方法无法告诉DLL您要使用两个连接中的哪一个
由于DLL不允许您一次打开多个设备,因此您只能使用两种可能的解决方法。首先在两个不同的进程中使用DLL,每个进程与不同的RFID设备通信。在这种情况下,DLL在每个进程中都有一个单独的内部状态,允许您使用它在每个进程中打开不同的设备。然后,您必须使用Windows的许多进程间通信方法中的一种,以允许这两个进程相互协调或协调主进程
第二种是通过串行端口直接与RFID设备通信。Windows允许您同时打开在同一进程中打开的多个串行设备。使用此解决方案意味着您必须自己处理与设备通话的所有低级协议细节。您正在使用的DLL的低级详细信息是用来隔离您的。您可能还需要使用异步I/O或多线程来避免从两个设备读写时出现死锁。这是操作系统(可能是设备和库)特有的。因此,请适当地标记您的问题。标准C++11不知道RFID,“同时”字面意思是同时。因此,“同时连接2个读卡器”与“同时连接1个读卡器”相矛盾,“连接RFID读卡器”是什么?你们称之为“同时”会发生什么?我正在用计算机通过COM端口连接两个RFID阅读器。如果我只连接一个RFID读卡器,那么它工作正常(读写数据正常)。如果我连接2个RFID读卡器,那么稍后连接的读卡器工作正常!什么是编程问题?我们能知道你试过什么吗?你的问题是什么?很多代码让我们不知道真正的底层问题。。。