A stand-alone access control with RFID

By on August 27, 2013
Pin It

0829_03

RFID Tags are increasingly used for many applications such as identifying objects by means of a code or access control. In logistics RFIDs allows asset tracking, or monitoring conveyor belts; in shops tags are often used as anti theft. RFIDs are also used for presence detection and security, with several use cases, for example in computer and appliance access and user identification. Due to the importance of RFIDs we propose today a simple, stand-alone project, which is basically a simple transponder enabled lock. This lock is equipped with a relay to be used to control an electric gate opener or a simple lamp. We’ll use a great module, very practical because it incorporates everything you need to make a transponder reader: the ID-12 by Innovations Technology. This component integrates the exciter coil, the logic to control absorption and that for code identification.
We presented also a RFID shield for Arduino available in the store.

Furthermore ID-12 integrates a logic that is able to output the data read from the transponder tag (according to three standards: ASCII, Wiegan26 and Magnetic ABA Track2).

Precisely because it provides transponder recognition by itself, the ID-12 is the ideal device for many systems, including electronic access gates, counters, goods classifiers and cataloguers, etc..

From the 11 pins available, pin 7 defines the data format: to read read ASCII-12 it should be put to 0 logic, if connected to pin 11 it will read Magnet ABA Track2 tags, if attached t the power supply will read Wiegan26 transponders.

ID12_PINOUT

The component sports a TTL level serial interface, that is accessible from pin 9 (TX or D0) and 8, from which the data read is outputted. Another output is available at pin 10: it blinks at a 3 kHz each time the module detects the code of a tag encoded as expected. This signal can be used to operate a buzzer without electronics or a light emitting diode, from which to report the identification event. The module can’t store codes, it only warns that it recognized something as expected, then, whether to activate the circuit is in charge of the rest of the electronics.

0829_05

Specification

  • Up to 127 tags can be stored.

  • Possibility to store\deletion of a single tag and memory reset.

  • Dynamic memory management: each tag is stored in the next available location.

  • Both bistable and monostable output operation (1 second activation).

  • Buzzer indicator of the passage of tag on the player.

 

Store

This RFID access control is available in the store

 

Circuit diagram

schema

As said, the circuit is made ​​easier thanks to the adoption of the ID-12: in the diagram we see that it is interfaced with:

  • a Microchip PIC12F683 microcontroller (a 8-bit micro-architecture RISC processor, with flash memory) to which it passes the data it reads from tags and

  • an NPN transistor (T2) that we use as a current amplifier needed to drive a buzzer.

Once fed, the ID-12 is ready to use.

In our case, pin 7 is connected to ground: the circuit will recognize tags encoded in ASCII and will output ASCII characters, which the microcontroller will either check for storing (in tracking applications) or compare with the codes in memory (as a lock).

silk

In the circuit, the ID-12 is interfaced with a microcontroller that provides tag recognition, and the actions for the identification of one of the transponders available in memory.

Upon initialization, the PIC firmware sets GP0 and GP1 as direct controls of the diodes of the LD1 two-color LED, used to signal the operating conditions. GP5 is used to command the the relay through T1 transistor (with the base polarized from the R1/R2 divider). GP2, GP3 and GP4 are initialized as inputs, reading, respectively, the incoming data from the ID-12 module, the state of the P1 butto) and the JP1 jumper condition.

The entire circuit operates with continuous and stabilized 5 volts provided by the U1 regulator coming from the supply voltage applied to + and – PWR (between 11 and 15V DC). D1 protects the circuit from reversed polarity, C1 filters impulse noise in input voltage and C2 filters out the residual alternating current (ripple), C3 and C4 filter out the 5 volts.

BOM

R1: 10 kohm
R2, R3, R5, R7: 4,7 kohm
R4, R6: 470 ohm
C1, C3: 100 nF 
C2: 220 μF 25 VL 
C4: 220 μF 16 VL 
C5, C6: 15 pF 
BZ1: buzzer 12 V c
LD1: Led 5 mm red/green
P1: Microswitch
RFID1: ID-12
RL1: relay 12 V
T1, T2: BC547
U1: 7805
U2: PIC12F683 (MF829)

 

How it works

0829_04

Once you plug the circuit and a tag approaches the reader module, pin 10 generates a one second pulse train at 3 kHz (which plays the buzzer through T2) and the micro prepares to read data from TX coming from RFID1; once data is read, the microcontroller pulls the code contained in them and compares it with those that in memory.

At this point, two things can happen: in case the code is not among those previously learnt the alarm is activated: the relay stays at rest, but the buzzer plays and the LED will turn red for a second.  If the circuit works in bistable mode and the relay has been energized by a valid transponder the diode, now with green light, switches to red and then turns green again.

Instead if the transponder read is known, we have different behaviours according to the activation mode selected: in monostable setting the micro pulses RL1 for a second and this relay will be used to control an electric lock, a gate opener or other actions. Meanwhile, the two-color LED will pulse to green light, and then turn off with the release of the relay.

In bistable mode, however, the relay changes state each time the ID-12 is approaching a valid tag: the first time RL1 clicks and stays excited, highlighted by the stable green color lighting.

0829_01

Notice that the firmware of the PIC was designed to signal tag reading in any case, irrespectively of being among those stored: indeed, if the ID-12 is approaching a non-ASCII transponder the two-color LED remains unchanged, but if you approach an ASCII tag, the message is different depending on whether the same is matched (light green) or not (red light).

 

Clearly the circuit can work with at least one RFID tag code: storing can be done as follows. After powering the board, press P1 button and keep it pressed until the LED lights up with an orange color. Then release the button and pass the transponder card that you want to store. If the LED turns off and on, the tag code has been stored, if the light remains on, the transponder code is already in memory, or the memory space may be exhausted.

At this point you can replicate the procedure to match other tags.

To exit the memory mode, press and hold the P1 button until the LED starts flashing meaning that is coming back to normal operation.

 

Tag  Cancellation

At any time you can remove a code from the memory: just power the board, press P1 button and keep it pressed until the red LED stops lighting. At this point, release the button and pass the tag you want to delete: if the LED turns off and on, the card has been canceled, differently, in case light remains on, it means that you are trying to remove from memory a transponder that is not stored in the reader. To remove more tags, just pass them one after another. To exit the procedure, hold the button until the LED starts flashing.

 

Cancellation of all tags

To cancel all tags in a single shot just power the circuit with P1 button pressed. When the red LED lights up, release the button since the cancellation is done.

Firmware (Pic Basic Pro)

'****************************************************************
'*  Name    :                                                   *
'*  Author  : Sottocornola Alessandro                           *
'*  Version : 2.1                                               *
'*  Notes   : Versione con ID tessera compressa con numero di   *
'*            byte da memorizzare impostabile con una variabile *
'*  PIC     : PIC12F683                                         *
'****************************************************************

INCLUDE "modedefs.bas"

@ DEVICE INTRC_OSC_NOCLKOUT
@ DEVICE MCLR_OFF
DEFINE OSC 4

ADCON0 = %00000000
OPTION_REG=%00000000
WPU=%00000011
CMCON0 =%00000111
ANSEL=%00000000
IOCB=%00000000
INTCON=%00000000
'OSCCON=%0111011

symbol RELE = GPIO.5
SYMBOL JUMPER = GPIO.4
SYMBOL PUSH = GPIO.3
SYMBOL RX_PIC = GPIO.2
SYMBOL LED_R = GPIO.0
SYMBOL LED_V = GPIO.1

INPUT RX_PIC
input push

INDIRIZZO var WORD  'Indirizzo memoria su cui scrivere presente sul buffer
ADDR var WORD       'Indirizzo memoria 24LC1024
I VAR byte          'Contatore di comodo
LAMP VAR BYTE
DATO_RX VAR BYTE[10]    'Dato ricevuto dalla seriale ID-12
DATO_I2C VAR BYTE[10]   'Dato letto dalla memoria
SN VAR BYTE 'S: Posizione occupata in mem. - N: Posizione non occupata in mem.
DATO_OK VAR BYTE    'Contatore per confronto dato letto in mem e da seriale
TROVATO VAR BIT     '0: Codice non trovato in mem - 1: Codice trovato in mem.
CONTATORE VAR BYTE  'Contatore di comodo per verifica pressione pulsante
FUNZIONE VAR BYTE   '0:NESSUNA - 1:MEMORIZZA - 2: CANCELLA ID - 3: RESET
RICERCA_TIPO VAR BYTE   '1: Ricercare dato presente in me - N: Ricercare posizione libera in mem.
TEMP VAR BYTE
OUT_FUNZ var byte
NUM_BYTE var BYTE   'MAX:5 --> NUM_BYTE*2 = Byte del codice del trasponder da memorizzare
CODICI VAR BYTE     'Numero di codici possibili in memoria

NUM_BYTE=2
CODICI= 255/NUM_BYTE

'************* I N I Z I O    P R O G R A M M A **************

GOSUB AVVIO 

MAIN:
    contatore=0
    if funzione=0 then  'Attivo funzione memorizzazione/cancellazione se il pulsante è premuto
        WHILE PUSH=0     
            PAUSE 500
            CONTATORE=CONTATORE+1
            select case contatore
                case is >=18    'Uscita
                    gosub out
                case is >=12    'Cancella
                    HIGH led_R
                    LOW led_V
                    FUNZIONE=2
                case is >=6     'Memorizza
                    HIGH led_v
                    HIGH led_r
                    FUNZIONE=1                
            end select     
        WEND
    else        'Se si è in memorizzazione/cancellazione controllo il pulsante per uscire dal menu
        WHILE PUSH=0
            PAUSE 500
            CONTATORE=CONTATORE+1
            if contatore>=6 then
                gosub out
            endif
        wend    
    endif

    serin2 RX_pic,84,1000,esci,[WAIT($02), STR DATO_RX\10]
    GOSUB COMPRIMI     
    SELECT CASE FUNZIONE
        CASE 0  'FUNZIONAMENTO CHIAVE
            RICERCA_TIPO="S"
            GOSUB RICERCA
            IF TROVATO=1 THEN       'Codice trovato
                IF JUMPER=0 THEN    'Bistabile
                    TOGGLE RELE 
                    TOGGLE led_v               
                ELSE                'Monostabile
                    HIGH rele 
                    high led_v               
                    PAUSE 1000
                    LOW RELE
                    low led_V
                ENDIF                 
            ELSE                    'Codice non trovato
                low led_v                
                high led_r
                PAUSE 1000                 
                low led_r
                if RELE=1 then          'Attiva il led verde se l'uscita era attiva prima di questo codice non valido                    
                    high led_v
                endif
            ENDIF                          
        CASE 1  'FUNZIONAMENTO MEMORIZZAZIONE
            RICERCA_TIPO="S"    'Verifico se il codice è già in memoria
            GOSUB RICERCA
            if trovato=0 then   'Non è già in memoria allora lo memorizzo
                RICERCA_TIPO="N"
                GOSUB RICERCA
                IF TROVATO=1 THEN
                    GOSUB SCRIVI
                ENDIF
            endif
        CASE 2  'FUNZIONAMENTO CANCELLAZIONE
            RICERCA_TIPO="S"
            GOSUB RICERCA
            IF TROVATO=1 THEN
                GOSUB CANCELLA
            ENDIF              
    END SELECT
    GOSUB AZZERA
ESCI: 
GOTO MAIN

'**************** O U T ****************
OUT:
    funzione=0
    GOSUB LAMPEGGIA_V
    WHILE PUSH=0    'SE IL PULSANTE è ANCORA PREMUTO PER SBAGLIO NON FACCIO NULLA
    WEND
    if RELE=1 then
        LOW LED_R
        high led_v
    endif
return

'**************** L A M P E G G I A ****************
LAMPEGGIA:
    low led_r
    low led_v
    for I=0 to 11
        toggle led_v
        toggle led_r
        PAUSE 200
    next i
return

'**************** L A M P E G G I A - V ****************
LAMPEGGIA_V:
    low led_v
    low led_r
    for I=0 to 11
        toggle led_v
        PAUSE 200
    next i
return

'**************** S C R I V I ****************
'Scrittura nella locazione INDIRIZZO del codice letto dalla seriale
SCRIVI:
    ADDR=indirizzo*NUM_BYTE
    for i=5-num_byte to 4
        WRITE addr,DATO_RX[i]
        PAUSE 10
        addr=addr+1
    next i
    low led_v                
    LOW LED_R
    PAUSE 1000
    high led_v
    HIGH LED_R
return

'**************** C A N C E L L A ****************
'Cancellazione di una specifica locazione
CANCELLA
    ADDR=indirizzo*NUM_BYTE
    for i=0 to num_byte-1        
        WRITE addr,$FF
        PAUSE 10
        addr=addr+1
    next i    
    low led_r
    PAUSE 1000
    high led_r
RETURN

'**************** R I C E R C A ****************
'Ricerca codice letto da seriale ID-12 con restituzione indirizzo
RICERCA:
    select case ricerca_tipo
        case "S"    'Ricerca tra le locazioni di memoria occupate
            FOR INDIRIZZO=0 TO CODICI-1
                ADDR=indirizzo*NUM_BYTE   
                for i=5-num_byte to 4
                    read addr,dato_i2c[i]
                    addr=addr+1
                next i
                GOSUB CONTROLLO
                IF DATO_ok=NUM_byte THEN
                    TROVATO=1                                       
                    GOTO ESCI_RICERCA
                ENDIF
            next indirizzo
        case "N"    'Ricerca posizione non occupata
            dato_ok=0
            FOR INDIRIZZO=0 TO CODICI-1
                ADDR=indirizzo*NUM_BYTE    
                for i=5-num_byte to 4
                    read addr,dato_i2c[i]
                    if dato_i2c[i]=$FF then
                        dato_ok=dato_ok+1    
                    endif
                    addr=addr+1
                next i
                IF DATO_OK=num_byte THEN
                    trovato=1
                    goto ESCI_RICERCA
                ENDIF
            next indirizzo
    end select    
ESCI_RICERCA:
RETURN

'**************** R E S E T _ M E M ****************
'Cancellazione totale memoria
RESET_MEM:
    HIGH led_r
    pause 2000    
    FOR INDIRIZZO=0 TO 255
        WRITE addr,$FF
        PAUSE 10
    NEXT INDIRIZZO    
    LOW led_r
    while push=0    'Se il pulsante è ancora premuto non faccio niente
    wend
RETURN

'**************** C O N T R O L L O ****************
'Confronto del dato letto in memoria e di quello letto da seriale ID-12
'se DATO_OK=10 allora i due dati sono uguali
CONTROLLO:
    DATO_OK=0
    for i=5-num_byte to 4
        IF DATO_I2C[i]=DATO_RX[i] THEN
            DATO_OK=DATO_OK+1
        ENDIF
    next i
RETURN

'**************** A Z Z E R A ****************
'Reset variabili
AZZERA:
    trovato=0
    FOR I=0 TO 9
        DATO_RX[I]=0
        DATO_I2C[I]=0
    NEXT I
RETURN

'**************** I N I Z I A L I Z Z A ****************
'Fase di inizializzazione all'avvio
INIZIALIZZA:    
    TROVATO=0
    CONTATORE=0
    FUNZIONE=0
    LOW RELE    
    GOSUB AZZERA     
RETURN

'**************** A V V I O ****************
'Controllo all'avvio, se il tasto è premuto per reset memoria oppure no
AVVIO:
    GOSUB LAMPEGGIA
    IF PUSH=0 THEN  'Se tasto premuto all'avvio forzo il reset memoria
        GOSUB RESET_MEM
    ENDIF
    GOSUB INIZIALIZZA
RETURN

'**************** C O M P R I M I ****************
'Converto il codice da ASCII (10 byte) a HEX (5 byte) per risparmiare spazio
'in memoria e quindi rendere più veloce la ricerca. In HEX impiega la metà del 
'tempo perchè vi è la metà dei byte da controllare
COMPRIMI:
    I=0
    WHILE I<9
        TEMP=DATO_RX[I]
        IF TEMP>57 THEN
            TEMP=TEMP - 55
        ELSE
            TEMP=TEMP - 48
        ENDIF                         
        TEMP=TEMP * 16
        DATO_RX[I]=TEMP
        TEMP=DATO_RX[I+1]
        IF TEMP>57 THEN
            TEMP=TEMP - 55
        ELSE
            TEMP=TEMP - 48
        ENDIF
        TEMP=TEMP + DATO_RX[I]    
        DATO_RX[I]=TEMP
        I=I+2
    WEND
    TEMP=DATO_RX[0]
    DATO_RX[0]=TEMP
    TEMP=DATO_RX[2]
    DATO_RX[1]=TEMP
    TEMP=DATO_RX[4]
    DATO_RX[2]=TEMP
    TEMP=DATO_RX[6]
    DATO_RX[3]=TEMP
    TEMP=DATO_RX[8]
    DATO_RX[4]=TEMP
RETURN

About Boris Landoni

Boris Landoni is the technical manager of Open-Electronics.org. Skilled in the GSM field, embraces the Open Source philosophy and its projects are available to the community.

15 Comments

  1. Pingback: Electronic Access Control · WWW.INFOWEBHUB.NET

  2. Pingback: fnmgwvkt

Leave a Reply

Your email address will not be published. Required fields are marked *