Search code examples
arduinorfidspiesp8266nodemcu

Weird behavior when using NodeMCU V3 with RF522


I'm attempting to use the RF522 with my NodeMCU v3 using the SPI interface. I was able to hook the RF522 to my Pi Zero and get it to scan both the chip that came with it as well as the NFC of my phone so I'm fairly confident the hardware is good.

Here's what I've found so far (connections are documented in code below):

  • If I hook everything up, I cannot upload my Arduino sketch (espcomm_upload_mem failed) and I cannot run a script that is on the NodeMCU.
  • If I disconnect the 3v power to the RF522, I can upload the script and run it.
  • If I leave the 3v power disconnect, the program fails the self test: mfrc522.PCD_PerformSelfTest()
  • If I plug the 3v power line in after the NodeMCU boots but before the self test, it passes the self test and runs!
  • I never find a card (repeats "No new card..." forever). Tried existing chip and phone but nothing was found.

I'm not sure why having the power installed keeps everything else from starting and I have no idea why I can't read a card when the self-test passes! Does anyone else have experience getting the RF522 and NodeMCU to work together?

Code:

#include <ESP8266WiFi.h>          //ESP8266 Core WiFi Library (you most likely already have this in your sketch)
#include <DNSServer.h>            //Local DNS Server used for redirecting all requests to the configuration portal
#include <ESP8266WebServer.h>     //Local WebServer used to serve the configuration portal
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
#include <PubSubClient.h>
#include <SPI.h>
#include <MFRC522.h>

/*
*RST GPIO15 -- D8
*SDA(SS) GPIO2 -- D4
*MOSI GPIO13 -- D7
*MISO GPIO12 -- D6
*SCK GPIO14 -- D5
*GND GND
*3,3V 3,3V
 */
#define SS_PIN  2 // D4 -- SDA-PIN for RC522
#define RST_PIN  15 // D8 -- RST-PIN for RC522
MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance.

WiFiClient espClient;
PubSubClient mqtt(espClient);

const char* MQTT_user = "rfid.local";
const char* MQTT_server = "mqtt.local";
const char* topic_base = "home/rfid/";

void setup() {
  Serial.begin(115200);
  Serial.println("Lets get started!!");

  WiFiManager wifiManager;
  wifiManager.setTimeout(180); 
  if(!wifiManager.autoConnect("RFID", "RFID")) {
    Serial.println("Failed to connect and hit timeout");
    delay(3000);
    ESP.reset();
    delay(5000);
  } 
  Serial.println("Connected...yippie!");

  mqtt.setServer(MQTT_server, 1883);

  SPI.begin();     // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card
  if (mfrc522.PCD_PerformSelfTest())
    Serial.println("RF522 Passed self test!");
  else {
    Serial.println("RF522 Failed self test!");
    delay(3000);
    ESP.reset();
    delay(5000);    
  }
  Serial.println("Waiting for someone to scan...");
}

void reconnectMQTT() {
  // Loop until we're reconnected
  while (!mqtt.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (mqtt.connect(MQTT_user, MQTT_user, MQTT_user)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqtt.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void loop() {
  // Make sure we are still connected!
  if (!mqtt.connected()) {
    reconnectMQTT();
  }
  mqtt.loop();

  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    Serial.println("No new card...");
    delay(1000);
    return;
  }

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    Serial.println("Can't read card...");
    delay(1000);
    return;
  }

  // Dump debug info about the card. PICC_HaltA() is automatically called.
  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
  //mqtt.publish(topic_base...);
}

Solution

  • The problem was that I needed to call mfrc522.PCD_Init(); again after performing the self test and version dump. Once I did this, everything worked as expected!