Autor Tema: Lector RFID pic 18f4550 en ccs  (Leído 8706 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado cristianego

  • PIC10
  • *
  • Mensajes: 6
Lector RFID pic 18f4550 en ccs
« en: 25 de Junio de 2011, 01:56:24 »
Hola gente. Estoy empezando con esto de los pic y quisiera un poco de ayuda.

Paso a comentar lo que quiero implementar.

Tengo un modulo RFID GP8F-R2 y simplemente pretendo leer los datos de su ID que emite, que corresponden a una tarjeta tag de rfid.

El problema que tengo, es que al leer la primera tarjeta, funciona bien, cuando quiero leer de nuevo, me produce error.
Estoy seguro que el problema es el pic y no el rfid, ya que si desconecto la alimentacion del pic, y pruebo leer la tarjeta lo hace en forma correcta, pero intento por segunda vez y ya no se puede.

Intente de varias formas, con interrupcion y sin interrupcion del puerto y ambas me dan el mismo error, solo lee correctamente una vez la tarjeta tag.

Estaba pensando que quizas sea un problema de algun buffer del pic que no lo borre, pero no estoy seguro, quizas alguna configuracion que se me esta escapando.

Aqui esta el codigo:

Citar
#include <18F4550.h>
#device adc=8

//Estos fuses los obtuve con el widzar

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL12                    //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV4                  //System Clock by 4
#FUSES USBDIV                   //USB clock source comes from PLL divide by 2
#FUSES VREGEN                   //USB voltage regulator enabled
#FUSES ICPRT                    //ICPRT enabled

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <string.h>
///////////////////////////////////////
// Constantes
///////////////////////////////////////
 
int const lenbuff=20; // Longitud máxima del buffer
 
///////////////////////////////////////
// RAM
///////////////////////////////////////
 
int  xbuff=0x00;     // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer de recepción
int1 flagcommand=0;  // Flag para comando disponible
 
///////////////////////////////////////
// Funciones de Buffer
///////////////////////////////////////
 
 
// Inicia a \0 cbuff -------------------
void init_cbuff(void){
   int i;
 
   for(i=0;i<lenbuff;i++){// Bucle que pone a 0 todos los
      cbuff=0x00;      // caracteres en el buffer
   }
   xbuff=0x00;            // Inicializo el indice de siguiente caracter
}
 
// Añade a cbuff -----------------------
 
void add_2_cbuff(char c){                               //En esta parte distingue si se ingresa un enter, un back space y un space, los dos ultimos no los utilizo ya que solo importa el enter.
 
      switch(c){
         case 0x0D:  // Enter -> Habilita Flag para procesar comando
            flagcommand=1;
            break;
         case 0x08:  // Del   -> Borra último caracter del Buffer
            if(xbuff>0) cbuff[--xbuff]=0x00;
            break;
         case 0x01B: // Esc   -> Borra el Buffer completamente
            init_cbuff();
            break;
         default:    // Añade caracter recibido al Buffer
            cbuff[xbuff++]=c;
      }
}
 
///////////////////////////////////////
// Procesador de Comandos
///////////////////////////////////////
 

 
void commad_process(void){
 
   
   char cmd[lenbuff];        // Comando
 
   flagcommand=0;            // Desactivo flag de comando pendiente.
 
 
   strcpy(cmd,cbuff);        // Lo copio para procesarlo
   
 
   init_cbuff();             // Borro buffer.
   if(cmd[0]==0x02){
   output_high (pin_b0);
   delay_ms(1000);
   output_low(pin_b0);
 
   }
}
///////////////////////////////////////
// INTERRUPCIONES : RDA Recepción USART
///////////////////////////////////////

#int_RDA
void  RDA_isr(void)
{
 char rcvchar=0x00;        // último caracter recibido
 
   if(kbhit()){              // Si hay algo pendiente de recibir ...
      rcvchar=getc();        // lo descargo y ...
      add_2_cbuff(rcvchar);  // lo añado al buffer y ...
     
   }
}


void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_4MHZ|OSC_INTRC|OSC_PLL_OFF);

   // TODO: USER CODE!!
   
   output_high (pin_b0); // enciendo y apago un led de prueba, solo para corroborar que funciona bien
   delay_ms(1000);
   output_low(pin_b0);
 
do {
      if(flagcommand) commad_process(); // Hay algo pendiente de procesar y lo procesa.
   } while (TRUE);
 
}


Este codigo lo modifique de uno que publico RedPic sobre como trabajar con el puerto RS232

El modulo RFID proporciona una cadena con

<STX> <DATA (10 bytes)> <CR> <LF> <ETX>

y trabaja a 9600 con 8 bits serie asincronico, sin paridad, a nivel logico

El RFID funciona correcto, puesto que lo he probado con un max 232 y se comunica de forma perfecta con la PC. De ahi puede anotar los numeros ID de cada tarjeta.

El Codigo de arriba solo pretende leer el STX (tengo tres tag) solo para corroborar que funciona bien, me pareció la prueba mas trivial.

Obviamente este es un paso previo al programa completo, pero lo unico que pretendo es leer ese bit STX, que me indica que se leyo una targeta correctamente y mostrar un led encendido en pin b0 confirmando la lectura.

El problema es que la segunda vez que paso una tarjeta en el modulo rfid, y este envia la cadena de caracteres, nunca mas se prende el led, es decir nunca mas el cmd[0], que es la cadena donde recibo el dato, obtiene el valor 0x02.

Repito, si desconecto la alimentacion del pic, funciona bien correctamente, eh probado con otro programa leer el dato completo y compararlos con los valores del ID de la targeta y si funciona, pero solo la primera vez!



Espero que puedan ayudarme, desde ya muchas gracias




Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #1 en: 25 de Junio de 2011, 10:32:02 »
Hola.

En la parte del programa principal, se te esta olvidando poner a ceros la bandera flagcommand. Por eso solo te funciona una vez, cuando esta en ceros, de ahí siempre queda en uno

Saludos
El papel lo aguanta todo

Desconectado cristianego

  • PIC10
  • *
  • Mensajes: 6
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #2 en: 25 de Junio de 2011, 12:12:32 »
Gracias MLO por responder tan rapido.

La bandera la tengo que poner a 0 en el programa principal? por que esta puesta en la funcion command_process(), la segunda instruccion


Citar
void commad_process(void){
 
   
   char cmd[lenbuff];        // Comando
 
   flagcommand=0;            // Desactivo flag de comando pendiente.
 
 
   strcpy(cmd,cbuff);        // Lo copio para procesarlo
   
 
   init_cbuff();             // Borro buffer.
   if(cmd[0]==0x02){
   output_high (pin_b0);
   delay_ms(1000);
   output_low(pin_b0);
 
   }
}

ahora pruebo y veo que tal

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #3 en: 25 de Junio de 2011, 12:34:51 »
Hola.

No habia visto la bandera en la funcion. Pon la funcion entre llaves { } a ver que sucede.

Saludos
El papel lo aguanta todo

Desconectado cristianego

  • PIC10
  • *
  • Mensajes: 6
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #4 en: 25 de Junio de 2011, 12:41:35 »
Muchas gracias men, ahora me detecta todos los inicios de texto de las tarjetas (0x02)

el programa quedo asi, siguiendo tu consejo puse la bandera en el programa principal

 
Citar
while(true) {
do {
    //  if(flagcommand)
     
   } while (flagcommand!=0);
    commad_process(); // Hay algo pendiente de procesar y lo procesa.
      flagcommand=0;            // Desactivo flag de comando pendiente.
     
 }


y funciona de maravillas. Gracias de nuevo

Aveces uno pierde un poco el hilo y necesita gente que vea los errores que estas cometiendo  y muchas veces estan en frente a tus narices (no en este caso por que ni sabia que habia diferencia en donde hago cero la bandera) y mejor cuando se trata de genete experta como uds.

Infinitamente agradecido xDDD

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #5 en: 25 de Junio de 2011, 12:45:33 »
Hola.

De nada hombre. Si puedes, sube algunas fotillos o algun esquema hardware para que quede mas chulo el post =P

saludos
El papel lo aguanta todo

Desconectado cristianego

  • PIC10
  • *
  • Mensajes: 6
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #6 en: 25 de Junio de 2011, 18:22:01 »
Yo de nuevo, si bien avanzo, no funciona del todo correctamente.

Ahora puedo leer varias veces el mismo tag y funciona a la perfeccion, el problema es cuando leo otro tag y vuelvo al anterior, deja de reconocerlo

Primero que nada, encontre que tenia mal el main, en el do while esta mal la pregunta
Citar
while(true) {
do {
    
    
   } while (flagcommand==0);  //<-------------------- aqui era igual a 0, no como esta arriba
    commad_process(); // Hay algo pendiente de procesar y lo procesa.
      flagcommand=0;            // Desactivo flag de comando pendiente.
    
 }

Como el rfid, funciona bien con el hyperterminal, conozco los IDs
uno termina en '3', el otro en '8' y el 3ero en 'E'

y la comparacion la hago en la siguiente funcion
Citar
void commad_process(void){
    
   char cmd[lenbuff];        // Comando
 
   strcpy(cmd,cbuff);        // Lo copio para procesarlo
  
   init_cbuff();             // Borro buffer.
  
   if(cmd[10]=='8'){            //pregunto si el ultimo byte del ID es igual a 8, es decir a una de los 3 tag
   output_high (pin_b0);
   delay_ms(1000);
   output_low(pin_b0);
   }
  
}


voy a seguir revisando el codigo, algo respecto a algun buffer tiene que ser, por que desconecto la alimentacon del pic y funciona correctamente, hasta que en el lector
acerco otro tag y deja de funcionar.


« Última modificación: 25 de Junio de 2011, 18:24:58 por cristianego »

Desconectado cristianego

  • PIC10
  • *
  • Mensajes: 6
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #7 en: 25 de Junio de 2011, 22:21:25 »
Bueno, cuento mi avance.

En mi afan de no encontrar una solucion, se me ocurrio (no se por que no lo hice antes), conectar el modulo RFID al pic y en la pata TX, el cable con el max 232 al PC.

Entonces agregue un par de prinft y esto es lo que se ve en el hyperterminar.

Por lo que puedo concluir que el problema que tengo, es cuando comparo el ID, ya que como se ve en la imagen, los datos los lee correctamente.

Lo unico que hice fue agregar un
printf("Enciendiendo..");
en el main y en

Citar
void commad_process(void){
 
   
   char cmd[lenbuff];        // Comando
 
 strcpy(cmd,cbuff);        // Lo copio para procesarlo
 
   init_cbuff();             // Borro buffer.
   printf(cmd);                    //<--------------------------------------------Este printf agregue
   
   if(cmd[10]=='8'){              //<------------- asi es como comparo el ultimo byte, antes del enter del ID de la tarjeta
   output_high (pin_b0);
   delay_ms(1000);
   output_low(pin_b0);
   }
 
}


Todavia no lo hice comparando cadenas, pero si tengo problemas en compara un byte... Mucha esperanza en comparar cadenas no creo que tenga


Lo que me llama la atencion, es que en la imagen se puede ver que el pic le entrega al hyperterminal el ID  fin de texto+ Inicio de texto + retorno de carro

pero es debido a que el retorno de carro hace que el fin de texto aparezca antes.

Pero, se supone que el modulo entrega  inicio de texto + Dato + retorno de carro+fin de texto

y a la hora de leer los datos se cargan hasta retorno de carro, se supone que fin de texto no lo lee, no entiendo por que aparece el fin de texto


De todas formas, esto da un mejor panorama de que esta haciendo el pic, los datos se leen, es decir el codigo para obtener el dato esta funcionando, el problema esta en comparar el byte, superado esto puedo comparar la cadena.



Desconectado cristianego

  • PIC10
  • *
  • Mensajes: 6
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #8 en: 26 de Junio de 2011, 01:14:34 »
Yo again xD. Esto ya me parece a un informe de avances jajajaj

Buenas noticias!!!!! Anda el codigo!!!!1 al fin. Probado y comprobado

Definitivamente el problema siempre fue los datos que quedaban en el buffer. Es decir el modulo rfid entrega  <incio de texto>+<dato>+<enter>+<fin de texto>, el codigo leia hasta enter (0x0D), pero no lo incluia al enter, es decir este junto con el fin de texto quedaban en el buffer, de modo que cuando acercaba otra tarjeta, estos dos datos pasaban a ocupar los dos primeros lugares del nuevo dato recibido.

La solucion que hice no es la mejor, pero es una.
 Lo ideal seria tomar los datos hasta encontrar el enter (0x0D), guardarlos en una cadena y borrar el buffer del pic.

Lo que hice fue leer los datos hasta detectar el fin de texto (0x0A) y luego hacer un getc() nuevamente para descargar el buffer en una variable auxiliar. Como dije, no es la mas efectiva, pero es una solucion al fin. De manera que vamos a obtener los datos completos en nuestra cadena <0x02>+<Dato>+<0x0D>+<0x0A>, solo queda copiar la cadena en otra, ignorando el primer y el ultimo byte, para luego hacer lo que quieramos con ella, enviarla a la pc, guardarla en la EEPROM del pic, en fin, utilizarla.

Aqui esta a modificacion que realize, solamente en la funcion donde cargo los datos a la cadena buffer de recepcion.

Citar

void add_2_cbuff(char c){
 
      switch(c){
         case 0x0A:  // Enter -> Habilita Flag para procesar comando
            {
            cbuff[xbuff++]=c;    //<---------------------------------------- a diferencia de antes guardo al cbuff el ultimo byte recibido
            flagcommand=1;     //<--------------------------------------- luego activo la bandera
            aux=getc();            //<---------------------------------------tomo lo que queda en el buffer para que no sea el primer byte de la proxima cadena, obviamente hay que declarar char aux antes de usarla
            }                          
            break;
         case 0x08:  // Del   -> Borra último caracter del Buffer
            if(xbuff>0) cbuff[--xbuff]=0x00;
            break;
         case 0x01B: // Esc   -> Borra el Buffer completamente
            init_cbuff();
            break;
         default:    // Añade caracter recibido al Buffer
            cbuff[xbuff++]=c;
      }
}


Bueno, por hoy suficiente. Mañana agrego todo el codigo completo y terminado, hay cosas que las deje como estaban (recuerden que esto era una modificacion de una publicacion de RedPic), pero la seccion de codigo anterior, esta pensada para recibir datos por telcado y en caso de encontrar un backspace borra un lugar en el buffer, en caso de encontrar un space, borrra toda la cadena. Estas cosas para leer datos de el modulo rfid no son necesarias.

Voy a agregar el conexionado tambien

La verdad ahora que lo veo, no parece la gran cosa, pero a mi me hice renegar y quizas esa informacion le sirva para alguien en el futuro.




« Última modificación: 26 de Junio de 2011, 01:21:34 por cristianego »

Desconectado shirly.morales

  • PIC10
  • *
  • Mensajes: 1
Re: Lector RFID pic 18f4550 en ccs
« Respuesta #9 en: 01 de Septiembre de 2011, 17:15:07 »
buenas tardes

necesito de su ayuda pues estoy desarrollando mi tesis en este tema de rfid y necesito un esquema del montaje de un lector que creo tu lo tienes espero me puedas colaborar publicando las dispositivos y un diagrama para tal construccion te lo agradeceremos toda la vida te cuidas