2014年10月24日 星期五

{ HZ1050 @ Arduino @ UART 模式 } 125KHz RFID 讀卡器使用說明

HZ-1050 125KHz RFID 讀卡器模組學習套件可至露天賣場訂購:
詳細的介紹,請上露天賣場。


這篇網頁主要用來說明在 Arduino 開發環境 中,使用 UART 讀取來自於 HZ-1050 125KHz RFID 讀卡器 ( 文中簡稱 HZ1050 ) 回傳 RFID 卡號 ( 因為 HZ1050 主要是針對 EM4100 以及 EM4001 RFID 卡,因此以下在文中簡稱 EM 卡 ),並且將卡號輸出到 Serial Monitor 中。

本篇是 Arduino 控制 HZ1050 系列的第一篇,這三篇依其接收方式不同有:
  1. UART
  2. Wiegand 26 / 34
  3. UART + Wiegand 26 / 34
前兩篇會將結果直接回傳到 Arduino 的 Serial Monitor 中;最後一篇則是另外再將結果顯示在 { 5V0 } 整合型 LCD 上。
HZ1050 讀取到 EM 卡號之後,會直接回傳四個位元組 ( Byte ) 的資料,最簡單檢視的方式就是使用套件中的 USB 轉 TTL 線。
USB 轉 TTL 線與 HZ1050 的接法

接線的方式如上圖所示。

USB 轉 TTL 線 HZ1050
紅線 ( +5V ) +5V
黑線 ( GND ) GND
綠線 ( TXD ) 不接
白線 ( RXD ) TXD

接好線之後,將 USB 轉 TTL 線插上電腦,確認此條線在電腦中的 COM 埠號碼 ( 假設是 COM 5 ),最後打開套件所附的軟體 CommUart Assistant ( 或是其他串列埠通訊軟體 ),照著下圖畫面中的軟體做相關參數設定
由 USB 轉 TTL 線傳回的 16 進位 EM 卡號

Note: HZ1050 可以經由上方的跳線帽設定 Wiegand 26 / 34 以及 UART 傳輸速度 ( 9600 / 19200 bps )。在上面的例子中,是選擇 9600 bps。

使用套件中的鑰匙卡在線圈上方停留一下,HZ1050 若是偵測到正確的卡片,LED +D4 就會亮起,CommUart 的畫面中就會收到卡號。所顯示的卡號就是鑰匙卡上面的號碼轉換成 16 進位的數字。

Note: 若不清楚 EM 卡換算的方法,請看賣場另一篇網頁 ( { HZ1050 } WIEGAND ( 韋根 ) 26 / 34 介紹 ) 的說明。

根據軟體上面所顯示,由 HZ1050 接收到的就是單純的 4 個位元組的 16 進位資料。但請注意 !!! 這 4 個位元組的資料是由 8 個字元所組成,處理上必須先將其轉換成 16 進位或是 10 進位的數字後再去比對會比較方便。

那麼就讓我們先來佈一下線吧 !!!


HZ1050, Arduino 測試電路圖說明:

HZ1050, Arduino 測試電路圖

上面這個電路圖接好之後,只要切換測試程式碼,就可以直接測試 UART 與 WIEGAND 模式。LCD 用的是賣場上的 { 5V0 } 整合型 LCD ( I2C 通訊 ),其他形式的 LCD 也可以,但要自己修改 LCD 顯示的程式;另外若是不使用 LCD 也可以,但要自行將輸出的資料修改為使用 Serial.print() 或是 Serial.println() 的方式輸出到 Arduino Serial Monitor 視窗中。


實際接線圖如下,中間的電路板轉接電源與可變電阻調整 LCD 螢幕亮度。套件中有雙邊等長排針,可使用在杜邦線與 Arduino 板子連接用。
HZ1050, Arduino 實際接線圖


Arduino 程式碼說明:


下載這些程式碼的目錄並將其放置在 Arduino 的 sketches 目錄底下,使用 Arduino IDE 開啟 {HZ1050}\codes\Arduino\sketches\HZ1050\RFID_Demo_UART 目錄  ( 或是 File\Sketchbook\HZ1050\RFID_Demo_UART ) 中的 RFID_Demo_UART.ino

  6 //
  7 #include <SoftwareSerial.h>
  8 
  9 // 如果要看更清楚的資料,將下行前方的斜線取消掉
 10 //#define DEBUG true
 11 
 12 // Connect the Reader's RX to the RX Pin and vice versa for TX
 13 #define RFID_RX_PIN 4
 14 #define RFID_TX_PIN 5
 15 
 16 // 要比對的 RFID Tag ID;可以更改為
 17 String hexTagID = "0x002285EA";  // 一定要 8 個 16 進位,不足的前方補 0
 18 long decTagID = 2262506;            // 2262506 = 0x2285EA
 19 
 20 // Configure the Library in UART Mode
 21 SoftwareSerial rfidTTL( RFID_RX_PIN, RFID_TX_PIN );
 22 

程式使用軟體模擬 UART 的方式 ( line 7 ) 接收資料,一些除錯的訊息就由系統內建的 Serial 函式庫處理。雖然程式只使用到軟體 UART 接收的功能,但是函式庫需要用到兩隻接腳 ( line 13 - 14 ),實體宣告在 line 21

line 17 - 18:程式會將讀取到的 EM 卡號顯示出來;而這兩行的設定是使用兩種不同方式來記錄要比對的 EM 卡號,而比對的程式碼同樣也依這邊的設定分為兩種比對方式,使用者可以根據自己喜歡的方式選擇,移除不需要的程式碼。
line 19:若需要輸出較詳細的資料在 Serial Monitor 上,移除前方的雙斜線。這會讓每個字元的轉換過程輸出到 Serial Monitor 上。

 22 
 23 unsigned char udataTTL[4];
 24 char dataTTL[8];
 25 int  dataIdx;
 26 
 27 long tagID;
 28 
 29 void setup() {
 30   Serial.begin(9600);
 31   rfidTTL.begin(9600);
 32   Serial.println("Serial Ready");
 33   
 34   dataIdx = 0;
 35   tagID = 0;
 36 }

setup() 函式處理幾個函式與變數的初始化。
line 23 - 27:宣告幾個資料處理會用到的陣列與變數。udataTTL ( line 23 ) 用來儲存由 UART 接收到資料;dataTTL ( line 24 ) 是用來儲存轉換為 10 位數之後的資料,下面會特別說明;dataIdx ( line 25 ) 是用來記錄讀取的進度,最多四個位元組;tagID ( line 27 ) 是轉換之後的 10 進位 EM 卡號,這數字會與偵測到的鑰匙卡號相同。
line 30 - 31:設定 SerialSoftwareSerial 傳輸速度為 9600 bps,並輸出 "Serial Ready" 的字串到 Serial Monitor。

 37 
 38 void loop() {  
 39   if( rfidTTL.available() ) {
 40    udataTTL[dataIdx++] = rfidTTL.read();
 41   }
 42 
 43   if(dataIdx == 4) 
 44   {
 45     << 收到完整四個位元組後的處理 >>
101   }
102 }

loop() 函式會重複執行,因此會一直檢查 HZ1050 是否傳來資料 ( line 39 ),如果有資料就將其取出放置入 udataTTL 陣列中 ( line 40 )。

如果取得的資料數量已經有 4 個了 ( line 43 ),就開始運作 ( line 44 - 101 ) 之間的程式碼。

 45     // unsigned char to char
 46     for( int i = 0; i < 8; i+=2 )
 47     {
 48       dataTTL[i] = 0x30 + udataTTL[i/2] / 16;
 49       if( dataTTL[i] > 0x39 ) dataTTL[i] += 7;  // 大於 ASCII '9' 就要變成英文 A(0x41)
 50       dataTTL[i+1] = 0x30 + udataTTL[i/2] % 16;
 51       if( dataTTL[i+1] > 0x39 ) dataTTL[i+1] += 7;
 52       #ifdef DEBUG
 53         Serial.print( dataTTL[i], HEX );
 54         Serial.print(", ");
 55         Serial.print( dataTTL[i+1], HEX );
 56       #endif
 57     }
 58     #ifdef DEBUG
 59       Serial.print('\n');
 60    #endif
 61     
 62     String id = dataTTL;
 63 
 64    // 轉成 16 進位資料並比對
 65    String hexCode = "0x" + id.substring( 0, 8 );
 66    Serial.print("HEX Code: ");
 67    Serial.print( hexCode );
 68    // 16 進位比對
 69    if( hexCode == hexTagID )
 70    {
 71      Serial.println(", HEX compare ok.");
 72      /*
 73       增加比對成功的處理碼在這邊
 74       ...   
 75      */
 76    }
 77    else
 78    {
 79      Serial.println(", HEX compare failed.");
 80    }
 81    
 82    // 轉換為 10 進位資料並比對
 83    char buf[11];  // 包括前方的 0x 共 10 個位元 + 空白字元
 84    hexCode.toCharArray( buf, sizeof(buf) );
 85    tagID = strtol( buf,  NULL, 0 );
 86    Serial.print( "Decimal: " );
 87    Serial.print( tagID );
 88    if( tagID == decTagID )
 89    {
 90      Serial.println(", DEC compare ok.");
 91      /*
 92       增加比對成功的處理碼在這邊
 93       ...   
 94      */
 95    }
 96    else
 97    {
 98      Serial.println(", DEC compare failed.");
 99    }
100    dataIdx = 0;
101   }

line 46 - 51:轉換 16 進位為 10 進位值,示意如下。假設 EM 鑰匙卡號為 0002262506,轉換為 16 進位為 0x002285EA,放入到陣列中就是

udataTTL[] = { 0x00, 0x22, 0x85, 0xEA};

轉換為 10 進位的字元就是

dataTTL[] = { '0', '0', '2', '2', '8', '5', 'E', 'A' };

若不是很了解的話,將 line 10 前方的雙斜線移除掉重新上傳後執行,就可以看到計算的結果。

line 62 - 80:EM 卡號的比較。將 16 進位的 EM 卡號轉成字串,在與設定的 EM 卡號做比對。雖然這部分有點多此一舉,但是合成的這個字串 "0x002285EA" 是要用來轉換成 long 的整數型態也就是用在  line 84 這一條指令上。

line 82 - 99:轉換 dataTTL 陣列中的資料為 long 整數型態。一但轉換成功之後,就可以使用數字來做比對。

if ... else 是比對成功或是失敗時,使用者想要做的動作,預留在這裡讓使用者自己發揮 !!!!


測試結果:

測試之前,請先使用跳線帽在 HZ1050 板子的上方選擇好要使用的傳輸速度 ( 這裡是選 9600 )。開啟 Arduino 電源並開啟 Serial Monitor,使用套件中的鑰匙卡在線圈上面停一下,Serial Monitor 就會顯示出鑰匙卡的 10 進位以及 16 進位的卡號。如果與設定的卡號相同就會輸出比對成功的字串。

Note: 使用 SoftwareSerial 函式庫的傳輸速度不能超過 9600 bps。若使用 19200 bps 的話,應該輸出會是亂碼或是完全得不到訊號,可以自己試試 ! 解決的方法就是使用作為 DEBUG 輸出的 Serial 函式庫,但要修改原本的程式碼。
HZ1050, Arduino Serial Monitor 輸出畫面

結論:

利用上面所列出的 HZ1050 UART 接收的 Arduino 程式碼,可方便的移植到其他的控制器或是系統上。關於這一點,可參考下一篇樹莓派使用 UART 接收 HZ1050 的 EM 卡號的範例程式。

另外,在 Arduino 中使用 SoftwareSerial 函式庫模擬 UART 有一個缺點,那就是傳輸速度不可以超過 9600 bps;如果要使用 19200 bps 的傳輸速度,那您就必須要直接使用 Arduino 的 D0 ( RxD ) 和 D0 ( TxD )。在這裡會這樣用,是因為程式中需要做除錯,而原本的硬體 UART 作為 DEBUG 是最方便的,改變傳輸速度時要將這問題考慮進去!



<< 部落格 HZ-1050,125KHz RFID 讀卡器模組相關網頁連結 >>

沒有留言:

張貼留言