ATrappmann / PN5180-Library

PN5180 library for Arduino
GNU Lesser General Public License v2.1
104 stars 92 forks source link

Making 2 reader to work together #50

Closed stuntman47 closed 2 years ago

stuntman47 commented 2 years ago

I have tried googling the past few days and don't seem to find any kind of solution. Basically, the PN5180 will only read the first reader but won't read on the 2nd reader. When I tried to add in the code to read the version of the hardware, it reads the first version 4.0 but the 2nd one is always 0.0. I tried to reverse the 1st and 2nd reader and it will only always read the first one.

I read online about SPI and what I can understand is that MOSI, MISO, and SCK can be used under the same pin, and the other pins like NSS, RST, and BUSY are separated.

Here is my picture of the layout and code(the jumper wire order starts from right to left for MOSI, MISO, SCK) layout

#include <PN5180.h>
#include <PN5180ISO14443.h>
#include <PN5180ISO15693.h>
#include <SPI.h>
//#include <Debug.h>

PN5180ISO15693 nfc(2, 4, 15);
PN5180ISO15693 nfc2(27,26,25);

void setup() {
  //spiV.begin(18,19,23,2); //SCLK, MISO, MOSI, SS
  //spiH.begin(14,12,13,27);
  //SPI.begin();
  Serial.begin(115200);
  Serial.println(SS);
  Serial.println(F("=================================="));
  Serial.println(F("Uploaded: " __DATE__ " " __TIME__));
  Serial.println(F("PN5180 ISO15693 Demo Sketch"));

  Serial.print("Reader 1 ");
  Serial.println(F("Initialising..."));
  nfc.begin();
  Serial.println(F("PN5180 Hard-Reset..."));
  nfc.reset();
  Serial.println(F("Reading product version..."));
  uint8_t productVersion[2];
  nfc.readEEprom(PRODUCT_VERSION, productVersion, sizeof(productVersion));
  Serial.print(F("Product version="));
  Serial.print(productVersion[1]);
  Serial.print(".");
  Serial.println(productVersion[0]);
  if (0xff == productVersion[1]) { // if product version 255, the initialization failed
    Serial.println(F("Initialization failed!?"));
    Serial.println(F("Press reset to restart..."));
    Serial.flush();
    exit(-1); // halt
  }
  Serial.println(F("Enable RF field..."));
  nfc.setupRF();
  Serial.println("Reader 1 ready");

  Serial.print("Reader 2 ");
  Serial.println(F("Initialising..."));
  nfc2.begin();
  nfc2.reset();
  Serial.println(F("Reading product version..."));
  nfc2.readEEprom(PRODUCT_VERSION, productVersion, sizeof(productVersion));
  Serial.print(F("Product version="));
  Serial.print(productVersion[1]);
  Serial.print(".");
  Serial.println(productVersion[0]);
  if (0xff == productVersion[1]) { // if product version 255, the initialization failed
    Serial.println(F("Initialization failed!?"));
    Serial.println(F("Press reset to restart..."));
    Serial.flush();
    exit(-1); // halt
  }
  nfc2.setupRF();
  Serial.println("Reader 2 ready");
  Serial.println(F("Setup Complete"));

}

uint8_t uid[8];
uint32_t loopCnt = 0;
void loop() {
  Serial.println(F("----------------------------------"));
  Serial.print(F("Loop #"));
  Serial.println(loopCnt++);

    bool entranceHasCard = readEntrance();

    if(entranceHasCard == true)
    {
      Serial.print("Entrance: ");
      for (int i=0; i<8; i++){
        Serial.print(uid[7-i], HEX); //LSB is first
        if (i < 2) Serial.print(":");
      }
      Serial.println();

    }

    bool exitHasCard = readExit();

    if(exitHasCard == true)
    {
      Serial.print("Exit: ");
      for (int i=0; i<8; i++){
        Serial.print(uid[7-i], HEX); //LSB is first
        if (i < 2) Serial.print(":");
      }
      Serial.println();
    }
    Serial.println("No card detected");
    delay(1000);
}

bool readEntrance(){
   nfc.reset();
   nfc.setupRF();
   ISO15693ErrorCode rc = nfc.getInventory(uid);
   if (ISO15693_EC_OK != rc){
     return false; //no card exist
   }
   else{
     return true; //card exist
   }
}

bool readExit(){
  nfc2.reset();
  nfc2.setupRF();
  ISO15693ErrorCode rc2 = nfc2.getInventory(uid);
  if (ISO15693_EC_OK != rc2){
    return false; //no card exist
  }
  else{
    return true; //card exist
  }
}
stuntman47 commented 2 years ago

I referred to this library and modified the object implementation.

I separate the 2 readers with VSPI and HSPI (instead of single VSPI) and it just works wonderfully. However, this does not work well with ISO 14443 as it will keep showing 0 values in UID.

// DESC: Example usage of the PN5180 library for the PN5180-NFC Module
//       from NXP Semiconductors.
//
// Copyright (c) 2018 by Andreas Trappmann. All rights reserved.
//
// This file is part of the PN5180 library for the Arduino environment.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// BEWARE: SPI with an Arduino to a PN5180 module has to be at a level of 3.3V
// use of logic-level converters from 5V->3.3V is absolutely necessary
// on most Arduinos for all input pins of PN5180!
// If used with an ESP-32, there is no need for a logic-level converter, since
// it operates on 3.3V already.
//
// Arduino <-> Level Converter <-> PN5180 pin mapping:
// 5V             <-->             5V
// 3.3V           <-->             3.3V
// GND            <-->             GND
// 5V      <-> HV
// GND     <-> GND (HV)
//             LV              <-> 3.3V
//             GND (LV)        <-> GND
// SCLK,13 <-> HV1 - LV1       --> SCLK
// MISO,12        <---         <-- MISO
// MOSI,11 <-> HV3 - LV3       --> MOSI
// SS,10   <-> HV4 - LV4       --> NSS (=Not SS -> active LOW)
// BUSY,9         <---             BUSY
// Reset,7 <-> HV2 - LV2       --> RST
//
// ESP-32    <--> PN5180 pin mapping:
// 3.3V      <--> 3.3V
// GND       <--> GND
// SCLK, 18   --> SCLK
// MISO, 19  <--  MISO
// MOSI, 23   --> MOSI
// SS, 16     --> NSS (=Not SS -> active LOW)
// BUSY, 5   <--  BUSY
// Reset, 17  --> RST
//

/*
 * Pins on ICODE2 Reader Writer:
 *
 *   ICODE2   |     PN5180
 * pin  label | pin  I/O  name
 * 1    +5V
 * 2    +3,3V
 * 3    RST     10   I    RESET_N (low active)
 * 4    NSS     1    I    SPI NSS
 * 5    MOSI    3    I    SPI MOSI
 * 6    MISO    5    O    SPI MISO
 * 7    SCK     7    I    SPI Clock
 * 8    BUSY    8    O    Busy Signal
 * 9    GND     9  Supply VSS - Ground
 * 10   GPIO    38   O    GPO1 - Control for external DC/DC
 * 11   IRQ     39   O    IRQ
 * 12   AUX     40   O    AUX1 - Analog/Digital test signal
 * 13   REQ     2?  I/O   AUX2 - Analog test bus or download
 *
 */

//#define WRITE_ENABLED 1

#include <PN5180.h>
//#include <PN5180ISO14443.h>
#include <PN5180ISO15693.h>
//#include <Debug.h>
//SPI.begin(CLK,MISO,MOSI,SS)

//#define VSPI (18,19,23)
//#define HSPI (14,16,13)

SPIClass SPI1(VSPI); //uses default vspi pins
SPIClass SPI2(HSPI); //uses default hspi pins

PN5180ISO15693 nfc1(2, 4, 15, SPI1);
PN5180ISO15693 nfc2(21,26,25, SPI2);

//PN5180ISO14443 nfc1A(2, 4, 15, SPI1);
//PN5180ISO14443 nfc2A(21, 26, 25, SPI2);

void setup() {
  Serial.begin(115200);
  Serial.println(F("=================================="));
  Serial.println(F("Uploaded: " __DATE__ " " __TIME__));
  Serial.println(F("PN5180 ISO15693 Demo Sketch"));

  Serial.print("Reader 1 ");
  Serial.println(F("Initialising..."));
  nfc1.begin();
  nfc1.reset();
  nfc1.setupRF();
  Serial.println("Reader 1 ready");
  nfc2.begin();

  nfc2A.reset();
  nfc2.setupRF();
  Serial.println("Reader 2 ready");

}

uint8_t uid[10];
uint32_t loopCnt = 0;
void loop() {
  Serial.println(F("----------------------------------"));
  Serial.print(F("Loop #"));
  Serial.println(loopCnt++);

    bool entranceHasCard = readEntrance();

    if(entranceHasCard == true)
    {
      Serial.print("Entrance: ");
      for (int i=0; i<8; i++){
        Serial.print(uid[7-i], HEX); //LSB is first
        if (i < 2) Serial.print(":");
      }
      Serial.println();

    }

    bool exitHasCard = readExit();

    if(exitHasCard == true)
    {
      Serial.print("Exit: ");
      for (int i=0; i<8; i++){
        Serial.print(uid[7-i], HEX); //LSB is first
        if (i < 2) Serial.print(":");
      }
      Serial.println();
    }
    Serial.println("No card detected");
    delay(500);
}

bool readEntrance(){
//   nfc1A.reset();
//   nfc1A.setupRF();
//   if (nfc1A.isCardPresent()){
//    uint8_t uidLength = nfc1A.readCardSerial(uid);
//    if (uidLength > 0){
//      return true; //tag exist
//    }
//   }
//   else{
//    return false;
//   }
//   
//   Serial.println("1st 14443 done");

   nfc1.reset(); //prevent serial monitor hangs
   nfc1.setupRF();
   ISO15693ErrorCode rc = nfc1.getInventory(uid);
   if (ISO15693_EC_OK != rc){
     return false; //no card exist
   }
   else{
     return true; //card exist
   }
//   Serial.println("1st 15693 done");
}

bool readExit(){
//  nfc2A.reset();
//  nfc2A.setupRF();
//
//  if (nfc2A.isCardPresent()){
//    uint8_t uidLength = nfc2A.readCardSerial(uid);
//    if (uidLength > 0){
//      return true; //tag exist
//    }
//  }
//  else{
//    return false;
//  }

  nfc2.reset();
  nfc2.setupRF();
  ISO15693ErrorCode rc2 = nfc2.getInventory(uid);
  if (ISO15693_EC_OK != rc2){
    return false; //no card exist
  }
  else{
    return true; //card exist
  }
//  Serial.println("2nd 15693 done");
}