Go Down

Topic: Setting two devices on SPI interface (Read 265 times) previous topic - next topic

qowii

Hi,

In recent weeks I try to run two RFID RC522 on the same arduino using the SPI interface. I checked that each of my connections worked separately. Then I plugged in both at the same time and neither of them work. I checked that each PIN was plugged in correctly and checked that SS and RESET were different for each RC522.

I use an arduino of this type: ATmega328P CH340G 5 V Micro

I did some actions:

- Check that my library for the RFID reader used an SPI library with transactions.
- Test a basic implementation without a standard library

None of these tests was conclusive, I went through many documentations and thread of discussions without overcoming my worries.

Robin2

You need to post your program and tell us exactly what it does and what you want it to do that is different.

I wonder if your code needs to set the SS pin "off" for one device before trying to talk to the other device? The library will not know that there are two devices.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pylon

Together with complete code post a wiring diagram of your setup (may be hand drawn)! Provide a link to the library you're using.

qowii

#3
Oct 16, 2018, 08:33 pm Last Edit: Oct 16, 2018, 08:37 pm by qowii
I use the sources of a github project : https://github.com/miguelbalboa/rfid
Especially the file ReadUidMultiReader.ino in the example folder.

VARIABLES :

constexpr uint8_t RST_PIN = 9;     // Configurable, see typical pin layout above
constexpr uint8_t SS_1_PIN = 10;   // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 2
constexpr uint8_t SS_2_PIN = 8;    // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 1

constexpr uint8_t NR_OF_READERS = 2;

byte ssPins[] = {SS_1_PIN, SS_2_PIN};

SETUP :

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

for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
  mfrc522[reader].PCD_Init(ssPins[reader], RST_PIN); // Init each MFRC522 card
  Serial.print(F("Reader "));
  Serial.print(reader);
  Serial.print(F(": "));
  mfrc522[reader].PCD_DumpVersionToSerial();
}
}

MAIN LOOP :

void loop() {

for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
  // Look for new cards

  if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
    Serial.print(F("Reader "));
    Serial.print(reader);
    // Show some details of the PICC (that is: the tag/card)
    Serial.print(F(": Card UID:"));
    dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
    Serial.println();
    Serial.print(F("PICC type: "));
    MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
    Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));

    // Halt PICC
    mfrc522[reader].PICC_HaltA();
    // Stop encryption on PCD
    mfrc522[reader].PCD_StopCrypto1();
  } //if (mfrc522[reader].PICC_IsNewC
} //for(uint8_t reader
}


// RFID lib change SS PIN to LOW or HIGH
/**
* Writes a byte to the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
void MFRC522::PCD_WriteRegister( PCD_Register reg, ///< The register to write to. One of the PCD_Register enums.
byte value ///< The value to write.
) {
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
SPI.transfer(value);
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
} // End PCD_WriteRegister()


Thanks,
Antoine

pylon

Post complete code and use code tags! This code does not compile (no includes, mfrc522 array is not declared)!

Quote
I checked that each PIN was plugged in correctly and checked that SS and RESET were different for each RC522.
This is not true for the posted code and for the posted wiring diagram.

qowii

#5
Oct 17, 2018, 09:47 pm Last Edit: Oct 17, 2018, 09:53 pm by qowii
Okay, my apologies for this post a bit messy. I will try to do things properly in this answer.


Code: [Select]

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

constexpr uint8_t RST_1_PIN = 9;     // Configurable, see typical pin layout above
constexpr uint8_t RST_2_PIN = 7;     // Configurable, see typical pin layout above
constexpr uint8_t SS_1_PIN = 10;   // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 2
constexpr uint8_t SS_2_PIN = 8;    // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 1

constexpr uint8_t NR_OF_READERS = 2;

byte ssPins[] = {SS_1_PIN, SS_2_PIN};
byte rstPins[] = {RST_1_PIN, RST_2_PIN};

MFRC522 mfrc522[NR_OF_READERS];   // Create MFRC522 instance.

/**
 * Initialize.
 */
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

  for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
    mfrc522[reader].PCD_Init(ssPins[reader], rstPins[reader]); // Init each MFRC522 card
    Serial.print(F("Reader "));
    Serial.print(reader);
    Serial.print(F(": "));
    mfrc522[reader].PCD_DumpVersionToSerial();
  }
}

/**
 * Main loop.
 */
void loop() {

  for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
    // Look for new cards

    if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
      Serial.print(F("Reader "));
      Serial.print(reader);
      // Show some details of the PICC (that is: the tag/card)
      Serial.print(F(": Card UID:"));
      dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
      Serial.println();
      Serial.print(F("PICC type: "));
      MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
      Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));

      // Halt PICC
      mfrc522[reader].PICC_HaltA();
      // Stop encryption on PCD
      mfrc522[reader].PCD_StopCrypto1();
    } //if (mfrc522[reader].PICC_IsNewC
  } //for(uint8_t reader
}

/**
 * Helper routine to dump a byte array as hex values to Serial.
 */
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);
  }
}



Here is the message displayed by the console after downloading on the arduino :

Quote
Reader 0: Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?
Reader 1: Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?
No reaction for each reader if I use an RFID token.

If I remove one of the MISO (lecteur 1 or 2), it works.

Thanks,
Antoine

Robin2

Images from Reply #5 so we don't have to download them. See this  Simple Image Guide





...R
Two or three hours spent thinking and reading documentation solves most programming problems.


pylon

The MFRC522 is a 3.3V chip. As you say that your setup runs with only one reader the breakout board must contain some level converter. It seems that your board vendor doesn't use an SPI compatbile level converter (CS HIGH => MISO tri-state). Ask your vendor for schematics for your board. You might have to change the level converter to one that isolates MISO from the bus if CS isn't pulled down.

qowii

Can i use a 74HC595 to solve the problem ?

pylon

Can i use a 74HC595 to solve the problem ?
No, that's a serial shift register. But this device is an example.

Whandall

No, that's a serial shift register. But this device is an example.
If you want to have it less fancy but a lot cheaper 3.3V 5V TXS0108E 8 Channel Logic Level Converter
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Go Up