2014年10月28日 星期二

{ HZ1050 @ Arduino + 整合型 LCD } 125KHz RFID 讀卡器使用說明

HZ-1050 125KHz RFID 讀卡器模組學習套件可至露天賣場訂購:
本篇網頁中所使用到的零件可到下面商品網址訂購:
詳細的介紹,請上露天賣場。


Arduino + HZ1050 + { 5V0 } 整合型 LCD 實際接線圖

依照 "{ HZ1050 @ Arduino @ UART 模式 } 125KHz RFID 讀卡器使用說明" 網頁中所提供的電路圖,完成佈線之後實際的線路圖如上面照片所示。

在這篇網頁中,我們會將 UART 以及韋根格式的程式碼全部寫在一個檔案中,並且加入了整合型 LCD 顯示的程式碼,這也是第一次我們將整合型 LCD 用在 Arduino 中。

程式碼說明:

開啟 Arduino IDE,再打開賣場所提供的測試程式 使用 Arduino IDE 開啟 {HZ1050}\codes\Arduino\sketches\HZ1050\Ii2cLCD_Demo 目錄  ( 或是 File\Sketchbook\HZ1050\Ii2cLCD)Demo ) 中的 Ii2cLCD_Demo.ino。

Ii2cLCD_Demo.ino, line 204 - 228
204 //////////////////////////////////////////////////////////////////////
205 void setup() 
206 {
207  Serial.begin(9600); 
208  Serial.println("RFID Reader Ready.");
209  Wire.begin();
210 
211  #ifdef RFID_UART
212   // HZ1050
213   rfidTTL.begin(9600);
214   dataIdx = 0;
215   tagID = 0;
216  #endif
217 
218  #ifdef RFID_WIEGAND
219   wg.begin();
220  #endif
221 
222  // 整合型 LCD 初始化 @ I2C 模式
223  initLCD();
224  delay(100); // delay 100 ms
225  clearLCD();
226  delay(100); // delay 100 ms
227 
228 }

先從 setup() 函式開始看,這裡面放是一些變數或是函數的初始設定,只會執行一次 !
line 207Serial 函式庫初始化,並設定通訊速度為 9600 bps。
line 208:輸出 "RFID Reader Ready." 的字串到 Serial Monitor
line 209Wire ( 負責處理 I2C 的 ) 函式庫初始化。

line 211 - 216:若開啟 line 17 ( 就要取消 line 18 ),就會初始化 rfidTTL 函式庫並設定傳輸速度為 9600 bps;rfidTTL 是使用 SoftwareSerial 函式庫 ( 宣告在 line 33 )。
line 218 - 220:若開啟 line 18 ( 就要取消 line 17 ),就會初始化 WIEGAND 函式庫。
隨然可以同時輸出 UART 或是 Wiegand 格式,但是 LCD 顯示行數的關係,不要同時打開 line 17 和 line 18

line 223 - 226:整合型 LCD 的初始化,不需要改就是這樣初始化 LCD。初始化完成之後,直接在程式中呼叫函式 displayChatAtLCD 就可以顯示字串到 LCD 上。

Ii2cLCD_Demo.ino, line 229- 241
229 
230 void loop() 
231 {
232  #ifdef RFID_UART
233   // HZ1050 UART
234   rfidUARTRead();
235  #endif
236 
237  #ifdef RFID_WIEGAND
238   rfidWiegandRead();
239  #endif
240 
241 }

在 loop 迴圈中,程式會一直重複執行,因此將讀取 UART ( line 234 ) 以及韋根碼 ( line 238 ) 的程式都放在這裡,而開啟這兩個函式的開關就是 line 17line 18 的宣告。

程式會一直等待 HZ1050 發送資料過來,一但資料進來之後,就會根據使用者所定義所使用的方式進行解碼,解碼之後的資料會傳送到 Serial Monitor 以及整合型 LCD 上。

下面再來說明程式所使用到的函式庫與整體變數的宣告。

Ii2cLCD_Demo.ino, line 8 - 51
  8 
  9 #include <stdio.h>
 10 #include <Wire.h>
 11 #include <Wiegand.h>
 12 
 13 #define II2CLCD 0x3C // I2C address of Ii2CLCD
 14 
 15 // 可用下面選擇 RFID 讀取的模式
 16 // 兩種模式同時開啟下,只能選擇一種給 LCD 專用
 17 //#define RFID_UART
 18 #define RFID_WIEGAND
 19 
 20 // 要比對的 RFID Tag ID;可以更改為
 21 String hexTagID = "0x002285EA";  // 一定要 8 個 16 進位,不足的前方補 0
 22 long decTagID = 2262506;            // 2262506 = 0x2285EA
 23 
 24 #ifdef RFID_UART
 25 
 26  #include <SoftwareSerial.h>
 27 
 28  // Connect the Reader's RX to the RX Pin and vice versa for TX
 29  #define RFID_RX_PIN 4
 30  #define RFID_TX_PIN 5
 31 
 32  // Configure the Library in UART Mode
 33  SoftwareSerial rfidTTL( RFID_RX_PIN, RFID_TX_PIN );
 34 
 35  unsigned char udataTTL[4];
 36  char dataTTL[8];
 37  int  dataIdx;
 38 
 39  long tagID;
 40 #endif
 41 
 42 #ifdef RFID_WIEGAND
 43  // HZ1050, D1 --> Arduino D5
 44  // HZ1050, D0 --> Arduino D4
 45 
 46  // Configure the Library in WIRGAND Mode
 47  WIEGAND wg;
 48 #endif
 49 
 50 //--*
 51 

line 9 - 11:字串處理函式、I2C 讀寫函式,以及韋根碼函式庫標頭檔宣告。
line 13:定義整合型 LCD 的 I2C 位址
line 17 - 18:使用 UART 或是 WIEGAND 方式解碼接收到的資料;只能選一種。
line 20 - 21:在這裡輸入套件中鑰匙卡的卡號。
line 24 - 40:這邊是 UART 模式下一些變數與函式的宣告,除了 line 29 和 line 30 可以根據程式設計的考慮變更之外,一般情況下其他部分都毋須再做變動!
line 42 - 48:這邊是 UART 模式下一些變數與函式的宣告。需要注意的是 ! 若使用韋根方式接收資料,則接腳必須接在 Arduino 的 INT0 ( D2 ) 和 INT1 ( D3 )。

Ii2cLCD_Demo.ino, line 52 - 94
 52 /************************************************************************************
 53 * LCD
 54 ************************************************************************************/
 55 void initLCD()
 56 {
 57  Wire.beginTransmission(II2CLCD);
 58  Wire.write( 0x00 ); // N x commands
 59  Wire.write( 0x38 ); // Function set
 60  Wire.write( 0x0C ); // Display ON/OFF
 61  Wire.write( 0x01 ); // Clear display
 62  Wire.write( 0x06 ); // Entry mode set
 63  Wire.endTransmission();
 64 }
 65 
 66 void clearLCD()
 67 {
 68 
 69  Wire.beginTransmission(II2CLCD);
 70 
 71  Wire.write( 0x80 ); // One command
 72  Wire.write( 0x01 ); // Clear display 
 73 
 74  Wire.endTransmission();
 75 }
 76 
 77 void displayCharAtLCD( int line, int column, const char *dp, unsigned char len )
 78 {
 79  unsigned char i;
 80 
 81  Wire.beginTransmission(II2CLCD);
 82 
 83  Wire.write( 0x80 );
 84  Wire.write( 0x80 + ( line - 1 ) * 0x40 + ( column - 1 ) );
 85  Wire.write( 0x40 );
 86 
 87  for( i = 0; i < len; i++)
 88  {
 89   Wire.write( *dp++ );
 90  }
 91 
 92  Wire.endTransmission();
 93 }
 94 

line 55 - 94:是關於整合型 LCD 的初始化以及一些函式程式碼。

line 55 - 64initLCD() 是開機之後必須作的初始化動作,要不然不管輸入什麼東西,LCD 都不會作動!因為這些初始化流程是制式化的,除非知道相對應的位元設定的意思,要不然毋須變更。

line 66 - 75:整合型 LCD 的螢幕清除程序。

line 77 - 93:顯示字串在螢幕上的程式碼。displayCharAtLCD( line, column, *dp,  len ) 裡面的四個參數,分別控制 dp 字元陣列螢幕哪一行 ( line ) 哪一列 ( column ) 開始顯示,要顯示多少個字元 ( len )。

displayCharAtLCD() 函式的四個參數注意事項如下:
line:螢幕第一列開始輸入就設為 1;第二列則設為 2。
column:每一列有 16 字元可以輸入,由 1 開始至 16。
dp:存放顯示在 LCD 上的字元資料。
len:要取出 dp 裡面多少個字元出來顯示在 LCD 上,每次都是由 dp[0] 開始取出。

Ii2cLCD_Demo.ino, line 95 - 166
 95 /************************************************************************************
 96 * HZ1050, UART Mode
 97 ************************************************************************************/
 98 #ifdef RFID_UART
 99 void rfidUARTRead()
100 {
101  if( rfidTTL.available() ) {
102     udataTTL[dataIdx++] = rfidTTL.read();
103    }
104 
105    if(dataIdx == 4) 
106    {
107 
108   // unsigned char to char
109   for( int i = 0; i < 8; i+=2 )
110   {
111    dataTTL[i] = 0x30 + udataTTL[i/2] / 16;
112    if( dataTTL[i] > 0x39 ) dataTTL[i] += 7;  // 大於 ASCII '9' 就要變成英文 A(0x41)...      
113    dataTTL[i+1] = 0x30 + udataTTL[i/2] % 16;
114    if( dataTTL[i+1] > 0x39 ) dataTTL[i+1] += 7;
115   }
116 
117   String id = dataTTL;
118   // 顯示 16 進位資料在 LCD 上
119   displayCharAtLCD( 1, 1, "HEX:0x", 6 );
120   displayCharAtLCD( 1, 7, dataTTL, 8 );
121 
122   // 轉成 16 進位資料並比對
123   String hexCode = "0x" + id.substring( 0, 8 );
124   Serial.print("HEX Code: ");
125   Serial.print( hexCode );
126   // 16 進位比對
127   if( hexCode == hexTagID )
128   {
129    Serial.println(", HEX compare ok.");
130    /*
131     增加比對成功的處理碼在這邊
132     ...   
133    */
134   }
135   else
136   {
137    Serial.println(", HEX compare failed.");
138   }
139 
140   // 轉換為 10 進位資料並比對
141   char buf[11];  // 包括前方的 0x 共 10 個位元 + 空白字元
142   hexCode.toCharArray( buf, sizeof(buf) );
143   tagID = strtol( buf,  NULL, 0 );
144   // 顯示 10 進位資料在 LCD 上
145   char decbuf[17];
146   sprintf( decbuf, "DEC:%10lu", tagID );
147   displayCharAtLCD( 2, 1, decbuf, 14 );
148 
149   Serial.print( "Decimal: " );
150   Serial.print( tagID );
151   if( tagID == decTagID )
152   {
153    Serial.println(", DEC compare ok.");
154    /*
155     增加比對成功的處理碼在這邊
156     ...   
157    */
158   }
159   else
160   {
161    Serial.println(", DEC compare failed.");
162   }
163   dataIdx = 0;
164  }
165 }
166 #endif

line 95 - 166 這部分的程式碼就是直接由 "{ HZ1050 @ Arduino @ UART 模式 } 125KHz RFID 讀卡器使用說明" 複製過來,程式碼相差不多所以這邊就不再重複說明了。


Ii2cLCD_Demo.ino, line 167 - 204
167 /************************************************************************************
168 * HZ1050, WIEGAND (26/34) Mode, 自動偵測
169 ************************************************************************************/
170 #ifdef RFID_WIEGAND
171 void rfidWiegandRead()
172 {
173  if(wg.available())
174  {
175   Serial.print("Wiegand HEX = 0x");
176   Serial.print(wg.getCode(),HEX);
177   Serial.print(", DECIMAL = ");
178   Serial.print(wg.getCode());
179   Serial.print(", Type W");
180   Serial.println(wg.getWiegandType());
181 
182   // 顯示資料在 LCD 上
183   char lcdbuf[17];
184   sprintf( lcdbuf, "HEX%8lX, W%d", wg.getCode(), wg.getWiegandType() );
185   displayCharAtLCD( 1, 1, lcdbuf, 16 );
186   sprintf( lcdbuf, "DEC%10lu,", wg.getCode(), 14 );
187   displayCharAtLCD( 2, 1, lcdbuf, 14 );
188   if( (wg.getCode()) == decTagID )
189   {
190    Serial.println( "DEC Compare OK !");
191    displayCharAtLCD( 2, 15, "OK", 2 );
192    /*
193     增加比對成功的處理碼在這邊
194     ...   
195    */
196   }
197   else
198   {
199    displayCharAtLCD( 2, 15, "NG", 2 );
200   }
201  }
202 }
203 #endif
204 //////////////////////////////////////////////////////////////////////

line 167 - 204 這部分的程式碼就是直接由 "{ HZ1050 @ Arduino @ Wiegand 模式 } 125KHz RFID 讀卡器使用說明" 複製過來,程式碼相差不多所以這邊就不再重複說明了。


測試結果:

修改 line 17 以及 line 18,選擇要使用的接收解碼方式,再將程式上傳到 Arduino。上傳成功之後,開啟 Serial Monitor,再將套件中的鑰匙卡在線圈上面停留一下,這時 Serial Monitor 以及 LCD 螢幕上就會出現剛剛的鑰匙卡卡號。

根據選擇方式,顯示的結果如下面兩張照片所示。
HZ1050, UART 模式

HZ1050, WIEGAND 模式


結論:

HZ1050, 125KHz RFID 讀卡器的資料處理,不管是使用 UART 或是使用韋根碼讀取 EM 卡號,都已經展示再各位使用者的面前,所以這讀卡器使用起來非常的方便,也很容易融合到微處理器的電路當中,做為門禁系統或是其他想的到的應用來說,是一款很好用的模組。

期望對於有需要的使用者,能起到輔助的作用 !!!



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

沒有留言:

張貼留言