1

I'm fairly new to Arduino (and C), but not to embedded electronics and programming.

I'm using an MFRC522 module (the common one) with a Nano, and getting some strange results. They are on a very simple custom PCB I've made (the only parts on it, except for a couple of LEDs on D4 & D5) I'm using SS_PIN on 8, and RST_PIN on 7, which is changed from 10 & 9, because the board will also be using an NRF24L01 module on the SPI bus (not fitted yet).

And I'm using the MFRC522 library. The DumpInfo example in the library works fine, but not the ReadNUID example.

When I bring a tag/card near the reader, the sketch (sometimes) gets some of its output to the serial monitor, but then (always) the board reboots and the startup messages appear again. This happens continuously while the card is near.

I have the RFID IRQ connected to pin D3, and while thinking that may be causing the problem, and trying all sorts of stuff, I found that it wasn't. In the process I did get the sketch to work, and have distilled the fix down to two seemingly superfluous lines of code:-

Added a null if statement at the start of loop:-

if (GotIRQ) {}  

and defined a volatile variable for it to test:-

volatile boolean GotIRQ=false; 

Doesn't work if it's not volatile. (A clue?)

What Gives? Some dumb newbie mistake?

(I could post the entire code if required, but I've started again from the original source, and only made the 2 changes and 2 additions described above)

Here is the code:-

/*
 * --------------------------------------------------------------------------------------------------------------------
 * Example sketch/program showing how to read new NUID from a PICC to serial.
 * --------------------------------------------------------------------------------------------------------------------
 * This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
 * 
 * Example sketch/program showing how to the read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
 * Reader on the Arduino SPI interface.
 * 
 * When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
 * then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When
 * you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
 * will show the type, and the NUID if a new card has been detected. Note: you may see "Timeout in communication" messages
 * when removing the PICC from reading distance too early.
 * 
 * @license Released into the public domain.
 * 
 * Typical pin layout used:
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 */

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 8   //QQ This changed from 10
#define RST_PIN 7   //QQ This changed from 9 

MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class

MFRC522::MIFARE_Key key; 

volatile boolean GotIRQ=false; //QQ needed for null if statement

// Init array that will store new NUID 
byte nuidPICC[3];

void setup() { 
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522 

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }

  Serial.println(F("This code scan the MIFARE Classsic NUID."));
  Serial.print(F("Using the following key:"));
  printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
}

void loop() {
  if (GotIRQ) {}   //QQ If this is not included, board resets when a RFID tag is detected

  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been readed
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));

  // Check is the PICC of Classic MIFARE type
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
    piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println(F("Your tag is not of type MIFARE Classic."));
    return;
  }

  if (rfid.uid.uidByte[0] != nuidPICC[0] || 
    rfid.uid.uidByte[1] != nuidPICC[1] || 
    rfid.uid.uidByte[2] != nuidPICC[2] || 
    rfid.uid.uidByte[3] != nuidPICC[3] ) {
    Serial.println(F("A new card has been detected."));

    // Store NUID into nuidPICC array
    for (byte i = 0; i < 4; i++) {
      nuidPICC[i] = rfid.uid.uidByte[i];
    }

    Serial.println(F("The NUID tag is:"));
    Serial.print(F("In hex: "));
    printHex(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
    Serial.print(F("In dec: "));
    printDec(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
  }
  else Serial.println(F("Card read previously."));

  // Halt PICC
  rfid.PICC_HaltA();

  // Stop encryption on PCD
  rfid.PCD_StopCrypto1();
}


/**
 * Helper routine to dump a byte array as hex values to Serial. 
 */
void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

/**
 * Helper routine to dump a byte array as dec values to Serial.
 */
void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], DEC);
  }
}

OK, trying to cut down to a minimal example has proved useful. It seems the problem is caused by the loop that stores the NUID, but not if the superfluous if statement is present. The code is :-

// Cut down version of MFRC522 library ReadNUID example that exhibits strangle 
// problem of rebooting the board when a card is near the reader.
// But only if:-
// * the Store NUID loop is included 
// and 
// * the superfluous "if" statement at start of loop() is NOT present.
// Changes from original example are indicated by comments starting with "//QQ" 
// (plus a lot of removed code)

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 8   //QQ This changed from 10
#define RST_PIN 7   //QQ This changed from 9 

MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class

MFRC522::MIFARE_Key key; 

volatile boolean GotIRQ=false; //QQ needed for null if statement

// Init array that will store new NUID 
byte nuidPICC[3];

void setup() { 
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522 

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }

  Serial.println(F("This code scan the MIFARE Classsic NUID."));
}

void loop() {
//  if (GotIRQ) {}   //QQ If this is not included, board resets when a RFID tag is detected

  // Look for new cards
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Verify if the NUID has been readed
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));

  // Store NUID into nuidPICC array //QQ does not fail if this loop is excluded
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }

  // Halt PICC
  rfid.PICC_HaltA();

  // Stop encryption on PCD
  rfid.PCD_StopCrypto1();
}
7
  • 1
    Please can you post a minimal verifiable example of code. Sorry but just adding two lines means nothing. Commented May 2, 2017 at 7:22
  • Welcome to Arduino SE. Be sure to take the tour to see how things work here: arduino.stackexchange.com/Tour
    – SDsolar
    Commented May 2, 2017 at 20:11
  • "minimal verifiable example of code". I wanted to use code that many would be familiar with, and just show the simple change I made that brings on the problem. I'll try to reduce it, but then we don't have a familiar starting point. just adding two lines means nothing.
    – bertoid
    Commented May 3, 2017 at 0:08
  • This comment system is confusing. I just wanted to start a new line, but it kept posting each time, so my comment could be gibberish, and then it timed out on me.
    – bertoid
    Commented May 3, 2017 at 0:18
  • Added my modified example code, and a minimal version of it. It seems the loop that stores the NUID causes the problem (new problem), and including the null if statement fixes it (original problem)
    – bertoid
    Commented May 3, 2017 at 0:54

2 Answers 2

1

You've defined this array to have three elements:

byte nuidPICC[3];

those three elements are numbered 0, 1, and 2.

In this for loop:

for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }

you are writing to position 3, which is out of bounds for that array.

Once you write out of bounds on an array the behavior is undefined. Resetting is one common result. But anything could happen.

0

I'm assuming that the extra byte in the array is needed, possibly for a null terminator or whatever, and that the example code has a bug. I've had no further problems since changing the NUID[3] to NUID[4], so I'll leave this at that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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