RFID, Radiofrekvencna identifikacija

RFID je tehnologija, pri kateri izvajamo identificiranje s pomočjo elektromagnetnega valovanja na področju radijskih frekvenc. Njena glavna prednost je, da RFID odzivnike, ki hranijo neko informacijo, lahko prepoznamo brezkontaktno (tudi v primerih, ko niso vidni direktno).

Kako deluje RFID?

Ko RFID odzivnik vstopi v območje dosega RFID čitalnika, ta preko ustrezne antene s pomočjo radijskih valov prebere podatke, ki so zapisani v odzivniku. Odzivnike tvorijo majhna integrirana elektronska vezja (čipi) in RF antene. Če vsebujejo tudi baterijo, govorimo o aktivnih odzivnikih, sicer pa so pasivni. Obstajajo zelo različne oblike RFID odzivnikov: etikete (pravimo jim tudi pametne nalepke), kartice, obeski, steklene cevke, ploščice, diski, škatlice in podobno. Uporabljamo jih za označevanje in sledenje živali, prepoznavanje artiklov v trgovinah, plačilo cestnine, spremljanje pošiljk v logistiki, pri izposoji knjig v knjižnicah, registraciji delovnega časa, za kontrolo dostopa (v posebej zaščitene prostore, na parkirišča, v garaže), za kodiranje ključev, spremljanje proizvodnih procesov ipd

RFID sistem sestavljajo naslednje komponente: RFID odzivniki, RFID čitalniki in RFID antene. Ker večina RFID odzivnikov, ki so v uporabi danes, za napajanje ne uporablja lastne energije (nimajo vgrajene baterije, govorimo torej o pasivnih odzivnikih), jo dobijo z radijskimi valovi. Čitalnik stopi v stik z odzivnikom preko svoje RFID antene, ki v prostor okoli sebe oddaja radijske valove. Kadar se odzivnik nahaja dovolj blizu anteni, sprejme te radijske valove in si s tem zagotovi napajanje za delovanje. To mu omogoča, da po nekem določenem protokolu s čitalnikom vzpostavi komunikacijo, v okviru katere si izmenjata želene podatke.

V vsak RFID sistem so vključene le takšne komponente, ki delujejo na isti frekvenci (npr. odzivnika, ki deluje na 125 kHz ne moremo uporabljati v sistemu, ki deluje na 13,56 MHz). Frekvenco RFID sistema izberemo glede na name uporabe, saj se nekatere značilnosti delovanja pri različnih frekvencah razlikujejo (razdalja prepoznavanja odzivnikov, hitrost prenašanja podatkov in podobno). Mi bomo uporabili pasivni RFID sistem, ki deluje na frekvenci 125 kHz:

Branje RFID odzivnikov, v našem primeru kartic in tag-ov, z razvojno ploščo Arduino Uno:

Slika 2: Povezava RFID komponent z razvojno ploščo Arduino Uno.

//Program za identifikacijo kartic oz. tag-ov:

/*

  Identifikacija RFID kartic oz. tag-ov s čitalcem RFID 125 kHz.

  Avtor: Milan Ivič

  Jan. 2015

*/

 #include <SoftwareSerial.h>     //Knjižnica za serijsko komunikacijo

 SoftwareSerial RFID(2, 3);      //RX in TX. Mi samo beremo => pin 2

 int i;                          //V spremenljivko i se bo shranjevala koda odzivnika (kartice oz. tag-a)

 void setup()

 {

   RFID.begin(9600);                 //Start serijske komunikacije z RFID čitalcem

   Serial.begin(9600);               //Start serijske komunikacije z računalnikom

 }

 void loop()

 {

   if (RFID.available() > 0)         //Ali je RFID zaznal odzivnik (kartico oz. tag)?

   {

      i = RFID.read();

      Serial.print(i, DEC);          //Izpiši kodo odzivnika v decimalni obliki na serijski monitor

      Serial.print(" ");             //Med posameznimi kodami napiši presledek

   }

 }

Najprej pojasnilo glede uporabe SoftwareSerial. Če bi podatkovni izhod iz RFID ploščice povezali na pin RX Arduinove ploščice, bi morali to povezavo ob vsakem zapisu programa prekiniti. Bolj priročno je torej, da podatkovni izhod povežemo na pin 2.

Vsaka kartica ali tag ima 96 bitno identifikacijsko standardno kodo. Prvih 8 bitov predstavlja glavo kode. Naslednji 4 biti predstavljajo filter. Sledi 48 bitna koda, ki označuje dobavitelja in zagotavlja edinstveno serijsko številko RFID odzivnikov (kartic, tag-ov itd). Zadnjih 36 bitov predstavlja edinstveno kodo, ki jo določi dobavitelj.

V našem primeru bo koda na serijskem monitorju izpisana v desetiškem (decimalnem) številskem sistemu.

Slika 3: Izpis kode RFID kartice na serijsem monitorju.

//Program za uporabo RFID bralnika:


/*

 Identifikacija in kontrola dostopa z RFID karticami oz. tag-i.

 L1 in L2 => antena.

 Tx RFID 125 kHz => digitalni pin 2 Arduino.

 Avtor: Milan Ivič

 Januar 205

 */

 #include <LiquidCrystal.h>

 #include <SoftwareSerial.h>  //Knjižnica.

 SoftwareSerial RFID(2, 3);     //RX in TX. Mi samo beremo => pin 2.

 int Podatek_1 = 0;

 int OK = -1;

 int LED_pravilno = 9;          //LED zelena.

 int LED_nepravilno = 10;       //LED modra.

 int Kljucavnica = 12;

 //Za kodo kartic oz. tag-ov uporabimo program za identifikacijo RFID kartic.

 //Za vsako kartico, ki ji dovolimo vhod, zapišemo njeno kodo:

 int Kartica_1[16] = {52,65,48,48,49,52,57,48,53,49,50,54,48,69,13,10};

 int Kartica_2[16] = {53,53,48,48,49,52,53,54,57,51,51,54,48,55,13,10};

 int Kartica_3[16] = {48,53,48,48,49,48,49,52,48,52,52,55,48,56,13,10};

 int Nova_kartica[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};    //Uporabimo v programu za primerjavo.

 LiquidCrystal lcd(3,4,5,6,7,8);     //Priključki LCD na pine Arduino.

 void setup()

 {

   RFID.begin(9600);                            //Start serijske komunikacije z RFID čitalcem.

   Serial.begin(9600);                          //Start serijske komunikacije z računalnikom.

   pinMode(LED_pravilno, OUTPUT);     //Zelena LED dioda => izhodni pin.

   pinMode(LED_nepravilno, OUTPUT);  //Modra LED dioda => izhodni pin.

   pinMode(Kljucavnica, OUTPUT);

   lcd.begin(16,2);                             //LCD 2x16 => dve vrstici, vsaka po 16 znakov.

 }

 boolean Primerjaj_kartico(int aa[16], int bb[16])

 {

   boolean ff = false;

   int koda = 0;          //Inicializacija.

   for (int cc = 0; cc < 16; cc++)      //Primerjaj vseh 16 mest kode.

   {

     if (aa[cc] == bb[cc])

     {

       koda++;

     }

   }

     if (koda == 16)

     {

       ff = true;

     }

   return ff;

 }

 void Preveri_kartico()        //Preverjanje ujemanja kode kartice oz. tag-ov.

 {

   OK = 0;     //Ta spremenljivka pomaga pri sprejemanju odločitve o ustreznosti kode.

                //OK = 1 => koda sprejeta.

                //OK = 0 => koda je prabrana a ni pravilna.

                //OK = -1 => poizkus branja kode ni uspel.

 

   if (Primerjaj_kartico(Nova_kartica, Kartica_1) == true)

   {

     OK++;          //Povečaj OK za 1 => Če je koda ustrezna je vrednost OK enaka 1.

   }

   if (Primerjaj_kartico(Nova_kartica, Kartica_2) == true)

   {

     OK++;

   }

   if (Primerjaj_kartico(Nova_kartica, Kartica_3) == true)

   {

     OK++;

   }

   delay(500);

   lcd.clear();    

   lcd.setCursor(2,0);

   lcd.print("Preverjam");

   lcd.setCursor(2,1);

   lcd.print("kartico");

   delay(1000);

   lcd.clear();

 }

 void Branje_kartic()     //Funkcija za branje kartic oz. tag-ov.

 {  

   OK = -1;

 

    lcd.setCursor(2,0);            

    lcd.print("Pribljizaj");             

    lcd.setCursor(2,1);            

    lcd.print("RFID kartico");

   if (RFID.available() > 0)      //Ali so na voljo podatki RFID kartice (oz. tag-ov)?

   {

     //Branje kartice oz. tag-a.

     delay(400);    //Zakasnitev, da se lahko preberejo podatki.

     for (int z = 0; z < 16; z++)       //Branje celotne 16-mestne kode.

     {

       Podatek_1 = RFID.read();

       Nova_kartica[z] = Podatek_1;      //Prebrana vrednost kode se shrani v Nova_kartica[z].

     }

     RFID.flush();                       //Začasna ustavitev branja 16-mestne kode.

     //Ali se 16-mestna koda ujema s katero od dovoljenih (napisanih) kod?

     Preveri_kartico();     //Klicanje rutine (podprograma) za preverjanje ujemanja kode.

   }

   //Ustrezni Izpis oz Vklop ustrezne LED, odvisno od sprejete kode:

   if (OK > 0)     //Ali je koda kartice pravilna?

   {  

     //Koda je pravilna, izvedi naslednji blok:

     lcd.setCursor(2,0);

     lcd.print("Koda sprejeta");

     lcd.setCursor(2,1);

     lcd.print("Odpri vrata");     

     Serial.println("Dovoljeno, koda sprejeta");

     digitalWrite(LED_pravilno, HIGH);

     delay(3000);

     lcd.clear();

     digitalWrite(LED_pravilno, LOW);

     OK = -1;    //Začetna nastavitev spremenljivke OK.

   }

   else if (OK == 0)    //Koda kartice ni pravilna, ali je nepravilna koda?

   {

     //Kartice s prebrano kodo ni na spisku dovoljenih, izvedi naslednji blok:

     lcd.clear();

     lcd.setCursor(1,0);

     lcd.print("Zavrnjeno, koda");

     lcd.setCursor(1,1);

     lcd.print("ni sprejeta");

     Serial.println("Zavrnejo, koda ni sprejeta");

     digitalWrite(LED_nepravilno, HIGH);

     delay(1500);

     lcd.clear();

     digitalWrite(LED_nepravilno, LOW);

     OK = -1;

   }

 }

 void loop()

 {

   Branje_kartic();

 }

Dodatni opis programa:

Iz glavne zanke void loop, ta se stalno ponavlja, kličemo funkcijo Branje_kartic(). Če so na voljo podatki iz RFID čitalnika (serijska komunikacija z RFID), se prebere celotna 16-mestna koda kartice ali tag-a, odvisno od tega, kateri odzivnik uporabljamo. Prebrana 16-mestna koda se shrani v spremenljivko Nova_kartica[z] (spremenljivka Nova-kartica je deklarirana kot enodimenzionalno polje s 16-timi elementi). Z RFID.flash() začasno ustavimo branje kode. Ustavi se za toliko časa, dokler prenašanje podatkov ni končano. Nato kličemo rutino za preverjanje kode, Preveri_kartico().

V rutini Preveri_kartico() primerjamo shranjeno kodo z vsemi kodami kartic (ali tag-ov), ki jih imamo napisane v programu kot dovoljene. V našem programu so tri. Če se shranjena prebrana koda ujema s katero od dovoljenih, se spremenljivka OK poveča za 1, sicer pa njena vrednost ostane 0. Program se v funkcijo Branje_kartic() vrne z vrednostjo spremenljivke OK. Če branje kartice (tag-a) ni bilo uspešno, ostane vrednost spremenljivke OK enaka -1. Če je bilo branje uspešno, koda pa ni enaka nobeni od dovoljenih, je vrednost OK enaka 0. Č je bilo branje uspešno in se koda ujema s katero od dovoljenih kod, pa je vrednost OK enaka 1.

V rutini Boolean Primerjaj_kartico(int aa[16], int bb[16]) primerjamo posamezna mesta prebrane kode Nova_kartica s posameznimi mesti dovoljene kode Kartica_1 (in ostale dovoljene). Spremenljivka aa prevzame vrednost spremenljivke Nova_kartica, spremenljivka bb pa prevzame vrednost spremenljivke Kartica_1 (in nato ostale dovoljene).

Načrt priključitve elementov na razvojno ploščo Arduino Uno:

Slika 4: Shema povezav elementov in priključitve na razvojno ploščo Arduino

Spisek potrebnega materiala:

- Razvojna plošča Arduino Uno

- LCD display 16x2

- RFID 125 kHz komponente (http://www.agreetao.com/taobao/view/id/5010509386)

- Rele TRK22, 5 V

- Trimer potenciometer 4,7 kohm

- Tranzistor BC337

- Upor 1,2 kohm

- Upor 470 ohm, 2 kos

- LED dioda, 5 mm, visokosvetleča modra

- LED dioda, 5 mm, visokosvetleča zelena

- Elektronska ključavnica (npr.: http://cpc.farnell.com/1/1/62309-lock-release-12vacdc-flock-adcn203s-dorcas.html) ali podobna.

- Vezice

Rele uporabimo zato, ker je električna poraba elektronske ključavnice, ki smo jo uporabili prevelika za tranzistor BC337. Za svojo delovanje potrebuje namreč napetost 12 V tok 900 mA. Zato rele krmilimo s tranzistorjem, preko kontaktov releja pa elektronsko ključavnico.