Data from NFC Card not writing to LCD properly

I am trying to make a small demo project where I have a 4 row LCD with static text on 3 rows and the 4th displaying data read from an Ndef NFC card or a blank line when no card is present. When I'm reading from the card, instead of writing the 4th line and stopping, it is continuously reading and causing what appears to be a buffer overflow on the LCD and overwriting the other three lines. I tried to have the program only write to the LCD once on new data, deleting the data and even tried blanking the whole LCD between cycles and nothing I'm doing seems to fix the issue.

The goal is to have the 4th line present the text from the NFC card and update when the text changes or be blank if there is no card.

Here is the code.

#include <Wire.h>
#include <PN532_I2C.h>
//#include <PN532.h>
#include <NfcAdapter.h>
#include <LiquidCrystal_I2C.h>

PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c);

LiquidCrystal_I2C lcd(0X26,20,4);

String payloadAsString = "";
String oldData = "";

void setup(void) {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  
 //display line 1
 lcd.setCursor(3,0);
 lcd.print("Hello");

 //display line 2
 lcd.setCursor(0,1);
 // lcd.print("   Welcome to V9    ");
 lcd.print("I'm the Prototype");

 //display line 3
 lcd.setCursor(2,2);
 lcd.print("The card contains:");
}

void loop (){
 readNFC();
 writeLCD();
 delay (2000);
}

void readNFC() {
  nfc.begin();    //this is here rather than in setup because if it's in setup the LCD won't initialize
  
  if (nfc.tagPresent())
  {
    NfcTag tag = nfc.read();
    Serial.println(tag.getTagType());
    Serial.print("UID: ");Serial.println(tag.getUidString());

    if (tag.hasNdefMessage()) // every tag won't have a message
    { NdefMessage message = tag.getNdefMessage();

      // cycle through the records, printing some info from each
      int recordCount = message.getRecordCount();
      for (int i = 0; i < recordCount; i++)
      {
        NdefRecord record = message.getRecord(i);
        int payloadLength = record.getPayloadLength();
        byte payload[payloadLength];
        record.getPayload(payload);

        for (int c = 4; c < payloadLength; c++) {
          payloadAsString += (char)payload[c];
        }
      }
    }
  }
}

void writeLCD(){
// Commented code added in attempt to correct buffer overflow.
/*lcd.clear();

 lcd.setCursor(3,0);
 lcd.print("Hello!");

 //display line 2
 lcd.setCursor(0,1);
 lcd.print("I'm the Prototype");

 //display line 3
 lcd.setCursor(2,2);
 lcd.print("The card contains:");*/
 
//display line 4
  lcd.setCursor(0,3);
  lcd.print("");
 if (nfc.tagPresent()){
  if (oldData != payloadAsString){
   lcd.setCursor(0,3);
   lcd.print(payloadAsString);
   oldData = payloadAsString;
   //payloadAsString = "";
   }else {}
 } else{
  lcd.setCursor(0,3);
  lcd.print("");
 }
}

A couple of things to consider:

This prints nothing at all.

  lcd.setCursor(0,3);
  lcd.print("");

If your intent is to clear the 4th line, you'll need something like

  lcd.setCursor(0,3);
  lcd.print("                    ");

And commenting this line out ensures that your String just grows and grows, quickly overflowing everything.

   //payloadAsString = "";

Off the top of my head, you'd do better to

  1. Not use Strings.
  2. Empty the payload buffer/String/char array in readNFC.
  3. Set a flag when you've read new data into it and have writeLCD only update the screen when the flag is set.
1 Like

Thank you! Clearing the payload in readNFC did the trick. I've only been working with arduino for about a month and have no previous experience with C++ or derivatives.

I am learning both as I go but don't have enough knowledge yet with either arduino OR NFC to work with more advanced data types. That is something the real software team will do when this goes into the product development.