Yun & RFID RC522 pin layout [solved]

Hi all,

I’m using this library GitHub - miguelbalboa/rfid: Arduino RFID Library for MFRC522 to get an RC522 RFID reader (Dumpinfo example) to work.

However, the pin layout on Yun is different from Uno in the example projects.
Using this diagram, I figured out the pins need to be connected to the ICSP pins pictured at the bottom. Attached is a drawing of how I connected the pins.

Unfortunately, the serial monitor keeps stating:
MFRC522 Software Version: 0x0 (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?

In the example script, two pins are defined using
#define RST_PIN 9
#define SS_PIN 10
I Googled and tried several options for these definitions, but no luck.

Has anyone else got the RC522 working on the Yun, or suggestions on how I should wire/script this differently?

Thanks in advance

I think you have several mistakes in your wiring.

You mention using pins 9 and 10, but you don't have them hooked up to anything on the board. Make sure you are looking at the pink/magenta boxes for PIN numbers, the grey "9" and "10" boxes on the diagram are the processor's physical pin numbers, not the logical PIN numbers used by the Arduino pin functions.

Also, you have SDA hooked up, but that's only half of the I2C bus - is this using I2C or SPI? Or is SDA on that board the SS pin (I don't see anything labeled SS on honest board?)

It's not very likely you will find an exact example for the Yun. But the shield interface part of the Yun is the same as a Leonardo - can you find an example of using that board with a Leonardo? That will be a much more useful example for you than an Uno example. (As you found, the Uno and the Yun/Leonardo have the SPI pins in different locations, but the Yun and Leonardo are the same in that regard.)

Thanks for your reply!

The pins for Leonardo are as follows: RST/Reset => RESET/ICSP-5 SPI SS => 10 SPI MOSI => ICSP-4 SPI MISO => ICSP-1 SPI SCK => ICSP-3 So I switched SDA to pin 10 (thanks for the colouring tip), and assume RESET/ICSP-5 is still like in my drawing. I'm not sure how to define these pins in the sketch as RST_PIN though (sorry, trying to get my head round these ICSP pins). With regards to SPI/SS/SDA, I took some guidance from this video, although he uses a different board.

I will continue to try and figure this out, but if you have any further tips based on this info, that'd be great.

Thanks again

I'm not familiar with the board or library, so I don't know what it's expecting with the reset line. As you have it hooked up now, to the ICSP reset line, it's connected to the AVR processor's reset signal. So it will reset the board whenever the processor resets. That pin is not accessible by, nor can it be controlled by the sketch. You simply ignore it and know that your board will be automatically reset when the AVR processor is reset. That pin on the ICSP is the same as the reset pin by the power pins, and is the same line that is grounded when you press the '32U4 RST button.

If the library needs an explicit reset pin, you will have to hook it up to one of the other pins, just don't use 0 or 1, as the are the Tx/Rx to the Linux processor. You will then be able to control that pin in software.

I think you're getting close.

Have you guys solved the problem? I started with Yun this week and Im having the same problem.

I have OK

RST/Reset RST = ICSP-5 SPI SS SDA(SS) = 10 !!!! SPI MOSI = ICSP-4 SPI MISO = ICSP-1 SPI SCK SCK = ICSP-3

define RST_PIN 13 // =ICSP-5

define SS_PIN 10

It's been a while since I played around with this, but thanks to kkmspb's reply I got it working in no time when I picked it up again today. Thanks! Also, this answer helped identify the correct ICSP pins; http://arduino.stackexchange.com/questions/6697/arduino-yun-rfid-rc522-module-not-working

I tried this and thought this would not harm anyone here.

I’m using the arduino YUN and I have connected the RC522 board to the ICSP pins as suggested by kkmsp.

RST to the ICSP-5
SPI SS SDA(SS) to pin 10
SPI MOSI to ICSP-4
SPI MISO to ICSP-1
SPI SCK to ICSP-3
I’m only using the 3.3V instead of the ICSP-2 which provides 5V.

Here it’s the code (should I use another library, cause this one worked with the Arduino Ethernet board, but now I want it to run on Arduino YUN):

#include <SPI.h>
#include <RFID.h>

#define RST_PIN         13 // =ICSP-5  I will change this to be able to use the built-in led in YUN
#define SS_PIN          10      //  


RFID rfid(SS_PIN,RST_PIN);


int led = 13;
int power = 8; 
int serNum[5];
int cards[][5] = {
  {5,117,21,219,190},//Card1
  {214,187,247,72,210}//Card2

  
};

bool access = false;

void setup(){

    Serial.begin(57600);
    SPI.begin();
    rfid.init();

    pinMode(led, OUTPUT);

    digitalWrite(led, LOW);
   
}

void loop(){
    
    if(rfid.isCard()){
    
        if(rfid.readCardSerial()){
            Serial.print(rfid.serNum[0]);
            Serial.print(" ");
            Serial.print(rfid.serNum[1]);
            Serial.print(" ");
            Serial.print(rfid.serNum[2]);
            Serial.print(" ");
            Serial.print(rfid.serNum[3]);
            Serial.print(" ");
            Serial.print(rfid.serNum[4]);
            Serial.println("");
            
            for(int x = 0; x < sizeof(cards); x++){
              for(int i = 0; i < sizeof(rfid.serNum); i++ ){
                  if(rfid.serNum[i] != cards[x][i]) {
                      access = false;
                      break;
                  } else {
                      access = true;
                  }
              }
              if(access) break;
            }
           
        }
        
       if(access){
          Serial.println("Welcome!");
           digitalWrite(led, HIGH); 
           delay(1000);
           digitalWrite(led, LOW);
           digitalWrite(power, HIGH);
           delay(1000);
           digitalWrite(power, LOW);
           
      } else {
           Serial.println("Not allowed!"); 
           digitalWrite(led, HIGH);
           delay(250);
           digitalWrite(led, LOW); 
           delay(250);
           digitalWrite(led, HIGH);
           delay(250);
           digitalWrite(led, LOW);
           delay(250);
           digitalWrite(led, HIGH);
           delay(250);
           digitalWrite(led, LOW);           
       }        
    }
    
    
    
    rfid.halt();

}

Regards.

This won’t do what I think you want it to accomplish:

bernext:

            for(int x = 0; x < sizeof(cards); x++){

for(int i = 0; i < sizeof(rfid.serNum); i++ ){

The sizeof() function returns the number of bytes allocated by the argument. I’m guessing you think it tells you the number of array elements, which is usually wrong (the only time that happens to work is when you have a single dimension array of bytes.)

In the outer loop, cards is a 2 x 5 array of integers, which is a total of 10 integers. For the AVR processor on the Yun, an integer is 2 bytes, so sizeof(cards) will return 20. I’m thinking that you want to only run that loop twice (the number of cards) and not 20 times.

In the inner loop, you are getting the size of rfid.serNum. I’m not familiar with that library, but the returned size is again unlikely to be the 5 that I guess you are expecting. If the type of array element is an int, like you defined for the cards array, then you are likely to get back a value of 10. However, if the array size is not explicitly defined in the RFID class declaration, sizeof() may treat rfid.serNum as a pointer, in which case the return value will be 2.

sizeof() is tricky, and can only be used to determine the number of array elements in very specific situations - only when the actual definition of the array being tested is visible in the same scope as the sizeof() call. It can’t be used where the actual size of the array is not directly known at compile time, like inside of a function where an array is passed into the function.

Even when the definition of the array is clearly known at compile time (like it is for the cards array when sizeof() is called in this sketch file) then sizeof() still won’t give you a reliable value unless you know some tricks of using it. Consider this example:

   int someArray[] = {1, 2, 3, 4, 5};
   Serial.println(sizeof(someArray);
   Serial.println(sizeof(someArray[0]);
   Serial.println(sizeof(somearray) / sizeof(someArray[0]));

In this example, someArray is a five element array of integers. The first println() call prints out the value 10, which is the total number of bytes used by the whole array - note that this is not the number of elements in the array.

The second println() call prints out the value 2, which is the number of bytes used by a single element of the array.

The third println() call prints out the value 5, which is the total number of bytes used by the array (10) divided by the number of bytes used by a single element of the array (2) and the quotient of that division gives the expected number of array elements: 5.

In your code, you could use something similar to determine your loop indicies, but it gets more complicated because of the two dimensional array. While writing code that automatically adjusts itself to the number of array elements is an admirable goal, in this case I would suggest to simply defining an explicit number of array elements, and using the value directly, something like this: (only a fragment of the code)

#define NUM_SERNUM_VALUES  5
#define NUM_CARDS          2

int serNum[NUM_SERNUM_VALUES];
int cards[NUM_CARDS][NUM_SERNUM_VALUES] = {
  {5,117,21,219,190},//Card1
  {214,187,247,72,210}//Card2


...


            for(int x = 0; x < NUM_CARDS; x++){
              for(int i = 0; i < NUM_SERNUM_VALUES; i++ ){

Also, I’m a bit suspicious of the way you are determining a valid card. Normally, when I’m performing a complex comparison such as this, I’ll set the flag to valid before starting the test, and then set it invalid whenever a test fails. I don’t set it back to valid inside the loop, otherwise a subsequent good test might wipe out the results of a prior test. Also, while trying to write efficient code by using the break statements to shortcut the loops is another admirable goal, this is a relatively short test sequence, and you aren’t saving a huge amount of processing time here. I think it better to have easy to read and maintain code, and only resort to the tricks to speed things up if you really need them. Taking all of the suggestions together, you end up with something like:

           access = true;
            for(int x = 0; x < NUM_CARDS; x++){
              for(int i = 0; i < NUM_SERNUM_VALUES; i++ ){
                  if(rfid.serNum[i] != cards[x][i]) {
                      access = false;
                  }
               }
            }

And some will debate this, but since all of the loop and if statements consist of a single controlled statement, you can make it a bit cleaner by eliminating the braces, although there is a risk of causing problems if you later add additional code that makes a set of braces necessary, and you don’t add the required braces. It’s a personal decision:

           access = true;
            for(int x = 0; x < NUM_CARDS; x++)
              for(int i = 0; i < NUM_SERNUM_VALUES; i++ )
                  if(rfid.serNum[i] != cards[x][i]) 
                      access = false;