Go Down

Topic: rfid compare tag code (Read 9671 times) previous topic - next topic


Sep 11, 2007, 12:54 am Last Edit: Sep 11, 2007, 01:18 am by Loic Reason: 1
Big big progress: After I filled the array with more than 60 tags I started to get problems with the 1k byte ram limit of the mega168. Random crashes and the like  :'( I figured that I needed to use PROGMEM to overcome this hurdle. A few hours later in pain I found out that the equivalent of the "memcmp" function when using PROGMEM was "memcmp_P". But here comes the nice part: This function was only added to avr_libc version 1.4.6 and Arduino uses version 1.4.4, couldn't be more convenient  ::) I compiled the latest avr_libc and replaced parts of the Arduino lib. Guess what, it worked!!! Going rock solid with 75 tags in memory! This is my latest code, cleaned up and filled with comments. With this code you can just copy-paste tags from the serial monitor into the array:

Code: [Select]
#include <avr/pgmspace.h>
#include <SoftwareSerial.h>

#define rxPin 7 // unused serial pin
#define txPin 2 // software-serial pin used to send the "read uid" command to the reader

#define TAG_LEN 12 // length of a single tag in bytes

SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin); // set up a new serial port

int ledPin = 13; //feedback led
int ledPin2 = 6; //feedback led
int checkrfid = 0; // after a scan for tags, this will become:  0 if no tag was read, 1 if tag is recognized, 2 if tag is not recognized,
byte code[TAG_LEN]; // var that will hold the bytes-in read from the serialBuffer
int bytes_read = 0; // number of bytes read
PROGMEM prog_char target_tag[][TAG_LEN] = //dynamic multidimensional array with known tags. It's stored into flash memory to overcome the 70 tag limit.
{{0x00, 0x00, 0xdd, 0x8e, 0x96, 0x0e, 0x00, 0x01, 0x04, 0xe0, 0x10, 0xc8 },
{0x00,  0x00, 0x1b, 0x4e, 0xc1, 0x0d, 0x00, 0x01, 0x04, 0xe0, 0xd5, 0x7b}};

void setup()  {
 // define pin modes for tx, rx, led pins:
 pinMode(rxPin, INPUT); // setup for software-serial
 pinMode(txPin, OUTPUT); // setup for software-serial
 pinMode(ledPin, OUTPUT); // setup for feedback led
 pinMode(ledPin2, OUTPUT); // setup for feedback led
 mySerial.begin(19200); // set the data rate for the SoftwareSerial port
 Serial.begin(19200);      // opens serial port, sets data rate to 19200 bps

void loop ()
scan(); // do a scan for tags
if(checkrfid == 1) // if tag is recognized
 fade(); //do function "fade" (see below)
if(checkrfid == 2) // if tag is not recognized
 blink(); //do function "blink" (see below)
delay(100); //wait before doing a new scan

void scan () {
 checkrfid = 0; //set "state of recogniton" back to zero
 mySerial.print(0xfa, BYTE); //request Tag code
 if(serialAvailable()){ //if data is coming back from the reader
    while (serialAvailable() && bytes_read < TAG_LEN){ //while data is coming back from the reader and not all 12 bytes are read      
    code[bytes_read] = Serial.read(); //add byte
    bytes_read++;  // update number of bytes read
 Serial.println ("NO TAG "); //No data has come from the reader so "No Tag" is displayed

 if( bytes_read >= TAG_LEN) //if 12 bytes were read, print them out
     Serial.print("{"); //adds syntax so you can just copy-paste the tag into your code
     for(int i=0; i<bytes_read; i++) //prints all 12 bytes one at a time
         Serial.print("0x"); //more syntax for copy-paste
           Serial.print(code[i], HEX);    //print out the byte in HEX
           Serial.print(", "); //more syntax for copy-paste
     Serial.print("},"); //more syntax for copy-paste
      for(int i = 0; i < ((sizeof(target_tag))/12); i++) //tag is compared to array of known tags, note that the size of the array is dynamic and calculated every time, more ease for copy-paste...
       if(memcmp_P(code, target_tag[i], TAG_LEN) == 0 ) //uses the PROGMEM variant of memcmp -> memcmp_P This function doesn't work with the standard Arduino 009 IDE, Needs avr-libc 1.4.6.
           checkrfid = 1; //if tag matches, set "checkrfid" to 1
     if(checkrfid == 0) //if tag doesn't match, set "checkrfid" to 2
       checkrfid = 2;
     Serial.flush(); //flush serial buffer

   Serial.println(); //print linefeed
   bytes_read = 0; //set number of bytes read back to zero
void blink ()
 digitalWrite(ledPin, HIGH); // if true blink led
 digitalWrite(ledPin, LOW);

void fade ()
int value = 0;
 for(value = 0 ; value <= 255; value+=5) // fade in (from min to max)
   analogWrite(ledPin2, value);           // sets the value (range from 0 to 255)
   delay(30);                            // waits for 30 milli seconds to see the dimming effect
 for(value = 255; value >=0; value-=5)   // fade out (from max to min)
   analogWrite(ledPin2, value);


Arduino is so great, never thought this would be possible!

Kind Regards, Loïc


Nice one Loic, add it to the playground it would be a great benefit to others searching for RFID options. I think there's a variety of storage options, but I haven't got that far yet  ;D

I read something a while back about USB memory sticks or flash memory or something  :)


I am trying to light up LEDs according to the specific Tags read by my Parallax RFID reader. I found your example but i cant get it to work. i dont know how to translate the Tag numbers I am getting i.e. 0415EBD8CC to a char string as this one that you are using:

char target_tag[ARR_LEN][TAG_LEN] =
{{0x00, 0x00, 0xdd, 0x8e, 0x96, 0x0e, 0x00, 0x01, 0x04, 0xe0, 0x10, 0xc8 },
{0x00,  0x00, 0x1b, 0x4e, 0xc1, 0x0d, 0x00, 0x01, 0x04, 0xe0, 0xd5, 0x7b}};

Also the library <avr/pgmspace.h> exists on the web as a text file. Should I copy it somewhere where the Arduino can track it? I have found this link for that library: http://ccrma.stanford.edu/courses/250a/docs/avrgcc/pgmspace_8h-source.html
Is it correct?
My code so far that prints out the Tag ID and lights one LED is the basic found in the arduino playground.

#include <SoftwareSerial.h>

int  val = 0;
char code[10];
int bytesread = 0;

#define ledPin 12   //need to define it here to read it through the software serial
#define rxPin 7   //connect with SOUT / TX in RFID at 2400bps
#define txPin 9

byte pinState=0;

void setup()
 Serial.begin(9600);  // Hardware serial for Monitor 9600bps

 pinMode(ledPin, OUTPUT);  //added my pin 12 as an output here

 pinMode(2,OUTPUT);       // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
 digitalWrite(2, LOW);    // Activate the RFID reader

void loop()
 SoftwareSerial RFID = SoftwareSerial(rxPin,txPin);

 if((val = RFID.read()) == 10)
 {   // check for header
   bytesread = 0;
   {  // read 10 digit code
     val = RFID.read();
     if((val == 10)||(val == 13))
     {  // if header or stop bytes before the 10 digit reading
       break;                       // stop reading
     code[bytesread] = val;         // add the digit          
     bytesread++;                   // ready to read next digit

   if(bytesread == 10)
   {      // if 10 digit read is complete
     Serial.print("TAG code is: ");   // possibly a good TAG
     Serial.println(code);            // print the TAG code
     digitalWrite(ledPin, HIGH);    //added this to flicker the LED
     digitalWrite(ledPin, LOW);
   bytesread = 0;
   delay(1500);                       // wait for a second


I hoped that by adding the char string ={{0x00, 0x00, 0xdd, 0x8e, 0x96, 0x0e, 0x00, 0x01, 0x04, 0xe0, 0x10, 0xc8 } nd call it in my loop it would be easy to get my tags, but it looks really complex. any sipmle way to go about this?

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131