Ardoino freezes or give weird characters

Hi

I am trying to make my first practical code to use in a real project.
Model train: Have a NFC-tag in each train, a NFC reader over the different stops in the railyard. Then the LCD show what train is on the different stops. Track 1 - Train 2

After trying to merge two codes, I got it to work after some trying. There is a problem i can`t figure out tho. There is two errors occurring randomly after reading the NFC-tag.

Error 1: The Serial monitor say “read failed 4” and everything just stops working. I have to reset the Arduino to make it run again.

Error 2: The Serial monitor say “read failed 5” and puts out alot of “###**⸮⸮” in random order and length.

Can anyone help me out?

I have a goal to make the code as short as possible. I have tried to remove the function for “// If you have more than 1 Message then it will cycle through them” as I only have one line. Not very important as long as it works.

Got my two codes here:

Arduino Uno
PN532
LCD 16/2 with i2c-shield

Code:
// Include Wire Library for I2C
#include <Wire.h>
#include <PN532_I2C.h>
#include <PN532.h> // The following files are included in the libraries Installed
#include <NfcAdapter.h>
#include <LiquidCrystal_I2C.h> // Include NewLiquidCrystal Library for I2C

PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c); // Indicates the Shield you are using

const int i2c_addr = 0x27; // Define I2C Address of LCD-display
const int en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3; //Define the LCD-pinout
LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE); //Define the LCD-pinout

void setup(void) {
Serial.begin(9600); // Initiate a serial communication
nfc.begin(); // Initiate MP532
Serial.print("\n"); // Set a emty space between info from PN532 and first tag-read

lcd.begin(16,2); // Set display type as 16 char, 2 rows
lcd.setCursor(2,0); // Set cursor to top left corner
lcd.print(“Track 1”); // Set location

}

void loop(void) {
if (nfc.tagPresent()){
NfcTag tag = nfc.read();
Serial.println(tag.getTagType());
Serial.print("UID: ");Serial.println(tag.getUidString()); // Retrieves the Unique Identification from your tag
if (tag.hasNdefMessage()){ // If your tag has a message
NdefMessage message = tag.getNdefMessage();
if (message.getRecordCount() != 1) {
}
int recordCount = message.getRecordCount(); // If you have more than 1 Message then it will cycle through them
for (int i = 0; i < recordCount; i++){
NdefRecord record = message.getRecord(i);
int payloadLength = record.getPayloadLength();
byte payload[payloadLength];
record.getPayload(payload);

String payloadAsString = “”; // Processes the message as a string vs as a HEX value
for (int c = 0; c < payloadLength; c++){
payloadAsString += (char)payload

;
  }
  Serial.println(payloadAsString);
  lcd.setCursor(0,1);
  lcd.print(payloadAsString);
  lcd.setCursor(0,1);
  lcd.print("   ");
                
  String uid = record.getId();
  if (uid != ""){
  Serial.print("  ID: ");Serial.println(uid); // Prints the Unique Identification of the NFC Tag
  }
 }
}
}
}

[u]Serial monitor error 1:[/u]
⸮Found chip PN532
Firmware ver. 1.6

Mifare Classic
UID: 1E 2D 23 D9
en  Train 2   
Mifare Classic
UID: 1E 2D 23 D9
en  Train 2   
Read failed 4

[u]Serial monitor error 2:[/u]
Found chip PN532
Firmware ver. 1.6

Mifare Classic
UID: 1E 2D 23 D9
en  Train 2   
Read failed 5
Mifare Classic
UID: 1E 2D 23 D9
en  Train⸮⸮u

[i](both can be as short as this, or after 10/20/30 tests)[/i]


I have looked around the forum and google, but can`t find this problem. Sorry if I am bad to search, please respond with a link if there is.


Kind regards
Terje

![NFC-LCD.png|1152x648](upload://xYiVVydIdC9Cf4J08kn2xMAVnN8.png)

According to the library, is it just printing out the block number that it couldn't read. Based on how many uses of malloc() and String littered thoughout that library, I'm guessing you are running into memory fragmentation issues.

memory fragmentation issues ?

tell you what, you have to check for free ram left each time you send data to serial monitor and see if you run out memory over time

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

8d97f4ac4d15c1e681aa7471ea28831f0d3c5ed4.png

What is the distance form reader to the UNO, have you got 4K7 pullup resistors on the two comms lines?

Thanks… Tom… :slight_smile:

Thank you for your response :slight_smile:

TomGeorge:
Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

I`m sorry.

TomGeorge:
8d97f4ac4d15c1e681aa7471ea28831f0d3c5ed4.png

What is the distance form reader to the UNO, have you got 4K7 pullup resistors on the two comms lines?

The distance is 10 cm.

From what I have managed to read in manuals, they both have pullup integrated in the board.

http://www.elechouse.com/elechouse/images/product/PN532_module_V3/PN532_%20Manual_V3.pdf

On-board level shifter

Did not find a proper manual for FC-113, Serial i2c LCD adapter. I do not see other have pullup in their shematic.

blh64:
According to the library, is it just printing out the block number that it couldn't read. Based on how many uses of malloc() and String littered thoughout that library, I'm guessing you are running into memory fragmentation issues.

I have now tried different methods for this, and did not get any result. I did not get the code to work.

KASSIMSAMJI:
memory fragmentation issues ?

tell you what, you have to check for free ram left each time you send data to serial monitor and see if you run out memory over time

KASSIMSAMJI:
memory fragmentation issues ?

tell you what, you have to check for free ram left each time you send data to serial monitor and see if you run out memory over time

Thank you for your response :slight_smile:

I will try to check both memory fragmentation and to check for free ram.

My suspicion was that since the error occurred only when moving the tag towards or from the reader, it was the reading when the tag it close enough to read, but to far to get a proper reading that make the issue.

If I lay the tag on the reader with no error, it prints for minutes without problem. But as soon as I take it away, og move it, the problem randomly occurs again.

Hi

After some searching and learning I have found where the error originates.

I tried with this code:

Serial.print("#####"); // Debug code -> Program get past this point every time the the "Error. Block Authentication failed for 4" and "Read failed 4" is not present
// delay(300); // Debug code -> Error not occurring often with 300+ delay. Did not manage to read message with the delay with tag moving over PN532.

    NfcTag tag = nfc.read();

Serial.print("-----"); // Debug code -> The program never get to this point after the "Error. Block Authentication failed for 4" and "Read failed 4

The error has to do with the “NfcTag tag = nfc.read();” and not ram or memory fragmentation. Maybe I run into that after som hours running this tho.

Here are the library NfsAdapter code that I found is the nfc.read() source

#include <NfcAdapter.h>

NfcAdapter::NfcAdapter(PN532Interface &interface)
{
    shield = new PN532(interface);
}

NfcAdapter::~NfcAdapter(void)
{
    delete shield;
}

void NfcAdapter::begin(boolean verbose)
{
    shield->begin();

    uint32_t versiondata = shield->getFirmwareVersion();

    if (! versiondata)
    {
#ifdef NDEF_USE_SERIAL
        Serial.print(F("Didn't find PN53x board"));
#endif
        while (1); // halt
    }

    if (verbose)
    {
#ifdef NDEF_USE_SERIAL
        Serial.print(F("Found chip PN5")); Serial.println((versiondata>>24) & 0xFF, HEX);
        Serial.print(F("Firmware ver. ")); Serial.print((versiondata>>16) & 0xFF, DEC);
        Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
#endif
    }
    // configure board to read RFID tags
    shield->SAMConfig();
}

boolean NfcAdapter::tagPresent(unsigned long timeout)
{
    uint8_t success;
    uidLength = 0;

    if (timeout == 0)
    {
        success = shield->readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, (uint8_t*)&uidLength);
    }
    else
    {
        success = shield->readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, (uint8_t*)&uidLength, timeout);
    }
    return success;
}

boolean NfcAdapter::erase()
{
    NdefMessage message = NdefMessage();
    message.addEmptyRecord();
    return write(message);
}

boolean NfcAdapter::format()
{
    boolean success;
#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
    if (uidLength == 4)
    {
        MifareClassic mifareClassic = MifareClassic(*shield);
        success = mifareClassic.formatNDEF(uid, uidLength);
    }
    else
#endif
    {
#ifdef NDEF_USE_SERIAL
        Serial.print(F("Unsupported Tag."));
#endif
        success = false;
    }
    return success;
}

boolean NfcAdapter::clean()
{
    uint8_t type = guessTagType();

#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
    if (type == TAG_TYPE_MIFARE_CLASSIC)
    {
        #ifdef NDEF_DEBUG
        Serial.println(F("Cleaning Mifare Classic"));
        #endif
        MifareClassic mifareClassic = MifareClassic(*shield);
        return mifareClassic.formatMifare(uid, uidLength);
    }
    else
#endif
    if (type == TAG_TYPE_2)
    {
        #ifdef NDEF_DEBUG
        Serial.println(F("Cleaning Mifare Ultralight"));
        #endif
        MifareUltralight ultralight = MifareUltralight(*shield);
        return ultralight.clean();
    }
    else
    {
#ifdef NDEF_USE_SERIAL
        Serial.print(F("No driver for card type "));Serial.println(type);
#endif
        return false;
    }

}


NfcTag NfcAdapter::read()
{
    uint8_t type = guessTagType();

#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
    if (type == TAG_TYPE_MIFARE_CLASSIC)
    {
        #ifdef NDEF_DEBUG
        Serial.println(F("Reading Mifare Classic"));
        #endif
        MifareClassic mifareClassic = MifareClassic(*shield);
        return mifareClassic.read(uid, uidLength);
    }
    else
#endif
    if (type == TAG_TYPE_2)
    {
        #ifdef NDEF_DEBUG
        Serial.println(F("Reading Mifare Ultralight"));
        #endif
        MifareUltralight ultralight = MifareUltralight(*shield);
        return ultralight.read(uid, uidLength);
    }
    else if (type == TAG_TYPE_UNKNOWN)
    {
#ifdef NDEF_USE_SERIAL
        Serial.print(F("Can not determine tag type"));
#endif
        return NfcTag(uid, uidLength);
    }
    else
    {
        // Serial.print(F("No driver for card type "));Serial.println(type);
        // TODO should set type here
        return NfcTag(uid, uidLength);
    }

}

boolean NfcAdapter::write(NdefMessage& ndefMessage)
{
    boolean success;
    uint8_t type = guessTagType();

#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
    if (type == TAG_TYPE_MIFARE_CLASSIC)
    {
        #ifdef NDEF_DEBUG
        Serial.println(F("Writing Mifare Classic"));
        #endif
        MifareClassic mifareClassic = MifareClassic(*shield);
        success = mifareClassic.write(ndefMessage, uid, uidLength);
    }
    else
#endif
    if (type == TAG_TYPE_2)
    {
        #ifdef NDEF_DEBUG
        Serial.println(F("Writing Mifare Ultralight"));
        #endif
        MifareUltralight mifareUltralight = MifareUltralight(*shield);
        success = mifareUltralight.write(ndefMessage, uid, uidLength);
    }
    else if (type == TAG_TYPE_UNKNOWN)
    {
#ifdef NDEF_USE_SERIAL
        Serial.print(F("Can not determine tag type"));
#endif
        success = false;
    }
    else
    {
#ifdef NDEF_USE_SERIAL
        Serial.print(F("No driver for card type "));Serial.println(type);
#endif
        success = false;
    }

    return success;
}

// TODO this should return a Driver MifareClassic, MifareUltralight, Type 4, Unknown
// Guess Tag Type by looking at the ATQA and SAK values
// Need to follow spec for Card Identification. Maybe AN1303, AN1305 and ???
unsigned int NfcAdapter::guessTagType()
{

    // 4 byte id - Mifare Classic
    //  - ATQA 0x4 && SAK 0x8
    // 7 byte id
    //  - ATQA 0x44 && SAK 0x8 - Mifare Classic
    //  - ATQA 0x44 && SAK 0x0 - Mifare Ultralight NFC Forum Type 2
    //  - ATQA 0x344 && SAK 0x20 - NFC Forum Type 4

    if (uidLength == 4)
    {
        return TAG_TYPE_MIFARE_CLASSIC;
    }
    else
    {
        return TAG_TYPE_2;
    }
}

Here is the source of error in the library NfcAdapter

NfcTag NfcAdapter::read()
{
    uint8_t type = guessTagType();

#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
    if (type == TAG_TYPE_MIFARE_CLASSIC)
    {
        #ifdef NDEF_DEBUG
        Serial.println(F("Reading Mifare Classic"));
        #endif
        MifareClassic mifareClassic = MifareClassic(*shield);
        return mifareClassic.read(uid, uidLength);
    }
    else

Any help to fix the error is much appreciated :slight_smile:
Maybe the entire setup of the code is wrong, and there is som better ways of doing this. I`m open for some advise on that also.