ATrappmann / PN5180-Library

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

Reading multiple ISO 15963 tags on the reader #37

Open alansbor opened 3 years ago

alansbor commented 3 years ago

Hello everybody ! I am studying the implementation of reading several ISO 15963 labels located on the reader. One label is readable - no problem, but anything more than two leads to a collision mode. Is it possible using the current library to read UIDs and blocks of information from several ISO 15963 tags located on the reader? I have looked through the source of examples from NXP, but the devil will break his leg. I would like to do on this library.

The author does not accept requests for additions, which is a pity, I would spend a couple of dollars on such an implementation.

Привет всем ! Изучаю вопрос реализации считывания нескольких расположенных на ридере меток ISO 15963. По одной метке читается - без проблем, а вот все что больше двух приводит к режиму коллизии. Можно ли используя текущую библиотеку считать UID и блоки информации с нескольких расположенных на ридере меток ISO 15963 ? Я просмотрел исходник примеров от NXP, но там черт ногу сломит. Хочется на этой библиотеке сделать.

Автор не принимает запросы на добавления, а жаль, я бы пару долларов потратил на такую реализацию.

FatherOfErik commented 3 years ago

Hi, I have implemented a simple anitcollision routine that can handle NFC tags that have unique last four bits in there uid. I haven´t figured out how to contribute this code.

the main part is in PN5180ISO15693.cpp. See below. It also requires some added code in PN5180ISO15693.h, PN5180.cpp and PN5180.h.

PN5180ISO15693.cpp, The delay in after sendData in ::issueISO15693Command routine has also to be changed from 10 ms to 15 ms.

/*
 * Inventory16slot, code=01
 *
 * Request format: SOF, Req.Flags, Inventory, AFI (opt.), Mask len, Mask value, CRC16, EOF
 * Response format: SOF, Resp.Flags, DSFID, UID, CRC16, EOF
 *
 * The uidBlock is a vectror that contains up to 16 uid, each uid starts at position n*10
 * in the vector. n=0..15. Example, uid for NFC tag 2 is located in position 20 to 28 in the 
 * vectror. uidCounter contains the number of NFC tags found
 * 
 * This code is designed after AN12650 "Using the PN5180 without library" from NXP
 */
ISO15693ErrorCode PN5180ISO15693::getInventory16slot(uint8_t *uidBlock, uint8_t *uidCounter) {
  //                     Flags, CMD,  maskLen
  uint8_t inventory[] = { 0x06, 0x01, 0x00 };
  //                        |\- inventory flag + high data rate
  //                        \-- 16 slot: anti collision routine, no AFI field present

  uint8_t SlotCounter, i; 
  uint8_t cmd[] = { PN5180_READ_DATA, 0 };
  uint8_t *resultPtr;

  uidCounter[0] = 0;
  setRF_off();
  loadRFConfig(0x0d, 0x8d);
  setRF_bit();
  clearIRQStatus(0x000fffff); //Clears the interrupt register IRQ_STATUS
  sendData(inventory, sizeof(inventory));

  for (int SlotCounter=0; SlotCounter<16;SlotCounter++) 
  {
    if (0 != (getIRQStatus() & RX_SOF_DET_IRQ_STAT)) 
    {
      uint32_t rxStatus;
      readRegister(RX_STATUS, &rxStatus);
      uint16_t len = (uint16_t)(rxStatus & 0x000001ff);
      resultPtr = readData(len);

      for (int i=0; i<8; i++) {
        uidBlock[uidCounter[0]*10+i] = resultPtr[i+2];
      }
      uidCounter[0]++;

    }
    writeRegisterWithAndMask(TX_CONFIG, 0xfffffb3f); //Send only EOF (End Of Frame)
                                        //without data at the next RF communication
    writeRegisterWithAndMask(SYSTEM_CONFIG, 0xfffffff8);  // Idle/StopCom Command
    writeRegisterWithOrMask(SYSTEM_CONFIG, 0x00000003);   // Transceive Command
    clearIRQStatus(0x000fffff);         //Clears the register IRQ_STATUS
    sendEOF();
  }

  return ISO15693_EC_OK;
}

PN5180.cpp


`/*
 * RF_bit - 0x16
 * This command is used to switch on the internal RF field. No check of field.
 */
bool PN5180::setRF_bit() {
  PN5180DEBUG(F("Set RF bit\n"));

  uint8_t cmd[2] = { PN5180_RF_ON, 0x00 };

  SPI.beginTransaction(PN5180_SPI_SETTINGS);
  transceiveCommand(cmd, 2);
  SPI.endTransaction();

  return true;
}

/*
 * send EOF - 0x09
 * This command is used to switch on the internal RF field. No check of field.
 */
bool PN5180::sendEOF() {
  PN5180DEBUG(F("Set RF bit\n"));

  uint8_t sendEOF[]   = {PN5180_SEND_DATA, 0};

  SPI.beginTransaction(PN5180_SPI_SETTINGS); // Send EOF
  transceiveCommand(sendEOF, 2);
  SPI.endTransaction();                                                      //     09 00

  return true;
}`
FatherOfErik commented 3 years ago

Hi, now a think a have succeeded to add all files to a fork of the code

alansbor commented 3 years ago

Hello FatherOfErik Thank you very much for your work, if my PN5180 can read the five NFC tags on it, tell me where to transfer the money so that you can drink beer for a great job. Write to me at alansbor@yandex.ru so that we stay in touch. Alexey.