Pages: 1 [2]   Go Down
Author Topic: rfid compare tag code  (Read 4410 times)
0 Members and 1 Guest are viewing this topic.
Ghent, Belgium
Offline Offline
Newbie
*
Karma: 1
Posts: 38
lovin it!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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  :smiley 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:
#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)
  delay(100);
}
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
  delay(1000);
  digitalWrite(ledPin, LOW);
  delay(500);
}

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
  }
  delay(200);
  for(value = 255; value >=0; value-=5)   // fade out (from max to min)
  {
    analogWrite(ledPin2, value);
    delay(30);
  }
 delay(500);

 }


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

Kind Regards, Loïc
« Last Edit: September 10, 2007, 06:18:51 pm by Loic » Logged

0
Offline Offline
God Member
*****
Karma: 0
Posts: 731
skcor oniudrA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley
Logged

london
Offline Offline
Newbie
*
Karma: 0
Posts: 2
arduino is hard
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
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);
  RFID.begin(2400);

  if((val = RFID.read()) == 10)
  {   // check for header
    bytesread = 0;
    
    while(bytesread<10)
    {  // 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
      Serial.println("");
      
    
      digitalWrite(ledPin, HIGH);    //added this to flicker the LED
      delay(30);
      digitalWrite(ledPin, LOW);
      delay(30);
  
    }
    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?
thanx
Logged

Pages: 1 [2]   Go Up
Jump to: