2

I have a project using the RC522 RFID module with my Arduino Uno board and miguelbalboa's rfid library. The example code and every other code I find on the internet work pooling the device in order to know if there is a new card present, but I intend to work with a interrupt-driven approach. I have the proper knowledge to do the hardware/arduino part, but I'm having trouble generating an interrupt in the IRQ pin when the card is present. Have anyone succeded on this?

Edit: Connection: RST -> 8

SS-> 9

MOSI -> 11

MISO -> 12

SCK -> 13

IRQ -> 2

Code:

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

#define RST_PIN     8 
#define SS_PIN      9

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

void setup() 
{
  Serial.begin(9600);       // Initialize serial communications with the PC
  while (!Serial);      // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();          // Init SPI bus
  mfrc522.PCD_Init();       // Init MFRC522
  mfrc522.PCD_WriteRegister(MFRC522::ComIrqReg, 0x80); //Clear interrupts
  mfrc522.PCD_WriteRegister(MFRC522::ComIEnReg, 0x7F); //Enable all interrupts
  mfrc522.PCD_WriteRegister(MFRC522::DivIEnReg, 0x14);
  Serial.println(F("Ready..."));
  attachInterrupt(0, isr, RISING);
}

void loop() 
{
}

void isr()
{
  Serial.println(F("Interrupt"));
  mfrc522.PCD_WriteRegister(MFRC522::ComIrqReg, 0x80); //Clear interrupts
}

Result: I only get the "Ready..." on the Serial Monitor, no matter if there is a card present or not.

  • Welcome to Arduino SE! Code? Wiring? – Anonymous Penguin Mar 28 '15 at 15:38
  • @AnnonomusPenguin I have only used the example codes and wiring from the link (minor change, RST -> pin 8 and SS -> pin 9, for compatibility with the ethernet shield). As I haven't got access to an oscilloscope right now, I'm unable to check the interrupt pin, so I wrote a sketch to pool this pin and print its state via serial, 3-line code. It keeps giving me 0, no matter if the card is present or not... The documentation link says little about the interrupts and they're relation to the card reading. – Gustavo Sgarbi Campos Mar 28 '15 at 21:36
  • Does that code deal with interrupts itself or have you modified it? – Anonymous Penguin Mar 28 '15 at 21:53
  • The library doesn't deal with the interrupt, they don't even use the IRQ pin... – Gustavo Sgarbi Campos Mar 29 '15 at 4:14
  • So you did modify the code? Can you please add a minimal example of the problem (with the code and a circuit) to your question with an edit? Thanks – Anonymous Penguin Mar 29 '15 at 5:14
3

From your code:

void isr()
{
  Serial.println(F("Interrupt"));
  mfrc522.PCD_WriteRegister(MFRC522::ComIrqReg, 0x80); //Clear interrupts
}

Do not do serial prints inside an ISR! They will eventually hang it. What you need to do is have a volatile variable (eg. a bool), set that in the ISR, and then check that in loop. If it changes, display it. Eg.

volatile bool cardPresent;

void loop() 
{
  if (cardPresent)
    {
    Serial.println(F("Interrupt"));
    mfrc522.PCD_WriteRegister(MFRC522::ComIrqReg, 0x80); //Clear interrupts
    cardPresent = false;
    }

}

void isr()
{
  cardPresent = true;
}

The other thing I would do is put a scope or logic analyzer on the IRQ pin and see if it is actually changing. It should trigger the interrupt if it does.

0

first of all, I apologize for the English, I can understand it but i use google translator to express myself in.

I don't use arduino, It's a interesting platform (for the ide, which is apparently object oriented programming POO), but extremely limited by the hardware

Well, entering the subject, I am also developing an implementation for the MRFC522, and the datasheet does not give examples of how do it, but indicates how enable interrupts (although I have not tried ,yet)

but if I'm not wrong, the following registers are involved:

ComIEnReg--> Control register bits to enable and disable the passing of interrupt requests.

DivIEnReg--> control bits to enable and disable the passing of interrupt requests.

ComIrqReg--> register Interrupt request bits. (I think it's read only)

DivIrqReg--> register bit descriptions (I think it's read only)

I think it's just properly setting the first two should be able to generate the interrupt on the pin irq. i don't know if the following is correct.

set ComIEnReg to --> (in binary) 0b01111111 //enables all al interrupts

set DivIEnReg to --> 0b10000100 //I don't understand complete about MFIN (bit4) and set it to 0 but i set CRCIEn to 1 (bit 2) and bit7 to 1 "pin IRQ is a standard CMOS output pin"

// the different posible configuration to DivIEnReg

  • yours--> 0b00010100 -->0x14
  • try 1 --> 0b00000100 -->0x04
  • try 2 --> 0b10010100 -->0X94
  • try 3 --> 0b10000100 -->0X84

if you manage to the module to do the interruption, it would be kind enough to comment on how you did

  • Unfortunatelly I was unable to use the IRQ pin. My project is stopped right now but I'll get back to it in a little and maybe figure it out. I'm pooling the module to check for a new tag for now and for what I read back then seem like no one was able to use the interruption to detect new tags. I agree with you on the Arduino, it's very limited but as I'm only working on a POC (proof of concept), is the perfect platform! – Gustavo Sgarbi Campos Aug 14 '15 at 5:49
  • As you mentioned "Arduino is limited" can you share other alternatives. Would like to explore them as-well. I am completely from the software side, and would like to understand this more. – karx Jan 27 '18 at 20:06

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.