PN5180 "FATAL: Reading more than 508 bytes is not supported!"

Buenas tardes, a ver si me podeis ayudar, por favor.

Estoy haciendo un par de puzzles para escape room utilizando PN5180 y arduino Mega. Con el primero no tuve ningún problema, usé 4 PN5180 y todo perfecto.
Pero en este nuevo utilizo 5 y a ka hora de ejecutar el código me salta este error:

Reader #0
Initialising...
Resetting...
Enabling RF field...
Reader #1
Initialising...
Resetting...
Enabling RF field...
Reader #2
Initialising...
Resetting...
Enabling RF field...
Reader #3
Initialising...
Resetting...
Enabling RF field...
Reader #4
Initialising...
Resetting...
Enabling RF field...
Setup Complete
*** FATAL: Reading more than 508 bytes is not supported!
*** FATAL: Reading more than 508 bytes is not supported!

No se si el problema puede ser a algún Level Shifter o que, pero no logro solucionarlo.

// INCLUDES
// Download from https://github.com/playfultechnology/PN5180-Library
#include <PN5180.h>
#include <PN5180ISO15693.h>

// CONSTANTS
// The number of PN5180 readers connected
const byte numReaders = 5;
// What is the "correct" UID that should be detected by each reader
uint8_t correctUid[][8] = {
  {0x31,0xA7,0xFD,0x31,0x8,0x1,0x4,0xE0}, //CEPILLO
  {0x7F,0xA1,0xFD,0x31,0x8,0x1,0x4,0xE0}, //RELOJ
  {0xD3,0xAA,0xFD,0x31,0x8,0x1,0x4,0xE0}, //PITILLERA
  {0xFB,0xAF,0xFD,0x31,0x8,0x1,0x4,0xE0}, //PIPA
  {0xD1,0xAB,0xFD,0x31,0x8,0x1,0x4,0xE0}, //ESPEJO
};
// If any of the readers detect this tag, the puzzle will be reset
uint8_t resetUid[8] = {0x36,0x5E,0xE4,0xF6,0x50,0x1,0x4,0xE0};

uint8_t noUid[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

// This pin will be driven LOW when the puzzle is solved
// Este pin se bajará cuando se resuelva el rompecabezas.
const byte relayPin1 = A2; // LIBERA ELECTROIMAN
const byte controlPin = 22;

// GLOBALS
// Each PN5180 reader requires unique NSS (VERDE), BUSY (BLANCO), and RESET (AMARILLO) pins,
// as defined in the constructor below
PN5180ISO15693 nfc[] = {
  PN5180ISO15693(10,9,8), // works
  PN5180ISO15693(7,6,5), // works
  PN5180ISO15693(4,3,2), // works
  PN5180ISO15693(14,15,16), // works
  PN5180ISO15693(17,18,19), // works
};
// Array to record the value of the last UID read by each reader
uint8_t lastUid[numReaders][8];

bool juegoResuelto=false;


void setup() {
  // Configura el pin del relé
  pinMode(relayPin1, OUTPUT);
  digitalWrite(relayPin1, HIGH);
  
  // Initialise serial connection
  Serial.begin(9600);

  // Print out the file and the date at which it was last compiled
  Serial.println(__FILE__ __DATE__);

  for(int i=0; i<numReaders; i++){
    Serial.print("Reader #");
    Serial.println(i);
    Serial.println(F("Initialising..."));
    nfc[i].begin();
    Serial.println(F("Resetting..."));
    nfc[i].reset();
    Serial.println(F("Enabling RF field..."));
    nfc[i].setupRF();
  }
  Serial.println(F("Setup Complete"));
}

void loop() {

  //while (!juegoResuelto) {
      if (digitalRead(controlPin) == HIGH) {
        Serial.println("CONTROL ------------------------------------------------------");
        onPuzzleSolved();
      }
      for(int i=0; i<numReaders; i++) {
        // Variable to store the ID of any tag read by this reader
        uint8_t thisUid[8];
        // Try to read a tag ID (or "get inventory" in ISO15693-speak) 
        ISO15693ErrorCode rc = nfc[i].getInventory(thisUid);
        // If the result code was that a card had been read
        if(rc == ISO15693_EC_OK) {
          // If this is the same ID as we read last frame
          if(memcmp(thisUid, lastUid[i], 8) == 0) {
            // Nothing to do - move on to the next reader
            continue;
          }
          // If it's a different ID
          else {
            // Update the array that keeps track of most recent ID
            memcpy(lastUid[i], thisUid, 8);
            // Display current state of all sensors
            showCurrentStatus();
            // Has placing this card solved the puzzle?
            checkIfPuzzleSolved();
          }
        }
        // If a card cannot be read
        else {
          // Test if we previously knew about a card (in which case it's just been removed
          // The most significant (last) byte of a valid UID should always be 0xE0. e.g. E007C4A509C247A8
          if(lastUid[i][7] == 0xE0){
            // Update the array that keeps track of last known ID
            memset(lastUid[i], 0, 8);
            // Display current state of all sensors
            showCurrentStatus();
          }
        }
        // Slight delay before checking the next reader
        delay(10);
      }
  //}   
}

void showCurrentStatus() {
  for(int i=0; i<numReaders; i++) {
    Serial.print(F("Reader #"));
    Serial.print(i);
    Serial.print(": "); 
    if(memcmp(lastUid[i], noUid, 8) == 0) {
      Serial.print(F("---"));
    }
    else {
      for (int j=0; j<8; j++) {
        // If single byte, pad with a leading zero
        if(lastUid[i][j]<0x10) { Serial.print("0"); }
        Serial.print(lastUid[i][j], HEX);
      }
      if(memcmp(lastUid[i], correctUid[i], 8) == 0) {
        Serial.print(F(" - CORRECT"));
      }
    }
    Serial.println("");
 }
 Serial.println(F("---"));
}



// Action to take when the puzzle is solved
void onPuzzleSolved() {
  // Activate the relay
  Serial.println("LIBERA ELECTROIMAN");
  digitalWrite(relayPin1, LOW); 
  // Loop until reset card is detected
  bool resetDetected = false;
  while(!resetDetected) {
    for(int i=0; i<numReaders; i++) {
      // Variable to store the ID of any tag read by this reader
      uint8_t thisUid[8];
      // Try to read a tag ID (or "get inventory" in ISO15693-speak) 
      ISO15693ErrorCode rc = nfc[i].getInventory(thisUid);
      // If a card is read with the same ID as the reset card UID
      if(rc == ISO15693_EC_OK && memcmp(thisUid, resetUid, 8) == 0) {
        resetDetected = true;
        digitalWrite(relayPin1, HIGH); // Enciende chimenea
      }
      delay(100);
    }
  }
  Serial.println(F("RESET"));
  Serial.println(F("---"));
  
}

// Check whether all PN5180s have detected the correct tag
void checkIfPuzzleSolved() {
  // Test each reader in turn
  for(int i=0; i<numReaders; i++){
    // If this reader hasn't detected the correct tag
    if(memcmp(lastUid[i], correctUid[i], 8) != 0){
      // Exit
      return;
    }
  }
  onPuzzleSolved();
}

Su publicacion se MUEVE a su ubicacion actual ya que es mas adecuada.

Moderador:
Si posteas en el foro en inglés usa idioma inglés para expresarte.
Si escribes en español debes usar el foro Arduino en español.

cambia solo para probar a otros pines justamente el 5to

 PN5180ISO15693(17,18,19), // works

la librería sugiere el level shifter

Si, perdona, utilizo 5 level shifters (uno por lector) más otro level shifters para los SPI.

Buenos días.
Cambié como me dijiste los pines del 5º y sigue dandome el error.

Lo que si he visto es que el error lo da justamente cuando intento hacer

ISO15693ErrorCode rc = nfc[i].getInventory(thisUid);

Según leo en el datasheed del PN5180

11.4.3.2 Transmission Buffer
Two buffers are implemented in the PN5180. The transmission buffer has a buffer size of
260 bytes, the reception buffer has a size of 508 bytes. Both memories buffer the input
and output data streams between the host and the internal state machine / contactless
UART of the PN5180. Thus, it is possible to handle data streams with lengths of up
to 260 bytes for transmission and up to 508 bytes for reception without taking timing
constraints into account.

No se si tiene que ver, tampoco se como solucionarlo

Aca lo resolvés

uint8_t PN5180::readBuffer[508];

buscá en el archivo PN5180.cpp de tu librería en la linea 40

image
Amplia el tamaño.
Y acá el error

uint8_t * PN5180::readData(int len, uint8_t *buffer /* = NULL */) {
  if (len > 508) {
    Serial.println(F("*** FATAL: Reading more than 508 bytes is not supported!"));
    return 0L;
  }

Diste con la tecla y te he proporcionado la solución

solo modifica y pon algo como

uint8_t PN5180::readBuffer[625];

Le sume 127 pero podes jugar con ese valor a tu conveniencia. no te pases de 1024

Gracias @Surbyte , probaré cambiando ese parámetro.

La verdad es que no se muy bien lo que hice, porque ayer fue un día de pruebas..... volví a cablear de nuevo el arduino por si el problema podía venir de algún Level Shifter que estuviese dañado o algún pin cambiado y no me volvió a dar el error, aun así lo cambiaré y probaré.

Eso si, se me produce un hecho curioso cuanto menos..... una vez subido el sketch al arduino Mega y al empezar a ejecutarse el for para inicializar los 5 lectores se me queda "pillado" en el Reader #0..... si desconecto del Mega el cable que va a 3.3v y lo vuelvo a conectar continua el for hasta el Reader #4...... no consigo el "Setup Complete" hasta que no hago esa operación 2 o 3 veces..... Sabes cual puede ser el problema?..... He probado con varias tarjetas, he probado a cambiar el cable de la protoboard al Mega, incluso a pincharlo en diferentes sitios en la proto.... No está muy fino.

Vuelvo a cargar el código por si puedes ver algo raro..... Muchas gracias de nuevo por tu ayuda, como siempre

// INCLUDES
// Download from https://github.com/playfultechnology/PN5180-Library
#include <Debug.h>
#include <PN5180.h>
#include <PN5180ISO15693.h>

// CONSTANTS
// The number of PN5180 readers connected
const byte numReaders = 5;
// What is the "correct" UID that should be detected by each reader
uint8_t correctUid[][8] = {
  {0x31,0xA7,0xFD,0x31,0x8,0x1,0x4,0xE0}, //CEPILLO
  {0x7F,0xA1,0xFD,0x31,0x8,0x1,0x4,0xE0}, //RELOJ
  {0xD3,0xAA,0xFD,0x31,0x8,0x1,0x4,0xE0}, //PITILLERA
  {0xFB,0xAF,0xFD,0x31,0x8,0x1,0x4,0xE0}, //PIPA
  {0xFB,0xAF,0xFD,0x31,0x8,0x1,0x4,0xE0}, //ESPEJO
};
// If any of the readers detect this tag, the puzzle will be reset
uint8_t resetUid[8] = {0x36,0x5E,0xE4,0xF6,0x50,0x1,0x4,0xE0};

uint8_t noUid[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

// This pin will be driven LOW when the puzzle is solved
// Este pin se bajará cuando se resuelva el rompecabezas.
const byte relayPin1 = A2; // LIBERA ELECTROIMAN
const byte controlPin = 39;

// GLOBALS
// Each PN5180 reader requires unique NSS (VERDE), BUSY (BLANCO), and RESET (AMARILLO) pins,
// as defined in the constructor below
PN5180ISO15693 nfc[] = {
  PN5180ISO15693(2,15,0), // works
  PN5180ISO15693(16,4,17), // works
  PN5180ISO15693(21,5,22), // works
  PN5180ISO15693(33,25,32), // works
  PN5180ISO15693(19,29,28), // works
};
// Array to record the value of the last UID read by each reader
uint8_t lastUid[numReaders][8];

bool juegoResuelto=false;


void setup() {
  // Configura el pin del relé
  pinMode(relayPin1, OUTPUT);
  digitalWrite(relayPin1, HIGH);
  
  // Initialise serial connection
  Serial.begin(115200);

  // Print out the file and the date at which it was last compiled
  Serial.println(__FILE__ __DATE__);

  for(int i=0; i<numReaders; i++){
    Serial.print("Reader #");
    Serial.println(i);
    Serial.println(F("Initialising..."));
    nfc[i].begin();
    Serial.println(F("Resetting..."));
    nfc[i].reset();
    Serial.println(F("Enabling RF field..."));
    nfc[i].setupRF();
  }
  Serial.println(F("Setup Complete"));

}

void loop() {

  //while (!juegoResuelto) {
      //if (digitalRead(controlPin) == HIGH) {
      //  Serial.println("CONTROL ------------------------------------------------------");
      //  onPuzzleSolved();
      //}
      for(int i=0; i<numReaders; i++) {
        // Variable to store the ID of any tag read by this reader
        //Serial.println("EMPIEZA A LEER");
        uint8_t thisUid[8];
        // Try to read a tag ID (or "get inventory" in ISO15693-speak) 
        ISO15693ErrorCode rc = nfc[i].getInventory(thisUid);
        // If the result code was that a card had been read
        if(rc == ISO15693_EC_OK) {
          // If this is the same ID as we read last frame
          //Serial.println("if(rc == ISO15693_EC_OK)");
          if(memcmp(thisUid, lastUid[i], 8) == 0) {
            // Nothing to do - move on to the next reader
            //Serial.println("(memcmp(thisUid, lastUid[i], 8) == 0)");
            continue;
          }
          // If it's a different ID
          else {
            // Update the array that keeps track of most recent ID
            //Serial.println("else... (memcmp(thisUid, lastUid[i], 8) == 0) MUESTRA ESTADO SENSORES");
            memcpy(lastUid[i], thisUid, 8);
            // Display current state of all sensors
            showCurrentStatus();
            // Has placing this card solved the puzzle?
            checkIfPuzzleSolved();
          }
        }
        // If a card cannot be read
        else {
          // Test if we previously knew about a card (in which case it's just been removed
          // The most significant (last) byte of a valid UID should always be 0xE0. e.g. E007C4A509C247A8
          if(lastUid[i][7] == 0xE0){
            // Update the array that keeps track of last known ID
            memset(lastUid[i], 0, 8);
            // Display current state of all sensors
            showCurrentStatus();
          }
        }
        // Slight delay before checking the next reader
        delay(10);
      }
  //}   
}

void showCurrentStatus() {
  for(int i=0; i<numReaders; i++) {
    Serial.print(F("Reader #"));
    Serial.print(i);
    Serial.print(": "); 
    if(memcmp(lastUid[i], noUid, 8) == 0) {
      Serial.print(F("---"));
    }
    else {
      for (int j=0; j<8; j++) {
        // If single byte, pad with a leading zero
        if(lastUid[i][j]<0x10) { Serial.print("0"); }
        Serial.print(lastUid[i][j], HEX);
      }
      if(memcmp(lastUid[i], correctUid[i], 8) == 0) {
        Serial.print(F(" - CORRECT"));
      }
    }
    Serial.println("");
 }
 Serial.println(F("---"));
}



// Action to take when the puzzle is solved
void onPuzzleSolved() {
  // Activate the relay
  Serial.println("LIBERA ELECTROIMAN");
  digitalWrite(relayPin1, LOW); 
  // Loop until reset card is detected
  bool resetDetected = false;
  while(!resetDetected) {
    for(int i=0; i<numReaders; i++) {
      // Variable to store the ID of any tag read by this reader
      uint8_t thisUid[8];
      // Try to read a tag ID (or "get inventory" in ISO15693-speak) 
      ISO15693ErrorCode rc = nfc[i].getInventory(thisUid);
      // If a card is read with the same ID as the reset card UID
      if(rc == ISO15693_EC_OK && memcmp(thisUid, resetUid, 8) == 0) {
        resetDetected = true;
        digitalWrite(relayPin1, HIGH); // Enciende chimenea
      }
      delay(100);
    }
  }
  Serial.println(F("RESET"));
  Serial.println(F("---"));
  
}

// Check whether all PN5180s have detected the correct tag
void checkIfPuzzleSolved() {
  // Test each reader in turn
  for(int i=0; i<numReaders; i++){
    // If this reader hasn't detected the correct tag
    if(memcmp(lastUid[i], correctUid[i], 8) != 0){
      // Exit
      return;
    }
  }
  onPuzzleSolved();
}

Otra cosa @Surbyte , hice hace 3 o 4 días el mismo sketch para otro puzzle con 4 lectores PN5180 y no tuve ningún problema. Los problemas me han llegado utilizando 5 lectores.

Estaba pensando que el problema de los 3.3v fuese por como estoy alimentando el arduino actualmente para hacer las pruebas (únicamente a través del cable del ordenador porque la fuente de alimentación se me fastidió y estoy esperando una nueva). No se si tiene algo que ver

Mide consumo aunque no creo que sea el caso. tal vez algun lector defectuoso que consuma de mas.
Lo que describes no parece ser un problema común sino uno particular. Ahora tal vez hayas cambiado el módulo y tmb lo hace y mi idea de un módulo defectuoso no tenga asidero.

Si no has tenido problemas con 4 lectores prueba asignarle ese valor a numreaders y fijate como se comporta.
Así descartas (o no) que el problema lo provoque el agregado de un 5to lector.

Gracias @Surbyte. Cambié el parámetro y ya no me devuelve el error Fatal

uint8_t PN5180::readBuffer[625];

Buenos dias, no estoy seguro que este sea el sitio idoneo para mi post.

Os cuento, estoy intentando intercambiar señales digitales con una raspberry.

Un pin digital de salida desde mi arduino a través de un divisor de potencia para pasar de los 5v de mi arduino mega a la RPi (tres resistencias de 10k en serie) donde le envío un valor HIGH para que comience a ejecutarse un video en un proyector.
Cuando finaliza, la RPi me debe enviar un valor HIGH a otro pin digital de mi arduino (directamente porque no hace falta ahí divisor de potencia) para seguir mi secuencia de programa.

El problema que tengo es que nunca recibo de la RPi un valor estable, lo que recibo son valores LOW y esporádicamente algún HIGH por lo que en ese momento salgo de ese "bucle de espera" y continuo la secuencia de mi arduino antes de que finalice la tarea la RPi

Las 3 estan en serie claramente pero forman un divisor 5 a 3.3V.

Asi.
image
Aca son dos en serie abajo y la 3ra tmb serie con las primeras pero con las conexiones que corresponde.
Eso tienes?
3.3V el RPi
5V el MEGA

Las masas de la raspi y el arduino están unidas, cierto?

Por lo que cuenta, parece que no.

Perdonad.... si, GND de arduino y GND de RPi están unidas

Sube los códigos así vemos cual puede ser el problema porque no parece ser de conexionado.

Postea un esquema de las conexiones tmb.
Usa etiquetas, lee las normas

Perdona @Surbyte este problema de la señal de la Raspi lo hemos solucionado "a las bravas".... me explico, resulta que el chaval que ha desarrollado el código para la Raspi no está en España y me comentó de hacerlo de esta manera:

  • Arduino mandaba señal HIGH en un pin digital que la Raspi leía. Iniciaba el Video.
  • Cuando el video finaliza, Raspi me manda a Arduino un valor HIGH en otro pin digital. Cuando lo leo sigo mi secuencia.

El problema es que yo leía siempre valores LOW en ese pin pero de vez en cuando algún HIGH y seguía la secuencia antes de la finalización del video. Así que decidimos (porque es indiferente para el resultado del puzzle) que arduino envía la señal, Raspi inicia el video y paro 56 segundos (que es lo que tarda el video) para continuar la secuencia.

Se que no es la manera de hacerlo y es una autentica chapuza, pero las prisas nos pueden, el puzzle funciona así correctamente

¿El micro de la Raspi no trabaja a 3.3V?
Tal vez por alguna razón no llega bien definido el nivel alto y con un adaptador de niveles lo solucionas como corresponde. :wink: