Video-tutorial de la semana

jueves, 11 de noviembre de 2010

Control de Acceso Usando la RFid – Parte IV

En esta entrada se muestran los resultados obtenidos, se muestra en fotografías la operación básica del sistema para el control de acceso, aunque el actuador no fue una cerradura eléctrica fue sustituido por un foco incandescente de 127vAC que es el que simula el acceso, al lugar restringido.
Implementación del sistema control de acceso

El sistema fue implementado como inicio, en una plantilla para experimentos (protoboard) es mostrado en la figura siguiente y la cual se aprecia los siguientes elementos.



 Lector RFID.
 Etiquetas RFID.
 PIC16F73.
 Una pantalla LCD de 2x16 caracteres.
 Modulo de potencia (formado por un MOC3011 y TRIAC )
 Actuador (en este caso representado por un foco para 127v).

Además en la imagen también se ve un dip-switch para seleccionar las opciones activo o modo programación, además del grabado y borrado de etiquetas.

Bienvenida el sistema control de acceso

Un letrero de bienvenida al sistema se muestra en la pantalla LCD al inicio de la ejecución del código, la figura siguiente muestra tal y como se ve el LCD al desplegar el mensaje.
 Sistema de RFID en modo de Activo

En las siguiente imágenes se muestran los letreros que aparecen en la pantalla LCD a medida que trascurre la ejecución del programa, cuando el sistema está operando en modo activo. Por ejemplo la siguiente figura se muestra la opción seleccionada como activo que quiere decir que el sistema esta esperando leer las etiquetas, si son autorizadas, activa el foco y si no no o enciende el letrero desplegado es como el mostrado en dicha figura. Esta opción es elegida con el dip-switch o cuando RC0 del PIC es igual a “1” también se ve en la figura siguiente

El siguiente paso es leer la etiqueta tal como lo indica el diagrama de flujo del post anterior, en este paso de leer etiqueta se activa al Lector RFID (se ve en la figura el LED del lector encendido que significa que esta activado) y se comienza la lectura de la etiqueta RFID; al acercar la etiqueta al lector se se despliega el mensaje como la figura siguiente que muestra el numero serial de la etiqueta que ya viene predefinido de fabrica.
El valor que se obtuvo de la etiqueta que acaba de ser leída se compara y verifica para saber si es una etiqueta autorizada o no, previamente se debieron grabar las etiquetas autorizadas obviamente.

La figura siguiente muestra el caso en que la etiqueta leída sea autorizada y en consecuencia mostrara un mensaje de autorización y activa el actuador (foco).


La figura 5.6 muestra el mensaje en la pantalla LCD, si la etiqueta no está autorizada, obviamente no enciende el actuador


Sistema de RFID en modo Programación

Las siguientes imágenes muestran el funcionamiento del sistema en modo programación este modo me permite dos acciones:

• Grabar las etiquetas autorizadas
• Borrar etiquetas guardadas

La figura siguiente, muestra la pantalla inicial cuando se elige este modo en el sistema.

La figura siguiente muestra el mensaje del LCD justo cuando se estaba en el modo de programación y se acerco una etiqueta al lector y se guardo en la memoria RAM del PIC

También este modo me permite borrar las etiquetas que ya han sido previamente guardadas, se probo con una etiqueta ya guardada, la figura siguiente muestra el mensaje justo después de borrar una etiqueta

Con esto se termina la serie de entradas del control de acceso, se puede ver que de una forma fácil y económica se implemento un sistema de identificación por radio frecuencia.
Clic AQUI para leer más...

lunes, 8 de noviembre de 2010

Control de Acceso Usando la RFid – Parte III

Hoy se muestra la parte III del proyecto control de acceso, esta parte habla del diseño del software para el microcontrolador PIC16F73, se muestra el código del programa, se realizarón todas las funciones para el LCD, no se uso ninguna librería ni para el LCD ni para la comunicación serial,  todo fue en base a las hojas de datos y se puso todo el código quizá a alguna persona le pueden servir las funciones para otros proyectos, el código se edito en el entorno llamado SourceBoost IDE, da clic aqui si deseas bajar este compilador de C para PIC.

4.1 Diagrama de flujo del programa

La siguiente figura muestra el diagrama de flujo del programa realizado para el microcontrolador




El funcionamiento del sistema en terminos generales es así:
• El sistema envía un mensaje de bienvenida en el LCD

• Por medio de un switch se elige el modo de programación o el modo de monitoreo

        o El modo de monitoreo sirve para leer las etiquetas y activar o desactivar la cerradura
           electrónica, en caso de recibir una etiqueta autorizada o no.

       o El modo de programación almacena las etiquetas autorizadas en la memoria del PIC.

Componentes del software.

El código fuente está compuesto por funciones, estas realizan una determinada acción sobre el sistema de hardware, de la misma manera se conforma de una función principal (main), que es la que gobierna todas las funciones que conforman el programa, y las cuales se describe en el presente capitulo. El software desarrollado para el PIC fue realizado en el entorno SourceBoost usando como base el lenguaje C, no se usaron ninguna librería para el LCD todo fue programado.

Programa principal (main)

El programa principal está en el listado 4.1; se comentan algunas líneas de código para mejor comprensión del programa.

Listado 4.1 Función para seleccionar opciones.

 1 void main()
 2 {
 3   int u,c,i,opcion;
 4   char tag[11];
 5   char DatosDeEtiqueta[11];
 6   char string[33];
 7   adcon1=0x06;  // puerto A como I/O digitales
 8   trisb=0x00;   // Se configura el Puerto B como salida
 9   trisa=0x00;   // Se configura el Puerto A como salida
10   porta=0x00;   // Pone al Puerto A apagado
11   trisc=0x87;   // 1000 0111 puerto C como entradas y salidas
12   def();    // Se manda llamar la subrutina de default
13   iniLCD();   // Se manda llamar la subrutina de inicialización
14   configserial();  // Llama la funcion configurar serial
15   set_bit(portc,5);  // Led VERDE desactivado lector RFID
16   strcpy(string, "  BIENVENIDOS   CONTROL  ACCESO");
17   escribeCadenaEnLCD(string);
18   delay_s(3);
19   inst(0x01);  // borrar LCD
20   while (1)
21     {
22       opcion=menu();
23       switch (opcion)
24         {
25         case 1:
26           leerEtiquetaDeRF(DatosDeEtiqueta);
27           if (portc.5==1)
28             {
29               strcpy(string, "   ETIQUETA #      ");
30               escribeCadenaEnLCD(string);
31               mostrarEtiquetaEnLCD(DatosDeEtiqueta);
32               delay_s(3);
33               inst(0x01);  // instrucción borra LCD
34             }
35           c=0;
36           for (i=0; i<11; i++)
37             {
38               if (tag[i]==DatosDeEtiqueta[i]) // verifica tag valido
39                 {
40                   c++;
41                 }
42             }
43           if (c<=10)
44             {
45               porta.5=1;
46               strcpy(string, "     ACCESO        AUTORIZADO");
47               escribeCadenaEnLCD(string);
48               delay_s(10);
49               inst(0x01);  // instrucción borra LCD
50               porta.5=0;
51             }
52           else
53             {
54               strcpy(string, "    ACCESO         DENEGADO");
55               escribeCadenaEnLCD(string);
56               delay_s(3);
57               inst(0x01);    // instrucción borra LCD
58             }
59           break;
60         case 2:
61           if (portc.1==0)          //push botton # 1
62             {
63               for (i=0; i<11; i++)
64                 {
65                   tag[i]=0x00; // borra un tag(etiqueta) grabada
66                 }
67               strcpy(string, "   ETIQUETA          BORRADA");
68               escribeCadenaEnLCD(string);
69               delay_s(3);
70               inst(0x01);   // instrucción borra LCD
71             }
72           if ((portc.1==1) && (portc.2==0)) // push botton 1 y 2
73             {
74               strcpy(string, "    GRABANDO        ETIQUETA");
75               escribeCadenaEnLCD(string);
76               leerEtiquetaDeRF(DatosDeEtiqueta);
77               u=0;
78               for (i=0; i<12; i++)
79                 {
80                   tag[u]=DatosDeEtiqueta[i]; //grabar tag en arreglo
81                   u++;
82                 }
83               inst(0x01); // instrucción borra LCD
84               strcpy(string, "ETIQUETA GRABADA ES ");
85               escribeCadenaEnLCD(string);
86               mostrarEtiquetaEnLCD(DatosDeEtiqueta);
87               delay_s(3);
88               inst(0x01); // instrucción borra LCD
89             }
90           if ((portc.1==1) && (portc.2==1))
91             {
92               menu();
93               delay_s(3);
94             }
95           break;
96         } // fin de switch
97     } // fin de while
98 } // fin de función main
99 

Funciones para el LCD.
Las funciones necesarias para trabajar con la pantalla LCD son tres esencialmente, y son la inicialización, enviar instrucción y enviar dato, estas funciones fueron programadas usando los diagramas de tiempo pueden verse en cualquier hoja de datos para el LCD.

Función para inicializar LCD.
Esta función es la encargada de la inicialización de la pantalla LCD; En el listado 4.2 de escribe una función llamada def, descrita en el programa como función default , esta es necesaria para controlar los estados de E (enable del LCD ) , por el hecho de que enable del LCD debe cambiar a “0” valor de “inicial”, para que al interpretar la función iniLCD (descrita posteriormente en el listado 4.4) sea única para cada instrucción enviada.

Listado 4.2 función default devuelve  E=0.
01 void def()     // Condiciones default del LCD.
02 {
03   clear_bit(porta,0);   // Señal E = 0
04   set_bit(porta,1);  // Señal RW = 1
05   set_bit(porta,2);  // Señal RS  = 1
06 }
07 

El listado 4.3 muestra una función que carga un valor de inicialización y consta de una retardo de 15ms y las instrucciones que se carga una a una a la función llamada inst (instrucción al LCD); estos valores se toman de la tabla 3.7 y tabla 3.8 expuestas en el capitulo III.

Listado 4.3 función para carga el valor de inicialización.
01 void iniLCD()  // Condiciones para inicializar el LCD
02 {
03   delay_ms(15);  // Espera 15 milisegundos
04   inst(0x01);   // 0000 0001 limpia LCD
05   inst(0X3F);   // 0011 1111 Funtion Set: 8bit, activa 2 líneas, 5x10 puntos.
06   inst(0X0F);   // 0000 1111 on/off pantalla y cursor, parpadea el cursor.
07   inst(0X06);  // 0000 0110 Modo de Entrada de caracteres
08 }
09 

Función para escribir instrucciones
Para enviar una instrucción al LCD y inicializarlo es necesario cumplir con los tiempos requeridos y expuestos en el capitulo III, en la sección 3.5.2, con uso del diagrama de tiempo expuesto en la figura 3.10 de dicho capitulo, por lo tanto, es necesario crear una función que lo realice; el siguiente listado 4.4 describe una función llamada inst() que en conjunto con las función def y la función iniLCD descritas anteriormente cumplen con ese diagrama de tiempo.

Listado 4.4 función para enviar instrucción al LCD.

01 void inst(int i)   // Secuencia para enviar las instrucciones al LCD
02 {
03   clear_bit(porta,2);  // RS = 0
04   clear_bit(porta,1); // RW = 0
05   portb=i;  // carga el valor de i al puerto B
06   set_bit(porta,0); // E = 0
07   delay_ms(50);  // retardo de 50 milisegundos
08   def();   // llama a la función def
09 }
10 

Función para enviar dato al LCD.

Al igual que la función para enviar instrucciones al LCD, la función de enviar datos en esta caso la función se llama datos(); Hace uso también de la función def, para regresar el valor E=0; La función “enviar datos” se muestra en el listado 4.5, la cual cumple con el diagrama de tiempo de una LCD estándar. Esta función es usada para escribir los datos en LCD, tanto los obtenidos por las etiquetas RFID como los letreros de información de estado del sistema; La descripción de esta función es tan simple como la función de enviar instrucción, solamente que en esta función cambian los valores RS, E y RW , lo cual se describe en las hojas de daos de una LCD

Listado 4.5 función para enviar dato al LCD .
01 void datos(int j)  // Instrucciones para enviar los datos al LCD
02 {
03   set_bit(porta,2); // RS = 1
04   clear_bit(porta,1); // RW = 0
05   portb=j;  // carga el valor de j al puerto B
06   set_bit(porta,0); // E = 1
07   delay_ms(20);  // retardo de 50 milisegundos
08   def();   // llama a la función def
09 }
10 

Función para escribir el número de etiqueta en el LCD.
Esta función llamada en el programa principal así: mostrarEtiquetaEnLCD, requiere que otras funciones sean ejecutadas con anterioridad, las cuales obtiene el numero de etiqueta, para posteriormente, poder mostrar su valor en el LCD, pero por razones de orden y descripción del programa es mencionada primero.

Esta función es mostrada en el listado 4.6, la función opera de la siguiente manera, los datos cargados en el arreglo etiqueta[ ] , son enviados a la función datos() para qué esta función los escrita en el LCD.

Al comenzar la función inicializamos una variable llamada u donde esta variable tomó valores desde 1 hasta 10, que representan los datos obtenidos del etiqueta; Que son los que se pueden mostrar, esto se describe en la sección anterior donde se habla del protocolo de cserial del lector, lafunción sólo mostrará los 10 bytes donde está escrito él ID del etiqueta leída.
Es de notar el arreglo etiqueta[] ese tipo char, el cual devuelve un valor hexa-decimal representativo de tipo ASCII, que se reciben del etiqueta en cuestión. El primer byte de start 0x0A se ubica en la posición etiqueta[0] y el byte de stop 0x0D se ubica en la posición etiqueta[11], es por eso que u comienza en uno y terminar en 10 el byte start y stop de la etiqueta no es necesario mostrarlos.

Listado 4.6. Función muestra datos de etiqueta en el LCD .
01 void mostrarEtiquetaEnLCD(char etiqueta[])
02 {
03   int u;     // declaramos una variable
04   for (u=1; u<11; u++)    // ciclo for con u =1 hasta U=11
05     {
06       datos(etiqueta[u]);  // llama a la función datos()
07       delay_ms(100);  // retardo 100 milisegundos
08     }
09 }
10 

Función para escribir una cadena de texto en el LCD
Al usar esta función llamada escribeCadenaEnLCD y que se muestra en el listado 4.7, se puede mandar una cadena de caracteres “texto” al LCD, sin la necesidad de escribir cada letra del texto en un código hexa-decimal, ya que como se menciona una cadena devuelve el valor en tipo ASCII al arreglo, para este caso, se usa el arreglo llamado str[ ] , que además es tipo char.
El proceso es el siguiente, los datos almacenados en el arreglo str[ ], son enviados uno a uno desde str[0] hasta str[a], donde a es valorada con la función strlen incluida en la librería string.h, y es devuelta como un entero el cual tiene la medida de longitud de la cadena; Aquí podemos intuir que una cadena de mas de 32 caracteres no podrá ser mostrada, pues el LCD tiene precisamente esos espacios 2x16, en todo caso si se escribiera una cadena de mayor longitud no se podrá visualizar con esta función.

Listado 4.7. función para escribir texto en el LCD.
01 void escribeCadenaEnLCD(char str[ ])
02 {
03   int a, u;      // declaramos variables usadas
04   a = strlen(str);   // mide la longitud de una cadena.
05   for (u=0; u < a; u++)   // ciclo for; u=0 hasta u < a
06     {
07       if (u==16)    // el if  para verificar el renglón del LCD
08         {
09           inst(0xc0);      // para cambiar a renglón 2
10         }
11       datos(str[u]);   // manda toda la cadena a la función datos
12     }
13 }
14 

Dentro de esta misma función esta un if que es el encargado de verificar que renglón del LCD se esta visualizando, es decir, los primeros 16 caracteres, sobrepasando este valor el LCD comenzara ha escribir en el renglón 2 y con esto se da una visualización legible.

Por ultimo se vuelve a llamar la función datos() que es la encargada de enviar la información al LCD para que sea posible visualizarla, como se menciona al principio envía uno a uno los datos en el arreglo str[u].

Función para la comunicación serial
Para establecer una comunicación serial primero se debe configurar el microcontrolador, para que se establezca los pines de comunicación y esto se logra con la función del listado 4.8 llamada configserial() en este código.

Listado 4.8 Configuración del PIC para recepción serial.
01 void configserial()  // Configuración PIC para recepción Serial
02 {
03   trisc.6= 0; // configura el pin 6 puerto C como salida
04   trisc.5= 0; // configura el pin 5 puerto C como salida
05   trisc.7= 1; // configura el pin 7 puerto C como entrada
06   spbrg = 25; // frecuencia en baudios 2400bps
07   txsta = 0x00; // valor requerido en el registro txsta
08   rcsta = 0x80; // valor requerido en el registro rcsta
09 }
10 
Lo que realiza esta función es configurar los registros TXSTA y RCSTA descritos en la hoja de datos del PIC16F73 para establecer la recepción serial.

Función para leer un dato serial
La función esta en el listado 4.9 y se llama leer1DatoSerial(), este proceso de obtener un dato serial esta descrito en la sección 3.3.4.2. En esta función se toma en cuenta los bit star y stop de cada byte recibido, es posible realizar esto porque RCIF (pir1<5>) se coloca a 1 lógico solo cuando recibe un dato completo; Puesto que ya se sabe que la etiqueta RFID se obtienen 12 bytes de su ID, entonces esta función se ejecuta 12 veces u once si no se toma en cuenta el byte stop de la etiqueta tal como se ve en el listado 4.10 con el while.

Listado 4.9 Función leer un dato del puerto Serie
01 int leer1DatoSerial()
02 {
03   int x=0;  // Declaramos una variable y la iniciamos en 0
04   while (pir1.5 == 0);  // Espera a que llegue el un Dato x el puerto serial
05   x = rcreg;       // Guarda el dato
06   while (pir1.5 == 1);  // Terminada la recepción de un dato (8bits)
07   return x;  // Regresa el valor de x
08 }
09 

El dato recibido se guarda en una variable x, la cual regresa el valor a otra función que se encarga de ir almacenado en un arreglo llamado etiqueta [u] esto byte a byte hasta los 12 bytes de la etiqueta RFID.

Función para leer los datos de una etiqueta.

La función encargada de la lectura de la etiqueta, esta en el listado 4.10, la función es llamada leerEtiquetaDeRF, esta función almacena cada byte de la etiqueta RFID en un arreglo de 10 pociones llamado etiqueta[u], los bytes son obtenidos a través de la función anteriormente descrita llamada leer1DatoSerial().

Listado 4.10 Lee datos de etiqueta RFID.

01 void leerEtiquetaDeRF(char etiqueta[])
02 {
03   int u = 0;  //Declara una variable u=0 para el control
04   clear_bit(portc,5);  //Activa el Lector
05   rcsta.4 = 1;   //Activa recepcion Continua
06   do
07     {
08       etiqueta[u]=leer1DatoSerial(); //Uno a uno byte recibido al arreglo
09       u++;
10     }  // incrementamos u para las posiciones del arreglo
11   while (u<11);    //Repite el ciclo hasta que es falsa la condición
12   set_bit(portc,5);    //Desactiva el Lector
13   rcsta.4 = 0;   //Desactiva recepción Continua
14 }
15 

En esta función, como primer instrucción se activa el lector RFID, mandando un “0” al pin 5 de puerto C, puesto que en el se encuentra conectado la terminal /enable del lector RFID.

Seguido se activa la recepción continua colocando un “1”lógico en el bit CREN, ubicado en el registro RCSTA del microcontrolador descrito en la sección 3.3.4.2. entra en un ciclo do-while que se repetirá hasta haber obtenido los 10 bytes de ID de la etiqueta RFID, dentro del ciclo se manda llamar la función leer1DatoSerial() que obtiene un byte y lo almacena en el arreglo; Terminando el ciclo do-while se desactiva el lector RFID al igual que la recepción continua del Pic.

Función para mostrar el menú de opciones
La función menú() nos permite seleccionar una entre dos opciones que son: CONTROL ACCESO ***ACTIVADO*** y MODO DE PROGRAMACIÓN.

Esta función solamente muestra en el lcd los dos letreros anteriores, y mediante un if se selecciona la opción deseada, lo que hay que resaltar es la función strcpy que pertenece a la librería string.h, dicha función strcpy, se encarga de copiar el letrero a la cadena de caracteres llamada string[ ], que es de 33 posiciones, después es mandada a la función escribeCadenaEnLCD() que se encarga de mandar la cadena al LCD y que es descrita en el listado 4.7.

Además esta función devuelve la opción seleccionada op para que mediante un switch en el programa principal (main), ejecute lo que concierne a la opción seleccionada.

Listado 4.10 Función para seleccionar opciones.
01 int menu()
02 {
03   char string[33];  // cadena de 32 posiciones, segmentos tiene el LCD
04   int op;
05   if (portc.0==1)
06     {
07       strcpy(string, " CONTROL  ACCESO ***ACTIVADO***");
08       escribeCadenaEnLCD(string);
09       delay_s(3);
10       inst(0x01);
11       op=1;
12     }
13   else
14     {
15       strcpy(string, "    MODO  DE      PROGRAMACION");
16       escribeCadenaEnLCD(string);
17       delay_s(3);
18       inst(0x01);
19       op=2;
20     }
21   return op;
22 }
23 

Ups, fue basante código, espero se haya explicado y si hay duda del código no duden en preguntar.
Clic AQUI para leer más...