NRF24L01 and MFRC522 using SPI

Hello, all.
This is my first post. I have read numerous other forums to get this far in my project, however I have hit a major roadblock. Software is my profession and Im learning how hardware as I go :slight_smile:

The overall idea for my project is to have multiple Arduino Nano's (important note for below: right now I am using UNO's) wired with MRFC522 RFID reader module and NRF34L01 radio module. Each "slave" Arduino will send the RFID UID card value to the "master" Arduino (either be a nano or Uno, have not gotten that far yet) where some logic will be computed and output set.

Presently, my issue is with the slave program.

A basic MRFC522 sketch (not provided) has proven that I am able to get the module working on its own. And by working, I mean detected a new card, read the UID and output it to serial.

Following Simple nRF24L01+ 2.4GHz transceiver demo I was able to get a basic RF Tx/Rx working with relative reliability. Reliability increased with adding the capacitor and external power.

My trancieveing nRF24L01 is equipped with its own 2 AA battery power supply and has a 10 ยตF capacitor soldered to the source. The receiving end has a smaller capacitor 100 nF capacitor on it using the 3.3v pin of the Arduino Uno

The MRFC522 is connected to the 3.3V pin on the Arduino board.

Both the MRFC522 and nRF24L01 share the common SPI bus line (SCK, MOSI, MISO). Both have their own slave select pins (detailed in the Rx code below).

The Tx code is where I believe my issue is. The expected behavior of the below Tx code is to:

  1. Init components/modules in the setup() function
    (In the loop() function):
  2. Transmit an a message to the reciever (which will print out the message; in this case it will be "Message1")
    2a. Then, check to see if a PICC card is present and the serial is able to be read (i.e. a card has been placed in front of the RFID reader).
    2b. If true, transmit another message to listening receivers, this time "Message2"
    2c. Else, do nothing, go to top of loop

The actual behavior right now is I am able to transmit the first message with some confidence.
( Hesitation is that there appears to be an irregular pattern to the message being received. In the test program where I was JUST Tx/Rx, the receive stream (i.e. printing to serial from the Rx program) was consistently providing output in relation to the delay() I had set. )
When a PICC card is present and the serial is able to be read, the second message is NOT sent and transmission stops until I remove the card (its as if it has become a blocking call?). Once the card has been removed, and that if-conditional is false, the first message ("Message1") begins transmitting in the irregular pattern again.

In summary, my question is 2-fold:

  1. How can I get the two interfaces to cooperate
  2. How can i get the two interfaces to cooperate in a reliable and predictable manner? (ultimately, this will be used in a system where reliability is paramount).

Transmitting Code (Tx)
RFID_basic.ino

#include <MFRC522.h>

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

#define CE_PIN          7
#define CSN_PIN         8

RF24 radio(CE_PIN, CSN_PIN);

const byte address[6]="00001";

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

String ACCEPTED = String("23327250110");

void setup() {
  Serial.begin(9600);

  pinMode(CE_PIN,OUTPUT);
  pinMode(CSN_PIN,OUTPUT);
  pinMode(RST_PIN,OUTPUT);
  pinMode(SS_PIN,OUTPUT);

  radioOFF();
  rfidOFF();

  SPI.begin();

  // NRF
  radioON();
  radio.begin();
  radio.setChannel(115);
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(address);
  radioOFF();

  // MRFC
  rfidON();
  rfid.PCD_Init();
  rfid.PCD_DumpVersionToSerial();
  rfidOFF();

  Serial.println("READY TO SCAN");

}

void loop() {
  radioON();
  const char text[] = "Message1";
  const char text2[] = "Message2";
  radio.write(&text,sizeof(text));
  radioOFF();
  rfidON();
  if( rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial() )
  {
      rfidOFF();
      //Serial.println("CARD FOUND");
      radioON();
      radio.write(&text2,sizeof(text2));
      radioOFF();
  }
  rfidOFF();
  delay(500);
}


/*
Checks the ACCEPTED array to see if the value of scanned is something we are looking for
*/
int isAcceptedCard (String card)
{
  return ACCEPTED.equals(card);
}

/*

/*
Returns the RFID card UID as a String 
*/
void dump_byte_array(char *card, byte *buffer, byte bufferSize) {
  //char s[64];
  for (byte i = 0; i < bufferSize; i++) {
    card[i] = buffer[i];
  }
  //return ;
}

/*
RADIO TOGGLES
*/
void radioOFF()
{
  digitalWrite(CE_PIN,HIGH);
  digitalWrite(CSN_PIN,HIGH);
}

void radioON()
{
  digitalWrite(CE_PIN,LOW);
  digitalWrite(CSN_PIN,LOW);
}

/*
RFID TOGGLES
*/

void rfidOFF()
{
    digitalWrite(RST_PIN,HIGH);
    digitalWrite(SS_PIN,HIGH);
}

void rfidON()
{
    digitalWrite(RST_PIN,LOW);
    digitalWrite(SS_PIN,LOW);
}

Receiving code:
simpleRx.ino

#include <SPI.h>
#include <nRF24L01.h>
#include "RF24.h"

#define CE_PIN  7
#define CSN_PIN 8

RF24 radio(CE_PIN,CSN_PIN);

const byte address[6]="00001";


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  radio.begin();
  radio.setChannel(115);
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(0,address);
  radio.startListening();

  Serial.println("READY TO RECIEVE");

}

void loop() {
  while(radio.available()){
    char text[32] = "";
    radio.read(&text,sizeof(text));
    Serial.println(text);
  }
}

Images of my connections, can provide more photos or details if need be!

Thank you to any that made it this far. I really want to understand why this is not working. It seems to me this is a SPI issue. However, pulling the control pins to HIGH/LOW do not seem to be responsive.

The more text, the more ignorance is a thought.
Using a simple phone, no copy and paste etc... "Adding a nanoF capacitor to the UNO 3.3 volt output".... Please post schematics!

Check the state of the MISO line coming out of the MFRC522 when it is idle. Dollars to donuts it's not tristating the line but is instead still driving it (a quick Google search brought up many many people having similar problems - though usually with multiple MFRC522 boards).

A hardware solution is to feed the MFRC522's MISO line through a 74AHC125 quad tri-state buffer. Connect the enable pin for the buffer to the MFRC522's SS pin. That way, the only time the MFRC522 is allowed to drive the MISO line is when it's selected.

For more reading, this is a good article.

https://www.pjrc.com/better-spi-bus-design-in-3-steps/

I am unsure of what most of your reply means, but I will work on getting a schematic worked up for easement

Awesome, thank you for that. Ill do some reading on that article and report back anything that sheds more light on my issue or solves it all together!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.