บทความ RFID พร้อมตัวอย่างการต่อใช้งาน
ตอนที่ 3 มาตรฐาน ISO15693 หรือ ICODE
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_24_11.png)
โดยเนื้อหาหลักๆ จะประกอบด้วยเนื้อหาดังนี้
- ตอนที่ 1 ความรู้เบื้องต้นเกี่ยวกับ RFID
- ตอนที่ 2 RFID มาตรฐาน ISO10536 หรือ RFID 125 KHz พร้อมตัวอย่างการต่อใช้งาน (คลิกอ่าน…)
- ตอนที่ 3 RFID มาตรฐาน ISO15693 หรือ ICODE พร้อมตัวอย่างการต่อใช้งาน (คลิกอ่าน…)
- ตอนที่ 4 RFID มาตรฐาน ISO14443 Type A หรือ Mifare พร้อมตัวอย่างการต่อใช้งาน (คลิกอ่าน…)
RFID ชื่อเต็มๆ ก็คือ Radio Frequency Identification หรือการระบุข้อมูลสิ่งต่างๆ โดยใช้คลื่นความถี่วิทยุ ซึ่งพวกเราทุกคนคงจะคุ้นเคยกับระบบนี้เป็นอย่างดี เพราะว่า RFID ถูกนำเข้ามาใช้ในชีวิตประจำวันของเราอย่างหลากหลาย เพียงแต่ว่าเราจะรู้หรือไม่เท่านั้นเองว่าสิ่งเหล่านั้นใช้เทคโนโลยี RFID
จากตารางในบทความตอนที่ 1 (คลิกดูตาราง) จะเห็นว่า RFID ที่ขายในเว็บไซต์ของเรามี 3 ประเภท คือ
1. มาตรฐาน ISO10536 หรือ RFID 125 KHz
2. มาตรฐาน ISO15693 หรือ ICODE
3. มาตรฐาน ISO14443 Type A หรือ Mifare
ในการเลือกใช้แต่ละมาตรฐานต้องคำนึงถึงว่าเครื่องอ่าน-เขียนรองรับมาตรฐานของการ์ดที่ใช้อยู่หรือไม่ เช่น เครื่องอ่าน-เขียนตามมาตรฐาน Mifare ไม่สามารถใช้ได้กับบัตร ICODE ถึงแม้ว่าจะใช้ย่านความถี่เดียวกัน คือ 13.56MHz แต่โปรโตคอลที่รับส่งข้อมูลแตกต่างกัน หากต้องการใช้ร่วมกันอาจเปลี่ยนไปใช้เครื่องอ่าน-เขียนที่รองรับหลายมาตรฐาน (Multi-Protocol) แทน เช่น Pi‐931‐X34CC จาก บจก. ซิลิคอน คราฟท์ เทคโนโลยี หรือ SL500F-USB Reader/Write จาก StrongLink Technology Co., Ltd.
2. มาตรฐาน ISO15693 หรือ ICODE เป็นมาตรฐาน RFID ที่ความถี่ 13.56 MHz เหมาะสำหรับงานต้องการเก็บข้อมูลไว้ที่บัตร ไม่ต้องการความปลอดภัยของข้อมูลบนบัตร
2.1 I.CODE SLI 13.56MHz 128 Byte Tag Card (ERFC008)
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_24_1_1.png)
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_25_1.jpg)
รูปแบบบัตร I.CODE ที่ทางเราจำหน่ายมีแบบการ์ดและฉลาก โดยก่อนที่เราจะใช้งาน RFID ประเภท ICODE จำเป็นจะต้องทราบถึงรายละเอียดโครงสร้างข้อมูลบนบัตรว่าส่วนใดเป็นข้อมูลของที่ผู้ใช้สามารถเขียนหรืออ่านได้ หรือส่วนใดเป็นส่วนแสดงรายละเอียดของบัตร จึงจะสามารถใช้งานบัตรได้ถูกต้อง
โครงสร้างข้อมูลของบัตร I.CODE SLI ขนาด 128 ไบต์ดังนี้
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_26_8.png)
จากภาพแสดงรูปแบบข้อมูลบนบัตรจะเห็นได้ว่าบัตรแบ่งข้อมูลออกเป็นบล็อค (Block) ทั้งหมด
32 บล็อค (-4 ถึง 27) ในแต่ละบล็อคเก็บข้อมูล 4 ไบต์ โดยบล็อคต่างๆ เก็บข้อมูล ดังนี้
– บล็อค -4 และ -3 เก็บค่า UID (Unique Identifier) คือ ข้อมูลของการ์ด เช่น ผู้ผลิต ชนิดของการ์ด หมายเลขซีเรียลนัมเบอร์ โดยค่า UID มีขนาดถึง 64 บิต ทำให้ต้องใช้ข้อมูล 2 บล็อคโดยบล็อค -4 เก็บ 4 ไบต์แรก บล็อค -3 เก็บ 4 ไบต์หลัง ซึ่งข้อมูลในส่วนนี้ผู้ใช้สามารถอ่านข้อมูลได้อย่างเดียว ไม่สามารถเขียนลงไปได้
– บล็อค -2 เก็บค่าคุณสมบัตรพิเศษบนบัตร ผู้ใช้สามารถเปิดใช้งานคุณสมบัติพิเศษต่างๆ เหล่านี้หรือไม่ก็ได้ ไม่มีผลต่อการอ่านหรือเขียนข้อมูลบนบัตร โดย
o ไบต์ 0 เป็นค่าที่ใช้ภายในบัตร ผู้ใช้ไม่สามารถเขียนหรืออ่านได้
o ไบต์ 1 ค่า EAS หรือย่อมาจาก Electronic Article Surveillance เป็นโหมดที่ออกแบบมาให้ทำงานในระบบป้องกันการขโมยสินค้าที่ใช้ในห้างร้านค้าทั่วไป สามารถเปิดการใช้งาน EAS โดยเซตที่บิต 0 มีค่าเป็น 1 หรือปิดโดยเซตเป็น 0 แต่จะใช้งานจะได้สมบูรณ์เมื่อนำไปใช้กับเครื่องอ่านบัตร ICODE ที่มีคำสั่งตรวจสอบค่า EAS บนบัตรด้วย
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_27_7.png)
o ไบต์ 2 ค่า AFI หรือย่อมาจาก Application Family Identifier เป็นการกำหนดรูปแบบการใช้งานของบัตร เช่น ผู้ใช้ต้องการกำหนดให้บัตรใช้ในประเภทขนส่งเท่านั้น เมื่อนำบัตรนี้ไปใช้กับเครื่องอ่านอื่นที่ตรวจค่า AFI เฉพาะด้านการแพทย์จะไม่สามารถใช้งานได้ แต่โดยค่าเริ่มต้นของบัตรกำหนดให้ใช้ได้กับงานทุกประเภท รายละเอียดสามารถอ่านเพิ่มเติมได้ที่ ISO/IEC 15693-3:2009
o ไบต์ 3 ค่า DSFID ย่อมาจาก Data storage format identifier เป็นค่าที่บรรยายโครงสร้างข้อมูลในบัตรรายละเอียดสามารถอ่านเพิ่มเติมได้ที่ ISO/IEC 15693-3:2009
– บล็อค -1 เก็บข้อมูล Write Access Condition โดยข้อมูลนี้เป็นการกำหนดสิทธิในการเขียนข้อมูลของผู้ใช้ทั้ง 28 บล็อค (0 ถึง 27) ค่ากำหนดการเขียนข้อมูลแต่ละบล็อคกำหนดดังตาราง
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_28_7.png)
จากตารางจะเห็นได้ว่าค่าเริ่มต้นของทุกบล็อคกำหนดเป็น ‘0’ คือสามารถเขียนได้ ถ้าผู้ใช้ต้องการป้องกันการเขียนข้อมูลในบล็อคที่ต้องการ เช่น ป้องกันบล็อคที่ 5 ต้องกำหนดไบต์ ที่ 1 บิตที่ 1 จาก ‘0’ เปลี่ยนเป็น ‘1’ แทน แต่เมื่อเปลี่ยนเป็น ‘1’ แล้ว Block ที่ 5 นี้จะไม่สามารถเขียนข้อมูลลงไปได้อีก
– บล็อค 0-27 เป็นข้อมูล ผู้ใช้สามารถอ่านหรือเขียนบล็อคที่ต้องการได้ ถ้าข้อมูลของ Write Access Condition (Block -1) ยังเป็นมีค่าเป็น 0 อยู่
2.2 RFID 13.56MHz Read/Write I.CODE SLI Module (UART TTL) (รหัสสินค้า EFDV029)
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_29_7.png)
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_30_6.png)
จากตารางคุณสมบัติแสดงว่าโมดูลนี้เชื่อมต่อแบบ Serial ระดับแรงดัน TTL รองรับการเขียน-อ่านข้อมูลเฉพาะบัตร ICODE เท่านั้น
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_31_4.png)
ขาที่ใช้งานบนโมดูล
– ขา IO แสดงสถานะเมื่อมีบัตรทาบที่โมดูล โดยเมื่อมีบัตรขา IO มีสถานะเป็น ‘0’ หรือ 0 V ในทางกลับกันเมื่อไม่บัตรขา IO จะมีสถานะเป็น ‘1’ หรือ 5V
– ขา TX ขาส่งข้อมูล Serial
– ขา 3 RX ขารับข้อมูล Serial
– ขา 4 ขาไฟ VCC ใช้แรงดันที่ 4.5 – 5.5 V
– ขา 5 ขากราวด์ GND
ไฟสถานะ LED State เป็น LED ที่ควบคุมโดยคำสั่งจากผู้ใช้ และ LED Tag In จะติดเมื่อมีบัตร ICODE มาทาบที่โมดูล
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_32_4.jpg)
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_33_5.png)
สามารถกำหนดความเร็ว Serial ได้ด้วยค่า R6 และ R7 ถ้าต้องการ Baud Rate เป็น 9600 ต้องลอยwไม่เชื่อมต่อ R ทั้ง 2 ตัว ดังภาพ แต่ปกติค่าเริ่มต้นจากโรงงานกำหนดไว้ที่ 115,200 คือ บัดกรี R6 และ R7 มาให้แล้ว
คำสั่งในโมดูล RFID I.CODE
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_34_5.png)
โมดูล RFID I.CODE กำหนดรูปแบบการส่งข้อมูล (Protocol) ดังนี้
1. ผู้ใช้ต้องส่งคำสั่งไปยังโมดูล (Host to Reader) เริ่มต้นจากการส่งข้อมูล 0xBA เป็นส่วนเริ่ม (Preamble) ไปก่อน ตามด้วยขนาดของข้อมูล (Len) ขนาด 1 ไบต์ คำสั่ง (Command) ขนาด 1 ไบต์ และข้อมูล (Data) แล้วปิดท้ายด้วยผลรวมสำหรับตรวจสอบ (Checksum) ขนาด 1 ไบต์
2. โมดูลส่งสถานะกลับมาที่ผู้ใช้ (Reader to Host) เริ่มต้นจากการส่งข้อมูลกลับ 0xBD เป็นส่วนเริ่มของข้อมูล (Preamble) ตามด้วยขนาดของข้อมูล (Len) ขนาด 1 ไบต์ คำสั่ง (Command) ขนาด 1 ไบต์ สถานะของคำสั่ง (Status) ขนาด 1 ไบต์ และข้อมูล (Data) แล้วปิดท้ายด้วยผลรวมสำหรับตรวจสอบ (Checksum) ขนาด 1 ไบต์
ผู้ใช้สามารถดูข้อมูลเพิ่มเติมได้จากคู่มือ RFID 13.56MHz Read/Write I.CODE SLI Module (UART TTL)
ทดลองการใช้งาน
การใช้งานโมดูล RFID I.CODE อ่าน-เขียนข้อมูลลงบนบัตร โมดูล RFID I.CODE ไม่สามารถเชื่อมต่อกับ PC ได้โดยตรง ต้องต่อวงจรเพิ่มเพื่อแปลงระดับสัญญาณเป็น Serial (RS-232) เข้า PC ทางพอร์ต Serial RS-232 หรือต่อกับ USB to Serial ที่สื่อสารในระดับแรงดัน TTL ในการทดลองนี้เชื่อมต่อกับ USB to Serial
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_35_5.png)
หรือเลือกใช้ RFID ICODE ที่เชื่อมต่อแบบ RFID 13.56MHz Read/Write I.CODE Module (RS232) (EFDV026) ที่สามารถเชื่อมต่อเข้ากับ PC ที่มีพอร์ต Serial RS232 ได้โดยตรงใช้ไฟเลี้ยงจากหัว PS/2
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_36.jpg)
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_37_4.png)
จากภาพเชื่อมต่อโมดูลเข้ากับ USB to Serial ถ้าดูที่ Device Manager จะเห็น USB to Serial เชื่อมต่ออยู่ พร้อมกับแสดงหมายเลขพอร์ต
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_38_4.png)
ทดลองนำบัตร RFID ICODE ไปทาบบนโมดูล ไฟ LED Tag In จะติดดังภาพ
1. เปิดโปรแกรม ThaiEasyEelec I.CODE โดยดาวน์โหลดได้ที่ link
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_39_4-1024x525.png)
2. เลือก Comport ให้ตรงกับที่เชื่อมต่ออยู่กับโมดูล กำหนด Baud rate ตรงกับโมดูล จากนั้นกดปุ่ม Connect
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_40_3.png)
3. กดปุ่ม Get tag Information เมื่อต้องการทราบรายละเอียดของบัตร RFID ที่ใช้งานอยู่
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_41_4.png)
โปรแกรมส่งคำสั่ง Get tag Information (0xBA,0x02,0x31,0x89) ไปยังโมดูล จากนั้นโมดูล จะส่งข้อมูลของบัตรกลับมา เป็นไปตาม Protocol ที่กำหนดไว้ในคู่มือ
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_42_2.png)
4. เมื่อต้องการทราบข้อมูลว่าบล็อคที่กำหนดมีการป้องกันการเขียนข้อมูลไว้หรือไม่ ใช้คำสั่ง Get block security state โดยกำหนด Block และ Byte (Number) บนบล็อคนั้นนั้นแล้วกดปุ่ม GET
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_43_3.png)
โมดูลจะตอบกลับดังภาพ
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_44_3.png)
5. หัวข้อ Read Block คำสั่งเมื่อผู้ใช้ต้องการอ่านข้อมูลบนบัตรโดยกำหนดบล็อคที่ให้โมดูลเริ่มอ่าน (Read Block) และหยุดอ่าน (To Block) จากนั้นกดปุ่ม Read
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_45_1.png)
6. หัวข้อ Write data to block เมื่อผู้ใช้ต้องการเขียนข้อมูลลงไปที่บัตร โดยกำหนดบล็อค (Block) และข้อมูลในช่อง Data (Hex) จากนั้นกดปุ่ม Write แล้วทดลองอ่านข้อมูลกลับจากบล็อคที่เขียนข้อมูลลงไป ซึ่งข้อมูลควรจะตรงกัน
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_46_1.png)
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_47_1.png)
7. หัวข้อ Accept to lock card เมื่อผู้ใช้ต้องการป้องกันการเขียนข้อมูลจากบล็อคที่กำหนด ให้เลือกบล็อคที่ต้องการล็อค จากนั้นกดปุ่ม LOCK
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_48_1.png)
8. นอกจากจะสามารถ Lock การเขียนข้อมูลของแต่ละบล็อค ผู้ใช้ยังสามารถ Lock การเขียน Register AFI และ DSFID ได้โดยเลือก AFI หรือ DSFID แล้วกดปุ่ม LOCK
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_49_1.png)
9. หัวข้อ Write AFI และ DSFID เมื่อผู้ใช้ต้องการกำหนดค่าให้กับ Register ทั้งสอง แต่ต้องไม่ถูกล็อคอยู่
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_50_1.png)
ทดลองเชื่อมต่อ Arduino กับโมดูล RFID I.CODE
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_51_1.png)
ต่อบอร์ด Arduino กับโมดูล RFID ICODE ผ่านขา Serial (TTL) ขาไฟ +5V และ GND โมดูล RFID กำหนด Baud rate เป็น 9600 bps โดยลอย R6 และ R7 การทดลองนี้ใช้ Library TEE_RFID_ICODE โดย Unzip แล้ววางโฟลเดอร์ไว้ที่ .. Arduino\libraries ดังภาพ
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_52_1.png)
![](https://blog.thaieasyelec.com/wp-content/uploads/2020/07/19_53_1.png)
ลองทดสอบโดยเปิด Arduino IDE ขึ้นมา ไปที่ File > Example > TEE_RFID_ICODE > RFID_Icode_test จากนั้นกดปุ่ม Upload แล้วบอร์ดจะแสดงสถานะการทำงานผ่าน Serial Monitor (Download ที่นี่)
ตัวอย่างโค้ดโปรแกรม
#include <SoftwareSerial.h> #include <icode_rfid.h> /* ------------------------ Icode RFID Library ------------------------ */ // function IcodeRFID(Rx,Tx); :: SoftwareSerial(Rx,Tx); define Rx and Tx IcodeRFID IcodeRFID(2,3); // function .begin(baudrate); for example it's define baudrate = 9600 // SoftwareSerial is use for -----> SL015M Icode RFID Reader // HarewareSerial is use for -----> PC for monitor and test function void setup(){ IcodeRFID.begin(9600); Serial.begin(9600); Serial.println(""); Serial.println("Hello RFID READER"); } void read_Taginfo(void){ taginfo *tag; tag = (taginfo *) malloc(sizeof(taginfo)); if (IcodeRFID.readTaginfo(tag)==0x00){ Serial.println("Operation Success"); Serial.print ("UID IS : "); for(int n = 0 ;n<8;n++){ String c = String(tag->uid[n],HEX); Serial.print(" "); Serial.print(c); } Serial.println(""); Serial.print("AFI : "); Serial.println(tag->afi,HEX); Serial.print("DSFID : "); Serial.println(tag->dsfid,HEX); Serial.print("TYPE IS : "); switch(tag->type){ case 0x31: Serial.println("Tag it"); break; case 0x32: Serial.println("I.code SLI"); break; } } free(tag); tag = NULL; } void test_readDATA(byte startblock,byte number){ datablock *storedata; storedata = (datablock *) malloc(sizeof(datablock)); if (IcodeRFID.readBlock(startblock,number,storedata) == OPERATION_OK){ Serial.println("Read DATA Complete"); Serial.print("DATA Block "); Serial.print(startblock,DEC); Serial.print (" To "); Serial.print(startblock+number,DEC); Serial.print(" : "); for(int n = 0 ;n<number*4;n++){ String c = String(storedata->data[n],HEX); Serial.print(" "); Serial.print(c); } } free(storedata); storedata = NULL; } void test_writeblock(byte block,byte byte1,byte byte2,byte byte3,byte byte4){ byte DAT_to_Write[4] = {byte1,byte2,byte3,byte4}; if (IcodeRFID.writeBlockFromData(block,DAT_to_Write) == OPERATION_OK){ Serial.println("Write Block Complete"); Serial.print ("DATA Block "); Serial.print (block,DEC); Serial.print (" : "); for(int n = 0 ;n<4;n++){ String c = String(DAT_to_Write[n],HEX); Serial.print(" "); Serial.print(c); } } } void test_writeAFI(byte AFI){ if (IcodeRFID.writeAFI(AFI) == OPERATION_OK){ Serial.println("Write AFI Complete"); } } void test_writeDSFID(byte DSFID){ if (IcodeRFID.writeDSFID(DSFID) == OPERATION_OK){ Serial.println("Write DSFID Complete"); } } void loop() { char a; byte startblock; byte number; if (IcodeRFID.WaitStatus(A5)){ // found card == 1 Serial.println(""); Serial.println("Found Card !!!"); int sector = 0; while(digitalRead(A5)==0){ // wait for next operation if (Serial.available() > 0){ a = Serial.read(); Serial.println(""); switch(a){ case 't': Serial.println("To Test Read TagInfo"); read_Taginfo(); break; case 'r': Serial.println("To Test Read DATA"); startblock = 0; number = 3; test_readDATA(startblock,number); break; case 'w': Serial.println("To Test Write Block"); test_writeblock(2,0x01,0x02,0x03,0x04); break; case 'a': Serial.println("To Test Write AFI"); test_writeAFI(0xAF); // set for sector 0 break; case 'd': Serial.println("To Test Write DSFID"); test_writeDSFID(0xDD); // set for sector 0 break; case 'L': Serial.println("To Test LED ON"); IcodeRFID.LED(0x01); break; case 'l': Serial.println("To Test LED OFF"); IcodeRFID.LED(0x00); break; } } } } }
จากโค้ดโปรแกรมทำงานดังนี้
void setup(){ IcodeRFID.begin(9600); Serial.begin(9600); Serial.println(""); Serial.println("Hello RFID READER"); }
ในฟังก์ชั่น setup() กำหนด software Serial IcodeRFID Baud Rate เป็น 9600 และ Hardware Serial Baud Rate เป็น 9600 เช่นกัน ส่งข้อความ “Hello RFID READER”
void loop() { char a; byte startblock; byte number; if (IcodeRFID.WaitStatus(A5)){ // found card == 1 Serial.println(""); Serial.println("Found Card !!!"); int sector = 0; while(digitalRead(A5)==0){ // wait for next operation if (Serial.available() > 0){ a = Serial.read(); Serial.println("");
ในฟังก์ชั่น Loop() ตรวจสอบเมื่อมีการ์ดเข้ามาทาบขา IO เปลี่ยนสถานะเป็น ‘1’ โดยตรวจสอบจากฟังก์ชั่น IcodeRFID.WaitStatus() แล้วโปรแกรมจะส่งข้อความ “Found Card !!!” จากนั้นจะวนตรวจสอบคำสั่งที่ส่งมาจาก PC
case 't': Serial.println("To Test Read TagInfo"); read_Taginfo(); break;
เมื่อผู้ใช้ส่งตัว “t” มา โปรแกรมจะส่งข้อความ “To Test Read TagInfo” และส่งข้อมูลของการ์ดผ่านฟังก์ชั่น read_Taginfo();
case 'r': Serial.println("To Test Read DATA"); startblock = 0; number = 3; test_readDATA(startblock,number); break;
เมื่อผู้ใช้ส่งตัว “r” มา โปรแกรมจะส่งข้อความ “To Test Read DATA” โปรแกรมจะอ่านข้อมูลของการ์ดจากฟังก์ชั่น test_readDATA ใน Block 0 Byte ที่ 3