0

I'm working on RFID project to handle multiple cards.

I did most of the things OK. But now I have one problem. Which is the following:

  1. The RFID code is 5 bytes, so I need an array of 5 bytes. If more cards then the array size = number of card * 5.
  2. For my example I'm working with 2 cards. So array size is 10 bytes.
  3. I can store the first card in the first 5 bytes.

The problem: I can't store the 2nd card in the next 5 bytes in the array. I don't know why.

This is my only test code:

/****************************** LIBRARIES ******************************/
#include <SPI.h>
#include <RFID.h>

/****************************** DEFINITIONS ******************************/
// pins definitions
#define SS_PIN          10
#define RST_PIN         9

// setup definitions
#define CARDS           2
#define MXCD            CARDS*5

/****************************** VARIABLES ******************************/
// rfid variables:
byte crd_buf[MXCD],card_no;
byte register_lock,check_lock,print_lock;

/****************************** FUNCTIONES ******************************/
// rfid functions
void register_accepted_card(void);
void record_new_cards(void);
void check_card(void);
void print_registered_cards(void);


// objects
RFID rfid(SS_PIN, RST_PIN); 

//////////////////////////////////////////////////////////////////////
void setup(){ 
  Serial.begin(9600);
  SPI.begin(); 
  rfid.init();
}

void loop(){
    register_accepted_card(); // apply only once
}


void register_accepted_card(void){
  if (!register_lock) {
    if (rfid.isCard()) {
      if(rfid.readCardSerial()){
        if(card_no>0){
          for(byte i = 0; i<card_no; i++){
            if(!memcmp((crd_buf+(i*5)),rfid.serNum,5)){

              Serial.println("already card is");
              for(byte p = i*5; p<(i*5)+5; p++){
                Serial.print(crd_buf[p],HEX);Serial.print(", ");}
                Serial.println();

              lcd_state = ALREADY_MSG;
              register_lock = 1;
            }
          }
        }

        //////////////////////////
        // problem is in this part
        //////////////////////////

        if(!register_lock){

          for(byte i=card_no*5;i<(card_no*5)+5;i++){
            crd_buf[i] = rfid.serNum[i];}

          Serial.print("loop#"); Serial.println(card_no);
          Serial.print("start index ");Serial.println(card_no*5);
          Serial.print("end index ");Serial.println((card_no*5)+5);
          Serial.println();


          Serial.print("card#"); Serial.println(card_no+1);
          for(byte i=card_no*5;i<(card_no*5)+5;i++){
            Serial.print(crd_buf[i],HEX);Serial.print(", ");}
          Serial.println();Serial.println("//////////////////////////");

          card_no++;
          if(card_no >= CARDS){lcd_state = FINISH_MSG;}
          else{lcd_state = REGISTER_MSG;}
          register_lock = 1;          
        }
      }
    }
    rfid.halt();
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

My second question, for the part of checking the cards after finishing registering the cards to be accepted.

I did a for loop for the number of cards to get the card that is registered in the array and send a message that the card is stored and accepted, otherwise, it returns a denied message that the card isn't stored in the array with alarm buzzer.

The problem that is the for loop checks the card for all the indexes in the array which is what I want but the result is mixed with accepted and denied.

The question is how to get out of the for loop?

void check_card(void){
  if (check_lock){
    if (rfid.isCard()){
      if (rfid.readCardSerial()){
        for(byte i=0;i<card_no;i++){

          // start of for loop
          Serial.print("check# ");Serial.println(i);
          if(!memcmp(crd_buf+(i*5),rfid.serNum,5)){
            Serial.println("card accepted");
            digitalWrite(ACCEPT_LED,HIGH);
            digitalWrite(DENIED_LED,LOW);
            digitalWrite(BUZZER,LOW);
            check_lock = 0;
            sys_state = 1;
            lcd_state = ACCEPTED_MSG;
          }
          else{
            Serial.println("card denied");
            digitalWrite(ACCEPT_LED,LOW);
            digitalWrite(DENIED_LED,HIGH);
            digitalWrite(BUZZER,HIGH);
            check_lock = 0;
            sys_state = 1;
            lcd_state = DENIED_MSG;
          }          
        }   
            // end of for loop

      }
      rfid.halt();
    }
  }
}
  • 2
    Why not a 2D array of crd_buf[CARDS][5];? So much simpler to deal with. – Majenko Apr 6 '19 at 12:24
  • OK, I should try your method. But I'm really confused of why it's not working as I tested it in codeblocks and it is working fine ! Is there something I don't know about Arduino compiler ? Is it possible that the compiler is not defined to handle these operations on arrays ? to me, I just don't think so, Arduino compiler is really professional. Maybe I'm doing something wrong .. But I should try the 2D version, thanks dude :) – R1S8K Apr 6 '19 at 13:13
1

Your problem is this bit:

      for(byte i=card_no*5;i<(card_no*5)+5;i++){
        crd_buf[i] = rfid.serNum[i];}

For the first card you're copying bytes 0-4 of the serNum to bytes 0-4 of crd_buf.

However for the second card you're copying bytes 5-9 of serNum to bytes 5-9 of crd_buf. That's correct for crd_buf but wrong for serNum.

The right way would be to add card_no*5 to i when creating the index:

      for(byte i=0; i<5; i++){
        crd_buf[(card_no*5) + i] = rfid.serNum[i];}

Or better to define your card buffer as a 2D array so you don't need to do that calculation:

byte crd_buf[CARDS][5];

for (i = 0; i < 5; i++) {
    crd_buf[card_no][i] = rfid.serNum[i];
}

Or simpler:

memcpy(crd_buf[card_no], rfid.serNum, 5);

For your second question, don't print your message at all in the loop.

Instead start out assuming that access is denied. Then if a card matches, grant access. The simplest way is with a flag.

if (rfid.readCardSerial()){

    bool accessGranted = false;  // A flag to store the state - start off denied.

    for(byte i=0;i<card_no;i++){
        if(!memcmp(crd_buf+(i*5),rfid.serNum,5)){
            accessGranted = true;
        }
    }

    // replace these with your own message routines.
    if (accessGranted) {
        Serial.println("Access Granted");
    } else {
        Serial.println("Access Denied");
    }
}
| improve this answer | |
  • Comments are not for extended discussion; this conversation has been moved to chat. – Majenko Apr 7 '19 at 10:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.