miguelbalboa / rfid

Arduino RFID Library for MFRC522
The Unlicense
2.74k stars 1.43k forks source link

Two RC522 with antenna set to RxGain_max not working #536

Closed don41382 closed 3 years ago

don41382 commented 3 years ago

Details:

Problem:

I am running two RFID RC522 via my ESP32 Lolin32 over one SPI bus.

Both reader work fine until I change the rfid[i].PCD_SetAntennaGain(rfid[i].RxGain_max); to the maximum (or anything above the average of 33dB) of both reader.

First observation: The antenna gain read outs (PCD_GetAntennaGain()) show not the same results. One reader is set to the maximum 112 and the other one is just set to 64.

In addition both reader are not able to read any tags anymore. I already tried to add a external power supply for the readers, but that didn't help either.

Any ideas?

Output without antenna gain set to max

Firmware Version: 0x82 = v2.0
RC 0 gain: 64
Firmware Version: 0x92 = v2.0
RC 1 gain: 64
RC0:  04 E7 16 D2 2F 66 80
RC1:  04 E7 16 D2 2F 66 80
RC0:  04 E7 16 D2 2F 66 80

Output with antenna gain set to max

Firmware Version: 0x82 = v2.0
RC 0 gain: 64
Firmware Version: 0x92 = v2.0
RC 1 gain: 112

*no read possible from none of the two rfid reader*

Code

#include <Arduino.h>
#include <MFRC522.h>

#define RFID_SS_PIN     GPIO_NUM_16
#define RFID2_SS_PIN    GPIO_NUM_17

#define NUM_READERS 2

MFRC522 rfid[NUM_READERS];
const byte ssPins[] = {RFID_SS_PIN, RFID2_SS_PIN};

void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void setup() {
  Serial.begin(115200);
  SPI.begin();
  for (int i=0; i < NUM_READERS; i++) {
    rfid[i].PCD_Init(ssPins[i],RFID_RESET_PIN);
    delay(10);
    rfid[i].PCD_DumpVersionToSerial();
    rfid[i].PCD_SetAntennaGain(rfid[i].RxGain_max);
    Serial.printf("RC %d gain: %d\n",i, rfid[i].PCD_GetAntennaGain());
    delay(100);
  }
}

void loop() {

  for (int i=0; i < NUM_READERS; i++) {
    digitalWrite(RFID_RESET_PIN, HIGH);
    delay(10);
    digitalWrite(RFID_RESET_PIN, LOW);
    bool cardPresent = rfid[i].PICC_IsNewCardPresent();
    if (cardPresent && rfid[i].PICC_ReadCardSerial()) {
      Serial.printf("RC%d: ",i);
      dump_byte_array(rfid[i].uid.uidByte, rfid[i].uid.size);
      Serial.println();
      rfid[i].PICC_HaltA();
      rfid[i].PCD_StopCrypto1();
    }
  }
  delay(50);
}
Rotzbua commented 3 years ago

outdated: Does firmware_check.ino work on both readers?

Edit: Your setup() does init every reader in a loop. But you have only one RST pin. The function .PCD_Init() resets the reader by the RST pin. Since you have only one RST pin you reset the already configured reader.

Solution: make a second loop where you set the gain.

don41382 commented 3 years ago

@Rotzbua Thanks for the hint with the firmware_check.ino. That put me on the right track.

The main problem wasn't the reset pin configuration (even though that was broken too) and I think it's actually not needed at all.

The main reason was actually the cable selection (SDA/SS) for each reader. So, when a reader became active the CS was set to LOW, but the previous reader wasn't set to HIGH in order to be inactive. I guess this created a SPI collusion.

In addition to this, I think the rfid example ReadUidMultiReader must be broken too, because it's also not setting the inactive reader to an inactive (CS to HIGH) state.

Wdyt?

Here is my (now) working code:

#include <Arduino.h>
#include <MFRC522.h>

#define RFID_RESET_PIN  GPIO_NUM_27
#define RFID2_RESET_PIN  GPIO_NUM_14

#define RFID_SS_PIN     GPIO_NUM_16
#define RFID2_SS_PIN    GPIO_NUM_17

#define NUM_READERS 2

MFRC522 rfid[NUM_READERS];
const uint8_t csPins[] = {RFID_SS_PIN, RFID2_SS_PIN};

void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void initCSMode() {
  for (int i=0; i<NUM_READERS; i++) {
    pinMode(csPins[i], OUTPUT);
  }
}

void setActiveReader(int id) {
  for (int i=0; i<NUM_READERS;i++) {
    digitalWrite(csPins[i], (id == i ? LOW : HIGH));
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("Let's start!");

  initCSMode();
  SPI.begin();

  for (int i=0; i < NUM_READERS; i++) {
    setActiveReader(i);
    rfid[i].PCD_Init(csPins[i],rfid[i].UNUSED_PIN);
    delay(4);
      rfid[i].PCD_DumpVersionToSerial();
    rfid[i].PCD_SetAntennaGain(rfid[i].RxGain_max);
    Serial.printf("RC %d gain: %d\n",i, rfid[i].PCD_GetAntennaGain());
  }
}

void loop() {

  for (int i=0; i < NUM_READERS; i++) {
    setActiveReader(i);
    if (!rfid[i].PICC_IsNewCardPresent()) {
      continue;
    }
    if (!rfid[i].PICC_ReadCardSerial()) {
      continue;
    }
    Serial.printf("RC%d: ",i);
    dump_byte_array(rfid[i].uid.uidByte, rfid[i].uid.size);
    Serial.println();

    rfid[i].PICC_HaltA();
    rfid[i].PCD_StopCrypto1();
  }
}