CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

get_string for RFID
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ds



Joined: 01 Nov 2009
Posts: 15

View user's profile Send private message

get_string for RFID
PostPosted: Wed Nov 04, 2009 10:45 pm     Reply with quote

Hi all,
so I have successfully read an RFID tag with a PIC. Only problem is that it only reads the string from the RFID reader once. I have a loop set up that would make it read over and over again. It goes through once, and I believe the code is getting stuck at the get_string function. Any ideas on what the problem is? By the way... it can successfully check whether or not it is the right card.
Thanks in advance!


Code:


#include <16F887.h>
#device ADC=10
#fuses INTRC_IO,NOWDT,PUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP,NODEBUG
#use delay(clock=4000000)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7) 

#include <lcd16x2.c>
#include <input.c>     
#include <string.h>

#define SENTANCE_LENGTH       12



void main(){


char sentance[SENTANCE_LENGTH];
char password[SENTANCE_LENGTH];
int answer;
sprintf(password,"220056CDD5");
lcd_init();
while(1){


get_string(sentance,SENTANCE_LENGTH);
lcd_putc("\f");
printf(lcd_putc,sentance);
lcd_putc("\n");
delay_ms(1000);

answer=strcmp(sentance,password);

if(answer==0){
lcd_putc("\fCorrect Card\n");
delay_ms(1000);
lcd_putc("\f");
}

else if(answer==1){
lcd_putc("\fWrong Card\n");
delay_ms(1000);
lcd_putc("\f");
}

}

}

Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Thu Nov 05, 2009 1:12 am     Reply with quote

Are you sure the card is sending the information repeatedly?
_________________
Regards
Jerson Fernandes
ds



Joined: 01 Nov 2009
Posts: 15

View user's profile Send private message

PostPosted: Thu Nov 05, 2009 1:20 am     Reply with quote

yes I am sure. I think the get_string() command is the hang up. For some reason it only likes to go through once! I've tested various parts of the code using my lcd and a debugger. Is there some sort of reset for this function?
Thanks!
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Thu Nov 05, 2009 5:00 am     Reply with quote

I can recommend you connect the RFID reader to your PC and look on HyperTerm what you get. There may be extra characters that you are not parsing. Only when you have the full information will it be easy to see where the problem lies.
_________________
Regards
Jerson Fernandes
ds



Joined: 01 Nov 2009
Posts: 15

View user's profile Send private message

PostPosted: Thu Nov 05, 2009 10:42 am     Reply with quote

Thanks guys! Right now I don't really have the means to connect to pc. My Max232 chips are coming in, and I don't have my serial to usb. I am pretty sure that the hang up is in the get_String. So maybe you are right. Maybe there is some initial bit or stop bit that get_string is not getting. Anyways, here is the what the pdf said is sent to the pic:

Quote:

When a valid RFID transponder tag is placed within range of the activated reader, the unique ID will be transmitted as a 12-byte ASCII string via the TTL-level SOUT (Serial Output) pin in the following format:


(0x0A) Start byte (MSB)
Digit 1 Unique ID
Digit 2 Unique ID
Digit 3 Unique ID
Digit 4 Unique ID
Digit 5 Unique ID
Digit 6 Unique ID
Digit 7 Unique ID
Digit 8 Unique ID
Digit 9 Unique ID
Digit 10 Unique ID
(0x0D) Stop Bye (LSB)


The start byte and stop byte are used to easily identify that a correct string has been received from the reader (they correspond to a line feed and carriage return characters, respectively). The middle ten bytes are the actual tag's unique ID.

All communication is 8 data bits, no parity, 1 stop bit, non-inverted, least significant bit first (8N1). The baud rate is configured for 2400bps, a standard communications speed supported by most any microprocessor or PC, and cannot be changed. The Parallax RFID Reader Module initiates all communication. The Parallax RFID Reader Module can connect directly to any TTL-compatible UART or to an RS232-compatible interface by using an external level shifter.


Does my code match the requirements? I'm fairly new at using RS232.
Thanks for all the help guys!
andyfraser



Joined: 04 May 2004
Posts: 47
Location: UK

View user's profile Send private message

PostPosted: Thu Nov 05, 2009 10:47 am     Reply with quote

You should always add ERRORS to your #use RS232 line to ensure that any errors do not lock up the RS232 receive.

Andy
www.sharpcontrols.net :: Free custom controls for .NET
ds



Joined: 01 Nov 2009
Posts: 15

View user's profile Send private message

PostPosted: Thu Nov 05, 2009 5:17 pm     Reply with quote

I've added ERRORS to the RS232 and it seems to have solved the problem of the lockup! Thanks!

Now the problem is: the card ID is: 220056CDD6 ... which is 10 digits. Perfect.

However on the display... it says the correct 10 digit code the first time! (success), however on the second time around it displays an extra '2' on the front of the string. Subsequent "reads" have the correct ID, with an extra '2' on the front also. I was thinking that I need to clear the string in the loop. I did so, and still the problem arises. I even tried reducing the string size to 10 and it didn't work. After 10 reads or so, I'll get a read of just "2" on the display and then a read of "2&&" on the display. Then is will continue with the correct ID with the 2 added at the front.
Any ideas? here is my updated code:
Code:

#include <16F887.h>
#device ADC=10
#fuses INTRC_IO,NOWDT,PUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP,NODEBUG
#use delay(clock=4000000)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7, ERRORS) 

#include <lcd16x2.c>
#include <input.c>     
#include <string.h>


#define SENTANCE_LENGTH 32

int answer;
int i;
char sentance[SENTANCE_LENGTH];
char password[SENTANCE_LENGTH];

void main(){

sprintf(password,"220056CDD6");
lcd_init();
while(1){
sentance[0]='\0';
get_string(sentance,SENTANCE_LENGTH);

printf(lcd_putc,sentance);
delay_ms(800);
lcd_putc("\f");
}


}



ps I realise that sentence is spelled wrong... it was like this in some sample code so I stuck with it. haha.
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Thu Nov 05, 2009 7:20 pm     Reply with quote

If you look at the datasheet section you posted, there is an additional byte (0x0A) before the actual string. You need to discard that before comparing. The first time around, the PIC might be missing the first byte and so, all works as expected.
_________________
Regards
Jerson Fernandes
ds



Joined: 01 Nov 2009
Posts: 15

View user's profile Send private message

PostPosted: Thu Nov 05, 2009 8:15 pm     Reply with quote

This extra "2" is really starting to bother me! Jerson, how do you suggest I get rid of the 0X0A? How big should my string length char array be if the string is only meant to be 10 useful characters? Do I really have to include the 0x0D aswell? I think it's only meant to tell the RS232 that it's done sending. The 0x0A is actually a \n (linefeed), and 0x0d is \r or carriage return. Any ideas? Thanks all for helping me get to this point!
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 05, 2009 8:19 pm     Reply with quote

Part of the answer is in that adding the ERRORS parameter caused the code to start working.
The PIC processor has a receive buffer for up to three characters. On receiving more data the UART will stall until the error condition is reset. The ERRORS parameter will add code for automatically clearing the error on every call to getc (and possibly kbhit too, I haven't checked) but the receiver hardware still holds 2 (or 3?) bytes of the old received data.

get_string will read data until a 0x0A character is received. Too bad this is the character your data starts with instead of ending with...
With your delay of 800ms the hardware receive buffer will overflow. The call to getc will clear the error, but the 2 old data characters waiting in the receive buffer most likely will not match the new arriving data.

Best solution is to roll your own get_rfid_string() function:
Code:
#define RFID_START_BYTE 0x0A
#define RFID_END_BYTE   0x0D


// Description: Receive an RFID string.
//              Expected receive data:
//                  (0x0A) Start byte (MSB)
//                  Digit 1 Unique ID
//                  Digit 2 Unique ID
//                  ...
//                  Digit 10 Unique ID
//                  (0x0D) Stop Byte (LSB)
// Input:       max - Maximum RFID string length, including terminating 0.
// Output:      s   - Buffer to hold the received RFID string. Will be zero terminated.
void get_rfid_string(char* s, int8 max)
{
  int8 len;
  char c;
 
  // Wait for start byte
  do
  {
    c = getc();
  } while (c != RFID_START_BYTE);
 
  // Receive data until END byte is received or buffer full
  max--;          // correct for terminating zero
  len=0;
  while ((c != RFID_END_BYTE) && (len < max))
  {
    s[len++] = c;
    c = getc();
  };
  s[len] = 0;
}
ds



Joined: 01 Nov 2009
Posts: 15

View user's profile Send private message

PostPosted: Thu Nov 05, 2009 10:30 pm     Reply with quote

Thanks so much for the help ckielstra! I tried the code and it works! However, the \n (0x0A) carried in by the first bit is causing the display output to be on a new line! I have been trying to throw that first bit away but haven't quite gotten it right. Do you know of a good way to do this? Also, what is the s[len]=0 for at the end? Does that terminate any characters after the last inputed character in the string? Also just out of curiosity, what does the max-- do? I saw it in the get_string function in input.c aswell.
Thanks again all of you for your help and suppport!
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Thu Nov 05, 2009 11:49 pm     Reply with quote

If you doubt the first character is causing trouble, you can simply start printing from the second character like this

printf(lcd_putc,&sentance+1);

s[len] = 0 is simply ending the string with a NUL character - also called an ASCIIZ ascii zero string.

max is the maximum number of characters that can be collected into the string s
_________________
Regards
Jerson Fernandes
ds



Joined: 01 Nov 2009
Posts: 15

View user's profile Send private message

PostPosted: Fri Nov 06, 2009 12:20 am     Reply with quote

I tried that and it actually just prints the code on the top line first, then the second time around and subsequent times it keeps displaying on the bottom. I'm thinking there is a \n being read in. But I'm not completely sure. Also, using strcmp with what the value should be doesn't work. I think there is an extra data being read in or saved maybe. If I use the &sentance+1 in the code, the first time it can successfully compare and tell me it is the correct card. However, subsequent reads appear on the bottom of the lcd and no comparison is even made. I'm thinking there is something fishy with the first character. What would be a good way to kick it out! ? If you think that it would help.






Thanks Jerson
Code:

#define SENTANCE_LENGTH 15

int answer;
int i;
char sentance[SENTANCE_LENGTH];
char password[SENTANCE_LENGTH];
void main(){
sprintf(password,"220056CDD6");
lcd_init();
while(1){
get_rfid_string(sentance,SENTANCE_LENGTH);
printf(lcd_putc,&sentance+1);
delay_ms(800);
lcd_putc("\f");

answer=strcmp(&sentance+1,password);

if(answer==0){
lcd_putc("\fCorrect Card\n");
delay_ms(1000);
lcd_putc("\f");
}

else if(answer==1){
lcd_putc("\fWrong Card\n");
delay_ms(1000);
lcd_putc("\f");
}

}


}
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Fri Nov 06, 2009 12:36 am     Reply with quote

A good way to know what is within the string (an educated guess) would be to print the strlen(s). That will tell you how many characters are inside the string. Then you have to correlate with the expected data.
_________________
Regards
Jerson Fernandes
ds



Joined: 01 Nov 2009
Posts: 15

View user's profile Send private message

PostPosted: Fri Nov 06, 2009 1:28 pm     Reply with quote

Thanks for the tip Jerson! I got the lcd to display each set of data stored in the array for string. The first bit is in fact a 10 (which corresponds to a \n]). The last bit is a 0. This is because of the s[len]=0; at the end of the get_rfid_string function. However, for some reason, if I look at data past the zero, (where the data should technically end), I get a whole bunch of random values for string[11] and beyond.

Should I be worried about this?

Also, I tried to do a function that erased
the first bit, but didn't have success. How do you suggest I do it?
I was thinking something along the lines of

Code:

for(i=0;i<12;i++){
if(sentance[i]==10){
sentance[i]="";
}
}


However, do you think it would be more appropriate to do a loop that essentially looks for "10", starts storing data, and stops when it finds a "0"?
Thanks for all the help and the tips Jerson!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group